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

Rust Enum in Struct in Enum causes bottom level enum constructor to change type? #901

Open
crides opened this issue Jan 5, 2021 · 4 comments · May be fixed by #902
Open

Rust Enum in Struct in Enum causes bottom level enum constructor to change type? #901

crides opened this issue Jan 5, 2021 · 4 comments · May be fixed by #902

Comments

@crides
Copy link

crides commented Jan 5, 2021

Minimum example needed to reproduce

Basically I have types in Rust like these:

#[derive(Clone, Debug, VmType, Pushable, Getable)]
enum E1 {
    S1(S),
}

#[derive(Clone, Debug, VmType, Pushable, Getable)]
struct S {
    e: E2,
}

#[derive(Clone, Debug, VmType, Pushable, Getable)]
enum E2 {
    Num(i32),
}

And if I try to initialize E1 with:

let { E1, S, E2 } = import! test
let e1 = S1 { e = Num 3 }

Then I get the following:

error: Expected the following types to be equal
Expected: | Num : Int -> E1
Found: E2
1 errors were found during unification:
Types do not match:
    Expected: Int -> E1
    Found: Int -> <opaque>
  ┌─ test:3:23
  │
3 │     let e1 = S1 { e = Num 3 }
  │
  │                       ^^^^^

So it seems like suddenly E2's constructor(s) have changed (if E2 has multiple variants they all get changed). Note that this also happens in the repl*, but (assuming test is the module containing the types) when I try :t import! test it shows all types correctly, but if I try :t let { E1 } = import! test in S1 then it also shows the wrong type.

[*] The repl included in the test repo is basically the one taken from gluon, except Color is removed and the repl is run from a provided Thread.

@crides
Copy link
Author

crides commented Jan 5, 2021

Seems like only 1 nested enum (i.e. enum in enum) is needed to trigger the same behaviour. The test repo has been updated to reflect that

@Marwes
Copy link
Member

Marwes commented Jan 5, 2021

Defining recursive types is not possible by deriving VmType as is atm.

What you can do is define the types in gluon also and then use the #[gluon(vm_type = "...")] attribute to point to the type on the gluon side (by linking to its module path). Should be an example in the marshalling example.

@crides
Copy link
Author

crides commented Jan 5, 2021

I'm not using recursive types here, but are nested foreign enums also not supported? Also In my use case, I want to pass the types from Gluon to Rust and from Rust to Gluon, so I have to use Getable and Pushable (is there another way?). It does seem like it's possible to define the same types in Gluon and then passing them to Rust functions, so I'll settle with that for now.

Marwes added a commit to Marwes/gluon that referenced this issue Jan 8, 2021
The opaque return type was likely a quick hack that went unnoticed. I
also had to force caching on the enum since the `Symbol` values created
for the variants and the returned enum will otherwise be different
between multiple `VmType::make_type` invocations (unless

Fixes gluon-lang#901
@Marwes Marwes linked a pull request Jan 8, 2021 that will close this issue
@Marwes
Copy link
Member

Marwes commented Jan 8, 2021

My bad, misread it. Fixed in #902

Marwes added a commit to Marwes/gluon that referenced this issue Jan 9, 2021
The opaque return type was likely a quick hack that went unnoticed. I
also had to force caching on the enum since the `Symbol` values created
for the variants and the returned enum will otherwise be different
between multiple `VmType::make_type` invocations (unless

Fixes gluon-lang#901
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

Successfully merging a pull request may close this issue.

2 participants