Skip to content

-Ztrait-solver=next-coherence: issue-90662-projection-caching.rs breaks #70

Closed
rust-lang/rust
#119071
@lcnr

Description

@lcnr

minimized https://rust.godbolt.org/z/MK6hWKhdb

trait HasProvider<T: ?Sized> {}
trait Provider<M: ?Sized> {
    type Interface: ?Sized;
}

struct Service;
struct ServiceImpl;
impl<M: HasProvider<&'static ()> + ?Sized> Provider<M> for ServiceImpl {
    type Interface = Service;
}

struct TestModule;
impl HasProvider<&'static ()> for TestModule {}
impl HasProvider<<ServiceImpl as Provider<TestModule>>::Interface> for TestModule {}

for whatever reason dyn Repository breaks, () does not.

why this compiles in the old solver:

  • before equating impl headers, normalize both impls
  • Projection(<ServiceImpl as Provider<TestModule>>::Interface)
  • single candidate with nested goal TestModule: HasProvider<&'static ()> is simply emitted as a nested goal, successfully normalize to Service
  • equating impl HasProvider<&'static ()> for TestModule {} with impl HasProvider<Service> for TestModule {} fails

what's happening in the new solver:

  • coherence equates the two impls, resulting in a nested alias-relate(<ServiceImpl as Provider<TestModule>>::Interface, &'static ())
  • uniquification results in exists<'0> alias-relate(<ServiceImpl as Provider<TestModule>>::Interface, &'0 ())
  • normalizes-to candidat with single impl, normalizing to Service with nested goal TestModule: HasProvider<&'static ()>, again, canonicalized to '0
  • two candidates:
    • impl HasProvider<&'static ()> for TestModule {}, YES '0 == 'static
    • impl HasProvider<<ServiceImpl as Provider<TestModule>>::Interface> for TestModule {}
      • unify <ServiceImpl as Provider<TestModule>>::Interface with &'static (), resulting in an inductive cycle
    • AMBIG
  • WHY DOES ALIAS-RELATE NOT FAIL?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions