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

Compiler unable to determine two types are equal #70703

Closed
grantslatton opened this issue Apr 2, 2020 · 6 comments · Fixed by #86796
Closed

Compiler unable to determine two types are equal #70703

grantslatton opened this issue Apr 2, 2020 · 6 comments · Fixed by #86796
Labels
A-associated-items A-impl-trait A-lazy-normalization C-bug E-needs-test T-compiler

Comments

@grantslatton
Copy link

@grantslatton grantslatton commented Apr 2, 2020

The compiler seems unable to determine that two types are equal.

I tried this code:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b363f89f0e686e243f3a92dcc1cfc09a

trait Factory {
    type Product;
}

impl Factory for () {
    type Product = ();
}

trait ProductConsumer<P> {
    fn consume(self, product: P);
}

impl <P> ProductConsumer<P> for () {
    fn consume(self, product: P) {}
}


fn make_product_consumer<F: Factory>(f: F) -> impl ProductConsumer<F::Product> {
    ()
}

fn main() {
    let consumer = make_product_consumer(());
    consumer.consume(());
}

I expected the program to compile and run without issue, because <() as Factory>::Product> is (), so the consume call should be fine.

Instead, I got this error message:

error[E0308]: mismatched types
  --> src/main.rs:25:22
   |
25 |     consumer.consume(());
   |                      ^^ expected associated type, found `()`
   |
   = note: expected associated type `<() as Factory>::Product`
                    found unit type `()`

The problem exists on stable 1.42 and nightly 1.44

@grantslatton grantslatton added the C-bug label Apr 2, 2020
@jonas-schievink jonas-schievink added A-associated-items A-impl-trait A-lazy-normalization T-compiler labels Apr 2, 2020
@rodrimati1992
Copy link
Contributor

@rodrimati1992 rodrimati1992 commented Apr 2, 2020

It somehow compiles if you replace the associated type with a type parameter:

fn make_product_consumer<T,F: Factory<Product=T>>(f: F) -> impl ProductConsumer<T> {
    ()
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=44455a7c12a77aa33c75b2c95658ebdb

@jonas-schievink
Copy link
Member

@jonas-schievink jonas-schievink commented Apr 2, 2020

cc #60414 / #62221

@jonas-schievink

This comment has been minimized.

@jonas-schievink

This comment has been minimized.

@jonas-schievink
Copy link
Member

@jonas-schievink jonas-schievink commented Apr 3, 2020

Duh, I forgot how opaque types work.

Not sure where <opaque>: ProductConsumer<<() as Factory>::Product> would be stored (ParamEnv? It's empty at this point according to log), but it's definitely not in the type, so this output makes sense.

@benjaminp
Copy link
Contributor

@benjaminp benjaminp commented Oct 21, 2020

This is fixed on nightly.

@jonas-schievink jonas-schievink added the E-needs-test label Oct 21, 2020
@bors bors closed this as completed in f6ef2c8 Jul 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items A-impl-trait A-lazy-normalization C-bug E-needs-test T-compiler
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants