aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-02-21 12:47:49 +0000
committerFlorian Diebold <[email protected]>2020-02-21 13:06:19 +0000
commite50201345ecc91b9eeb284cd04c6b55f9c5ce0fd (patch)
treebfea7d01b69ecc97d57ba7749c08682a7c82169e /crates/ra_hir_ty
parentdb1bbb11fbe85a5230452359e80535a2169d0929 (diff)
Normalize associated types in types coming from Chalk
Fixes #3232.
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/infer/unify.rs5
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs42
2 files changed, 46 insertions, 1 deletions
diff --git a/crates/ra_hir_ty/src/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs
index 9c7996572..2d03c5c33 100644
--- a/crates/ra_hir_ty/src/infer/unify.rs
+++ b/crates/ra_hir_ty/src/infer/unify.rs
@@ -161,7 +161,10 @@ impl<T> Canonicalized<T> {
161 let new_vars = Substs((0..solution.num_vars).map(|_| ctx.table.new_type_var()).collect()); 161 let new_vars = Substs((0..solution.num_vars).map(|_| ctx.table.new_type_var()).collect());
162 for (i, ty) in solution.value.into_iter().enumerate() { 162 for (i, ty) in solution.value.into_iter().enumerate() {
163 let var = self.free_vars[i]; 163 let var = self.free_vars[i];
164 ctx.table.unify(&Ty::Infer(var), &ty.subst_bound_vars(&new_vars)); 164 // eagerly replace projections in the type; we may be getting types
165 // e.g. from where clauses where this hasn't happened yet
166 let ty = ctx.normalize_associated_types_in(ty.subst_bound_vars(&new_vars));
167 ctx.table.unify(&Ty::Infer(var), &ty);
165 } 168 }
166 } 169 }
167} 170}
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index aa2018944..7d796d0b9 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -1910,3 +1910,45 @@ fn test() -> impl Trait<i32> {
1910 "### 1910 "###
1911 ); 1911 );
1912} 1912}
1913
1914#[test]
1915fn assoc_types_from_bounds() {
1916 assert_snapshot!(
1917 infer(r#"
1918//- /main.rs
1919#[lang = "fn_once"]
1920trait FnOnce<Args> {
1921 type Output;
1922}
1923
1924trait T {
1925 type O;
1926}
1927
1928impl T for () {
1929 type O = ();
1930}
1931
1932fn f<X, F>(_v: F)
1933where
1934 X: T,
1935 F: FnOnce(&X::O),
1936{ }
1937
1938fn main() {
1939 f::<(), _>(|z| { z; });
1940}
1941"#),
1942 @r###"
1943 [147; 149) '_v': F
1944 [192; 195) '{ }': ()
1945 [207; 238) '{ ... }); }': ()
1946 [213; 223) 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) -> ()
1947 [213; 235) 'f::<()... z; })': ()
1948 [224; 234) '|z| { z; }': |&()| -> ()
1949 [225; 226) 'z': &()
1950 [228; 234) '{ z; }': ()
1951 [230; 231) 'z': &()
1952 "###
1953 );
1954}