Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

disambiguating record types defined in different files #120

Open
johnynek opened this issue May 15, 2024 · 2 comments
Open

disambiguating record types defined in different files #120

johnynek opened this issue May 15, 2024 · 2 comments

Comments

@johnynek
Copy link

I have some code like:

fn foo(v: Value) {
  let ty = Ty::of_value(v);
  let ident = ty.to_string();
  ...
}

And the motivation is that I am building a configuration system where I allow users to define new record types. But the issue comes when user in one file makes Foo = record() and another file makes Foo = record(). These are distinct types because they were defined in two separate files.

But the ty.to_string() in the above collides.

  1. is there currently a way I can disambiguate these two?
  2. if not, would you be open to a PR that allows inspecting the module id where the user type was defined, which should allow disambiguation.
@ndmitchell
Copy link
Contributor

The Ty you get back has both a name (which isn't sufficient to disambiguate them), but also a type matcher which can be applied to a Value to figure out if it matches. I think you need to use that type matcher. Unfortunately, I can't find anywhere it is exposed. Maybe @stepancheg knows where?

@det
Copy link

det commented Dec 29, 2024

I ran into this as well. I would have preferred an approach based on a hash table, but was able to get something to work using a linear search by adapting the code used to implement the starlark isinstance function. Some demo code:

    fn at(&self, index: Value<'v>, heap: &'v Heap) -> starlark::Result<Value<'v>> {
        let matcher = TypeCompiled::new(index, heap)?;
        for item in &self.items {
            if matcher.matches(item.to_value()) {
                return Ok(item.to_value());
            }
        }
        Err(starlark::Error::new_value(anyhow::Error::msg(
            "No matching type found",
        )))
    }

Here self.items is a Vec<FrozenValue>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants