3259: Normalize associated types in types coming from Chalk r=matklad a=flodiebold

Fixes #3232.

Co-authored-by: Florian Diebold <florian.diebold@freiheit.com>
This commit is contained in:
bors[bot] 2020-02-21 13:22:06 +00:00 committed by GitHub
commit e3037c2631
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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': &()
"###
);
}