Open thomaseizinger opened 1 year ago
I don't think this is a bug. Associated types (projections) are not injective in general. Just because we know that the projected type is String
we should not make assumptions about the self type, here Impl
. In this case, there's indeed only one possibility but as soon as you add another impl, you could potentially get to String
through different impls. I don't know if we should special-case this.
you could potentially get to
String
through different impls.
How? There can only be one implementation of Baz
for Impl
, I am explicitly constructing Impl
und Impl
hardcodes B
in Bar<B>
to be Self
, i.e. Impl
.
The last point is important. The type definition of Impl
literally says Bar<Self>
, why would anything else be allowed?
you could potentially get to
String
through different impls.How? There can only be one implementation of
Baz
forImpl
, I am explicitly constructingImpl
undImpl
hardcodesB
inBar<B>
to beSelf
, i.e.Impl
.The last point is important. The type definition of
Impl
literally saysBar<Self>
, why would anything else be allowed?
Is the problem that type aliases are "invisible" to the type checker? Even if associated types are not injective, it appears that the compiler should be able to look at the definition site of Impl
and reject anything that is not Bar<Impl>
.
I haven't tried but are you saying that I could actually put another impl Baz
into Impl.bar
as long as it has the same associated type? That would be very unintuitive.
I tried this code:
Playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=97b88d916216f04a93c1d24ca2a4f558
I expected to see this happen: It compiles without issues.
Instead, this happened:
Unless I am missing something, the type of
Impl::Bar
is defined unambiguously to beFoo<String>
. It works once you add the type annotation:Meta
The problem is reproducible for stable, beta and nightly (tried in playground).
rustc --version --verbose
: