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

Trying to use same existential type for two functions cause cycle dependency #61863

Open
shootingsyh opened this issue Jun 15, 2019 · 1 comment

Comments

Projects
None yet
3 participants
@shootingsyh
Copy link

commented Jun 15, 2019

On a nightly rustup 1.18.3 (435397f48 2019-05-22)
Some code like this

#![feature(existential_type)]
pub trait T {
    fn bla() -> ();
}

pub struct S {
  v: u64
}

impl T for S {
    fn bla() -> () {}
}

existential type TE: T;
pub fn bla() -> TE {
    return S {v:1}
}

pub fn bla2() -> TE {
    bla()
}

cause error

Compiling playground v0.0.1 (/playground)
error[E0391]: cycle detected when processing TE
--> src/lib.rs:14:1
|
14 | existential type TE: T;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires processing bla2...
--> src/lib.rs:19:21
|
19 | pub fn bla2() -> TE {
| ___________________^
20 | | bla()
21 | | }
| |
^
= note: ...which again requires processing TE, completing the cycle
note: cycle used when collecting item types in top-level module
--> src/lib.rs:1:1
|
1 | / #![feature(existential_type)]
2 | | pub trait T {
3 | | fn bla() -> ();
4 | | }
... |
20 | | bla()
21 | | }
| |
^

error: concrete type differs from previous defining existential type use
--> src/lib.rs:19:1
|
19 | / pub fn bla2() -> TE {
20 | | bla()
21 | | }
| |^ expected S, got TE
|
note: previous use here
--> src/lib.rs:15:1
|
15 | / pub fn bla() -> TE {
16 | | return S {v:1}
17 | | }
| |
^

error: aborting due to 2 previous errors

playground link:
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=71c724f92b074d0b6f355a6aaf8d3d1a

@Aaron1011

This comment has been minimized.

Copy link
Contributor

commented Jul 5, 2019

I think the most straightforward way to resolve this would be to try to 'recover' from the cycle error, and see if processing any other items allows us to constraint the existential type. Unfortunately, the docs state that cycle recovery was removed.

Aaron1011 added a commit to Aaron1011/rust that referenced this issue Jul 5, 2019

Fix cycle error with existential types
Fixes rust-lang#61863

We now allow uses of 'existential type's that aren't defining uses -
that is, uses which don't constrain the underlying concrete type.

To make this work correctly, we also modify eq_opaque_type_and_type to
not try to apply additional constraints to an opaque type. If we have
code like this:

```
existential type Foo;
fn foo1() -> Foo { ... }
fn foo2() -> Foo { foo1() }
```

then 'foo2' doesn't end up constraining 'Foo', which means that
'foo2' will end up using the type 'Foo' internally - that is, an actual
'TyKind::Opaque'. We don't want to equate this to the underlying
concrete type - we just need to enforce the basic equality constraint
between the two types (here, the return type of 'foo1' and the return
type of 'foo2')

Aaron1011 added a commit to Aaron1011/rust that referenced this issue Jul 5, 2019

Fix cycle error with existential types
Fixes rust-lang#61863

We now allow uses of 'existential type's that aren't defining uses -
that is, uses which don't constrain the underlying concrete type.

To make this work correctly, we also modify eq_opaque_type_and_type to
not try to apply additional constraints to an opaque type. If we have
code like this:

```
existential type Foo;
fn foo1() -> Foo { ... }
fn foo2() -> Foo { foo1() }
```

then 'foo2' doesn't end up constraining 'Foo', which means that
'foo2' will end up using the type 'Foo' internally - that is, an actual
'TyKind::Opaque'. We don't want to equate this to the underlying
concrete type - we just need to enforce the basic equality constraint
between the two types (here, the return type of 'foo1' and the return
type of 'foo2')

@Aaron1011 Aaron1011 referenced a pull request that will close this issue Jul 5, 2019

Open

Fix cycle error with existential types #62423

Aaron1011 added a commit to Aaron1011/rust that referenced this issue Jul 7, 2019

Fix cycle error with existential types
Fixes rust-lang#61863

We now allow uses of 'existential type's that aren't defining uses -
that is, uses which don't constrain the underlying concrete type.

To make this work correctly, we also modify eq_opaque_type_and_type to
not try to apply additional constraints to an opaque type. If we have
code like this:

```
existential type Foo;
fn foo1() -> Foo { ... }
fn foo2() -> Foo { foo1() }
```

then 'foo2' doesn't end up constraining 'Foo', which means that
'foo2' will end up using the type 'Foo' internally - that is, an actual
'TyKind::Opaque'. We don't want to equate this to the underlying
concrete type - we just need to enforce the basic equality constraint
between the two types (here, the return type of 'foo1' and the return
type of 'foo2')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.