Resolve Self::AssocTy in impls

To do this we need to carry around the original resolution a bit, because `Self`
gets resolved to the actual type immediately, but you're not allowed to write
the equivalent type in a projection. (I tried just comparing the projection base
type with the impl self type, but that seemed too dirty.) This is basically how
rustc does it as well.

Fixes #3249.
This commit is contained in:
Florian Diebold 2020-03-06 18:08:10 +01:00
parent ce7496ec22
commit d17c5416af
3 changed files with 93 additions and 38 deletions

View file

@ -1802,6 +1802,47 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> {
assert_eq!(t, "u32");
}
#[test]
fn unselected_projection_on_trait_self() {
assert_snapshot!(infer(
r#"
//- /main.rs
trait Trait {
type Item;
fn f(&self, x: Self::Item);
}
struct S;
impl Trait for S {
type Item = u32;
fn f(&self, x: Self::Item) { let y = x; }
}
struct S2;
impl Trait for S2 {
type Item = i32;
fn f(&self, x: <Self>::Item) { let y = x; }
}
"#,
), @r###"
[54; 58) 'self': &Self
[60; 61) 'x': {unknown}
[140; 144) 'self': &S
[146; 147) 'x': u32
[161; 175) '{ let y = x; }': ()
[167; 168) 'y': u32
[171; 172) 'x': u32
[242; 246) 'self': &S2
[248; 249) 'x': i32
[265; 279) '{ let y = x; }': ()
[271; 272) 'y': i32
[275; 276) 'x': i32
"###);
}
#[test]
fn trait_impl_self_ty() {
let t = type_at(