Normalize associated types in types coming from Chalk

Fixes #3232.
This commit is contained in:
Florian Diebold 2020-02-21 13:47:49 +01:00
parent db1bbb11fb
commit e50201345e
2 changed files with 46 additions and 1 deletions

View File

@ -161,7 +161,10 @@ impl<T> Canonicalized<T> {
let new_vars = Substs((0..solution.num_vars).map(|_| ctx.table.new_type_var()).collect());
for (i, ty) in solution.value.into_iter().enumerate() {
let var = self.free_vars[i];
ctx.table.unify(&Ty::Infer(var), &ty.subst_bound_vars(&new_vars));
// eagerly replace projections in the type; we may be getting types
// e.g. from where clauses where this hasn't happened yet
let ty = ctx.normalize_associated_types_in(ty.subst_bound_vars(&new_vars));
ctx.table.unify(&Ty::Infer(var), &ty);
}
}
}

View File

@ -1910,3 +1910,45 @@ fn test() -> impl Trait<i32> {
"###
);
}
#[test]
fn assoc_types_from_bounds() {
assert_snapshot!(
infer(r#"
//- /main.rs
#[lang = "fn_once"]
trait FnOnce<Args> {
type Output;
}
trait T {
type O;
}
impl T for () {
type O = ();
}
fn f<X, F>(_v: F)
where
X: T,
F: FnOnce(&X::O),
{ }
fn main() {
f::<(), _>(|z| { z; });
}
"#),
@r###"
[147; 149) '_v': F
[192; 195) '{ }': ()
[207; 238) '{ ... }); }': ()
[213; 223) 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) -> ()
[213; 235) 'f::<()... z; })': ()
[224; 234) '|z| { z; }': |&()| -> ()
[225; 226) 'z': &()
[228; 234) '{ z; }': ()
[230; 231) 'z': &()
"###
);
}