diff options
author | Florian Diebold <[email protected]> | 2020-02-21 12:47:49 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-02-21 13:06:19 +0000 |
commit | e50201345ecc91b9eeb284cd04c6b55f9c5ce0fd (patch) | |
tree | bfea7d01b69ecc97d57ba7749c08682a7c82169e /crates/ra_hir_ty | |
parent | db1bbb11fbe85a5230452359e80535a2169d0929 (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.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 42 |
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] | ||
1915 | fn assoc_types_from_bounds() { | ||
1916 | assert_snapshot!( | ||
1917 | infer(r#" | ||
1918 | //- /main.rs | ||
1919 | #[lang = "fn_once"] | ||
1920 | trait FnOnce<Args> { | ||
1921 | type Output; | ||
1922 | } | ||
1923 | |||
1924 | trait T { | ||
1925 | type O; | ||
1926 | } | ||
1927 | |||
1928 | impl T for () { | ||
1929 | type O = (); | ||
1930 | } | ||
1931 | |||
1932 | fn f<X, F>(_v: F) | ||
1933 | where | ||
1934 | X: T, | ||
1935 | F: FnOnce(&X::O), | ||
1936 | { } | ||
1937 | |||
1938 | fn 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 | } | ||