diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-05 16:46:28 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-05 16:46:28 +0100 |
commit | 2a3ab7f3b4b6f1917a55025d54ac39b0a0642b6e (patch) | |
tree | c8aa32697a5c7910f8ebbcacf6e06d088bfca833 /crates/ra_hir_ty/src/tests | |
parent | f133159ec0b5037b58a26f52f8b37c545872dc7d (diff) | |
parent | 0d2328f3eaf69c6a50fe6c1e946257bd3503d751 (diff) |
Merge #4689
4689: Implement return position impl trait / opaque type support r=matklad a=flodiebold
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.
Co-authored-by: Florian Diebold <[email protected]>
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/tests')
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 90 |
1 files changed, 89 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..0c538a62d 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,95 @@ fn test(x: impl Trait<u64>, y: &impl Trait<u64>) { | |||
1161 | } | 1160 | } |
1162 | 1161 | ||
1163 | #[test] | 1162 | #[test] |
1163 | fn simple_return_pos_impl_trait() { | ||
1164 | mark::check!(lower_rpit); | ||
1165 | assert_snapshot!( | ||
1166 | infer(r#" | ||
1167 | trait Trait<T> { | ||
1168 | fn foo(&self) -> T; | ||
1169 | } | ||
1170 | fn bar() -> impl Trait<u64> { loop {} } | ||
1171 | |||
1172 | fn test() { | ||
1173 | let a = bar(); | ||
1174 | a.foo(); | ||
1175 | } | ||
1176 | "#), | ||
1177 | @r###" | ||
1178 | 30..34 'self': &Self | ||
1179 | 72..83 '{ loop {} }': ! | ||
1180 | 74..81 'loop {}': ! | ||
1181 | 79..81 '{}': () | ||
1182 | 95..130 '{ ...o(); }': () | ||
1183 | 105..106 'a': impl Trait<u64> | ||
1184 | 109..112 'bar': fn bar() -> impl Trait<u64> | ||
1185 | 109..114 'bar()': impl Trait<u64> | ||
1186 | 120..121 'a': impl Trait<u64> | ||
1187 | 120..127 'a.foo()': u64 | ||
1188 | "### | ||
1189 | ); | ||
1190 | } | ||
1191 | |||
1192 | #[test] | ||
1193 | fn more_return_pos_impl_trait() { | ||
1194 | assert_snapshot!( | ||
1195 | infer(r#" | ||
1196 | trait Iterator { | ||
1197 | type Item; | ||
1198 | fn next(&mut self) -> Self::Item; | ||
1199 | } | ||
1200 | trait Trait<T> { | ||
1201 | fn foo(&self) -> T; | ||
1202 | } | ||
1203 | fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } | ||
1204 | fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} } | ||
1205 | |||
1206 | fn test() { | ||
1207 | let (a, b) = bar(); | ||
1208 | a.next().foo(); | ||
1209 | b.foo(); | ||
1210 | let (c, d) = baz(1u128); | ||
1211 | c.next().foo(); | ||
1212 | d.foo(); | ||
1213 | } | ||
1214 | "#), | ||
1215 | @r###" | ||
1216 | 50..54 'self': &mut Self | ||
1217 | 102..106 'self': &Self | ||
1218 | 185..196 '{ loop {} }': ({unknown}, {unknown}) | ||
1219 | 187..194 'loop {}': ! | ||
1220 | 192..194 '{}': () | ||
1221 | 207..208 't': T | ||
1222 | 269..280 '{ loop {} }': ({unknown}, {unknown}) | ||
1223 | 271..278 'loop {}': ! | ||
1224 | 276..278 '{}': () | ||
1225 | 292..414 '{ ...o(); }': () | ||
1226 | 302..308 '(a, b)': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) | ||
1227 | 303..304 'a': impl Iterator<Item = impl Trait<u32>> | ||
1228 | 306..307 'b': impl Trait<u64> | ||
1229 | 311..314 'bar': fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) | ||
1230 | 311..316 'bar()': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) | ||
1231 | 322..323 'a': impl Iterator<Item = impl Trait<u32>> | ||
1232 | 322..330 'a.next()': impl Trait<u32> | ||
1233 | 322..336 'a.next().foo()': u32 | ||
1234 | 342..343 'b': impl Trait<u64> | ||
1235 | 342..349 'b.foo()': u64 | ||
1236 | 359..365 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | ||
1237 | 360..361 'c': impl Iterator<Item = impl Trait<u128>> | ||
1238 | 363..364 'd': impl Trait<u128> | ||
1239 | 368..371 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | ||
1240 | 368..378 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | ||
1241 | 372..377 '1u128': u128 | ||
1242 | 384..385 'c': impl Iterator<Item = impl Trait<u128>> | ||
1243 | 384..392 'c.next()': impl Trait<u128> | ||
1244 | 384..398 'c.next().foo()': u128 | ||
1245 | 404..405 'd': impl Trait<u128> | ||
1246 | 404..411 'd.foo()': u128 | ||
1247 | "### | ||
1248 | ); | ||
1249 | } | ||
1250 | |||
1251 | #[test] | ||
1164 | fn dyn_trait() { | 1252 | fn dyn_trait() { |
1165 | assert_snapshot!( | 1253 | assert_snapshot!( |
1166 | infer(r#" | 1254 | infer(r#" |