diff options
author | Florian Diebold <[email protected]> | 2020-03-04 22:00:44 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-06-05 16:08:27 +0100 |
commit | 02962b374ecefd6f2a75956f4fb18806531d1d51 (patch) | |
tree | 7c807d6a09db7e485ea39c3e67331b99829a364c /crates/ra_hir_ty/src/tests | |
parent | 9c52f527a1cef7d39c2b1c55b49dc5459d392a4d (diff) |
Implement return position impl trait / opaque type support
This is working, but I'm not that happy with how the lowering works. We might
need an additional representation between `TypeRef` and `Ty` where names are
resolved and `impl Trait` bounds are separated out, but things like inference
variables don't exist and `impl Trait` is always represented the same
way.
Also note that this doesn't implement correct handling of RPIT *inside* the
function (which involves turning the `impl Trait`s into variables and creating
obligations for them). That intermediate representation might help there as
well.
Diffstat (limited to 'crates/ra_hir_ty/src/tests')
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index e8778d419..d83dc6d79 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -1110,7 +1110,6 @@ fn test() { | |||
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | #[test] | 1112 | #[test] |
1113 | #[ignore] | ||
1114 | fn impl_trait() { | 1113 | fn impl_trait() { |
1115 | assert_snapshot!( | 1114 | assert_snapshot!( |
1116 | infer(r#" | 1115 | infer(r#" |
@@ -1161,6 +1160,52 @@ fn test(x: impl Trait<u64>, y: &impl Trait<u64>) { | |||
1161 | } | 1160 | } |
1162 | 1161 | ||
1163 | #[test] | 1162 | #[test] |
1163 | fn return_pos_impl_trait() { | ||
1164 | assert_snapshot!( | ||
1165 | infer(r#" | ||
1166 | trait Iterator { | ||
1167 | type Item; | ||
1168 | fn next(&mut self) -> Self::Item; | ||
1169 | } | ||
1170 | trait Trait<T> { | ||
1171 | fn foo(&self) -> T; | ||
1172 | } | ||
1173 | fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } | ||
1174 | fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} } | ||
1175 | |||
1176 | fn test() { | ||
1177 | // let (a, b) = bar(); | ||
1178 | // a.next().foo(); | ||
1179 | // b.foo(); | ||
1180 | let (c, d) = baz(1u128); | ||
1181 | c.next();//.foo(); | ||
1182 | // d.foo(); | ||
1183 | } | ||
1184 | "#), | ||
1185 | @r###" | ||
1186 | 50..54 'self': &mut Self | ||
1187 | 102..106 'self': &Self | ||
1188 | 185..196 '{ loop {} }': ({unknown}, {unknown}) | ||
1189 | 187..194 'loop {}': ! | ||
1190 | 192..194 '{}': () | ||
1191 | 207..208 't': T | ||
1192 | 269..280 '{ loop {} }': ({unknown}, {unknown}) | ||
1193 | 271..278 'loop {}': ! | ||
1194 | 276..278 '{}': () | ||
1195 | 292..429 '{ ...o(); }': () | ||
1196 | 368..374 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | ||
1197 | 369..370 'c': impl Iterator<Item = impl Trait<u128>> | ||
1198 | 372..373 'd': impl Trait<u128> | ||
1199 | 377..380 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | ||
1200 | 377..387 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | ||
1201 | 381..386 '1u128': u128 | ||
1202 | 393..394 'c': impl Iterator<Item = impl Trait<u128>> | ||
1203 | 393..401 'c.next()': impl Trait<u128> | ||
1204 | "### | ||
1205 | ); | ||
1206 | } | ||
1207 | |||
1208 | #[test] | ||
1164 | fn dyn_trait() { | 1209 | fn dyn_trait() { |
1165 | assert_snapshot!( | 1210 | assert_snapshot!( |
1166 | infer(r#" | 1211 | infer(r#" |