Skip to content

Compiler unable to determine two types are equal #70703

Closed
@grantslatton

Description

@grantslatton

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

Activity

added
A-associated-itemsArea: Associated items (types, constants & functions)
A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.
A-lazy-normalizationArea: Lazy normalization (tracking issue: #60471)
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Apr 2, 2020
rodrimati1992

rodrimati1992 commented on Apr 2, 2020

@rodrimati1992
Contributor

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

jonas-schievink commented on Apr 2, 2020

@jonas-schievink
Contributor
jonas-schievink

jonas-schievink commented on Apr 2, 2020

@jonas-schievink
jonas-schievink

jonas-schievink commented on Apr 2, 2020

@jonas-schievink
jonas-schievink

jonas-schievink commented on Apr 3, 2020

@jonas-schievink
Contributor

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

benjaminp commented on Oct 21, 2020

@benjaminp
Contributor

This is fixed on nightly.

added
E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.
on Oct 21, 2020
added a commit that references this issue on Jul 2, 2021

Rollup merge of rust-lang#86796 - JohnTitor:test-70703, r=jonas-schie…

f6ef2c8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-lazy-normalizationArea: Lazy normalization (tracking issue: #60471)C-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @benjaminp@jonas-schievink@grantslatton@rodrimati1992

      Issue actions

        Compiler unable to determine two types are equal · Issue #70703 · rust-lang/rust