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

Closed
shootingsyh opened this issue Jun 15, 2019 · 1 comment · Fixed by #62423
Closed

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

shootingsyh opened this issue Jun 15, 2019 · 1 comment · Fixed by #62423
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug.

Comments

@shootingsyh
Copy link

shootingsyh 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

@jonas-schievink jonas-schievink added A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. labels Jun 15, 2019
@Aaron1011
Copy link
Member

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 7, 2019
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')
Centril added a commit to Centril/rust that referenced this issue Jul 27, 2019
…oli-obk

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:

```rust
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
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants