aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/tests/traits.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-02-09 11:35:08 +0000
committerGitHub <[email protected]>2020-02-09 11:35:08 +0000
commit01836a0f35fa163025c64cabe1d0c34bb4f69c92 (patch)
treeaa1a3cf97173b2885f8b6d23002c73196f9a0b61 /crates/ra_hir_ty/src/tests/traits.rs
parent961a69b88f923d4477ca4f746a793217a0cc8576 (diff)
parenteefe02ce6e1750b771cf99125429358e87485745 (diff)
Merge #3050
3050: Refactor type parameters, implement argument position impl trait r=matklad a=flodiebold I wanted to implement APIT by lowering to type parameters because we need to do that anyway for correctness and don't need Chalk support for it; this grew into some more wide-ranging refactoring of how type parameters are handled :sweat_smile: - use Ty::Bound instead of Ty::Param to represent polymorphism, and explicitly count binders. This gets us closer to Chalk's way of doing things, and means that we now only use Param as a placeholder for an unknown type, e.g. within a generic function. I.e. we're never using Param in a situation where we want to substitute it, and the method to do that is gone; `subst` now always works on bound variables. (This changes how the types of generic functions print; previously, you'd get something like `fn identity<i32>(T) -> T`, but now we display the substituted signature `fn identity<i32>(i32) -> i32`, which I think makes more sense.) - once we do this, it's more natural to represent `Param` by a globally unique ID; the use of indices was mostly to make substituting easier. This also means we fix the bug where `Param` loses its name when going through Chalk. - I would actually like to rename `Param` to `Placeholder` to better reflect its use and get closer to Chalk, but I'll leave that to a follow-up. - introduce a context for type lowering, to allow lowering `impl Trait` to different things depending on where we are. And since we have that, we can also lower type parameters directly to variables instead of placeholders. Also, we'll be able to use this later to collect diagnostics. - implement argument position impl trait by lowering it to type parameters. I've realized that this is necessary to correctly implement it; e.g. consider `fn foo(impl Display) -> impl Something`. It's observable that the return type of e.g. `foo(1u32)` unifies with itself, but doesn't unify with e.g. `foo(1i32)`; so the return type needs to be parameterized by the argument type. This fixes a few bugs as well: - type parameters 'losing' their name when they go through Chalk, as mentioned above (i.e. getting `[missing name]` somewhere) - impl trait not being considered as implementing the super traits (very noticeable for the `db` in RA) - the fact that argument impl trait was only turned into variables when the function got called caused type mismatches when the function was used as a value (fixes a few type mismatches in RA) The one thing I'm not so happy with here is how we're lowering `impl Trait` types to variables; since `TypeRef`s don't have an identity currently, we just count how many of them we have seen while going through the function signature. That's quite fragile though, since we have to do it while desugaring generics and while lowering the type signature, and in the exact same order in both cases. We could consider either giving only `TypeRef::ImplTrait` a local id, or maybe just giving all `TypeRef`s an identity after all (we talked about this before)... Follow-up tasks: - handle return position impl trait; we basically need to create a variable and some trait obligations for that variable - rename `Param` to `Placeholder` Co-authored-by: Florian Diebold <[email protected]> Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/tests/traits.rs')
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs312
1 files changed, 257 insertions, 55 deletions
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index a6ac18f86..17611ddbf 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -1,7 +1,6 @@
1use insta::assert_snapshot; 1use insta::assert_snapshot;
2 2
3use ra_db::fixture::WithFixture; 3use ra_db::fixture::WithFixture;
4use test_utils::covers;
5 4
6use super::{infer, infer_with_mismatches, type_at, type_at_pos}; 5use super::{infer, infer_with_mismatches, type_at, type_at_pos};
7use crate::test_db::TestDB; 6use crate::test_db::TestDB;
@@ -261,10 +260,10 @@ fn test() {
261 [92; 94) '{}': () 260 [92; 94) '{}': ()
262 [105; 144) '{ ...(s); }': () 261 [105; 144) '{ ...(s); }': ()
263 [115; 116) 's': S<u32> 262 [115; 116) 's': S<u32>
264 [119; 120) 'S': S<u32>(T) -> S<T> 263 [119; 120) 'S': S<u32>(u32) -> S<u32>
265 [119; 129) 'S(unknown)': S<u32> 264 [119; 129) 'S(unknown)': S<u32>
266 [121; 128) 'unknown': u32 265 [121; 128) 'unknown': u32
267 [135; 138) 'foo': fn foo<S<u32>>(T) -> () 266 [135; 138) 'foo': fn foo<S<u32>>(S<u32>) -> ()
268 [135; 141) 'foo(s)': () 267 [135; 141) 'foo(s)': ()
269 [139; 140) 's': S<u32> 268 [139; 140) 's': S<u32>
270 "### 269 "###
@@ -289,11 +288,11 @@ fn test() {
289 [98; 100) '{}': () 288 [98; 100) '{}': ()
290 [111; 163) '{ ...(s); }': () 289 [111; 163) '{ ...(s); }': ()
291 [121; 122) 's': S<u32> 290 [121; 122) 's': S<u32>
292 [125; 126) 'S': S<u32>(T) -> S<T> 291 [125; 126) 'S': S<u32>(u32) -> S<u32>
293 [125; 135) 'S(unknown)': S<u32> 292 [125; 135) 'S(unknown)': S<u32>
294 [127; 134) 'unknown': u32 293 [127; 134) 'unknown': u32
295 [145; 146) 'x': u32 294 [145; 146) 'x': u32
296 [154; 157) 'foo': fn foo<u32, S<u32>>(T) -> U 295 [154; 157) 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32
297 [154; 160) 'foo(s)': u32 296 [154; 160) 'foo(s)': u32
298 [158; 159) 's': S<u32> 297 [158; 159) 's': S<u32>
299 "### 298 "###
@@ -358,15 +357,15 @@ fn test() {
358 [221; 223) '{}': () 357 [221; 223) '{}': ()
359 [234; 300) '{ ...(S); }': () 358 [234; 300) '{ ...(S); }': ()
360 [244; 245) 'x': u32 359 [244; 245) 'x': u32
361 [248; 252) 'foo1': fn foo1<S>(T) -> <T as Iterable>::Item 360 [248; 252) 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item
362 [248; 255) 'foo1(S)': u32 361 [248; 255) 'foo1(S)': u32
363 [253; 254) 'S': S 362 [253; 254) 'S': S
364 [265; 266) 'y': u32 363 [265; 266) 'y': u32
365 [269; 273) 'foo2': fn foo2<S>(T) -> <T as Iterable>::Item 364 [269; 273) 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item
366 [269; 276) 'foo2(S)': u32 365 [269; 276) 'foo2(S)': u32
367 [274; 275) 'S': S 366 [274; 275) 'S': S
368 [286; 287) 'z': u32 367 [286; 287) 'z': u32
369 [290; 294) 'foo3': fn foo3<S>(T) -> <T as Iterable>::Item 368 [290; 294) 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item
370 [290; 297) 'foo3(S)': u32 369 [290; 297) 'foo3(S)': u32
371 [295; 296) 'S': S 370 [295; 296) 'S': S
372 "### 371 "###
@@ -822,8 +821,7 @@ fn test<T: ApplyL>() {
822"#, 821"#,
823 ); 822 );
824 // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out<T>` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types]. 823 // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out<T>` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types].
825 // FIXME: fix type parameter names going missing when going through Chalk 824 assert_eq!(t, "ApplyL::Out<T>");
826 assert_eq!(t, "ApplyL::Out<[missing name]>");
827} 825}
828 826
829#[test] 827#[test]
@@ -850,6 +848,197 @@ fn test<T: ApplyL>(t: T) {
850} 848}
851 849
852#[test] 850#[test]
851fn argument_impl_trait() {
852 assert_snapshot!(
853 infer_with_mismatches(r#"
854trait Trait<T> {
855 fn foo(&self) -> T;
856 fn foo2(&self) -> i64;
857}
858fn bar(x: impl Trait<u16>) {}
859struct S<T>(T);
860impl<T> Trait<T> for S<T> {}
861
862fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
863 x;
864 y;
865 let z = S(1);
866 bar(z);
867 x.foo();
868 y.foo();
869 z.foo();
870 x.foo2();
871 y.foo2();
872 z.foo2();
873}
874"#, true),
875 @r###"
876 [30; 34) 'self': &Self
877 [55; 59) 'self': &Self
878 [78; 79) 'x': impl Trait<u16>
879 [98; 100) '{}': ()
880 [155; 156) 'x': impl Trait<u64>
881 [175; 176) 'y': &impl Trait<u32>
882 [196; 324) '{ ...2(); }': ()
883 [202; 203) 'x': impl Trait<u64>
884 [209; 210) 'y': &impl Trait<u32>
885 [220; 221) 'z': S<u16>
886 [224; 225) 'S': S<u16>(u16) -> S<u16>
887 [224; 228) 'S(1)': S<u16>
888 [226; 227) '1': u16
889 [234; 237) 'bar': fn bar(S<u16>) -> ()
890 [234; 240) 'bar(z)': ()
891 [238; 239) 'z': S<u16>
892 [246; 247) 'x': impl Trait<u64>
893 [246; 253) 'x.foo()': u64
894 [259; 260) 'y': &impl Trait<u32>
895 [259; 266) 'y.foo()': u32
896 [272; 273) 'z': S<u16>
897 [272; 279) 'z.foo()': u16
898 [285; 286) 'x': impl Trait<u64>
899 [285; 293) 'x.foo2()': i64
900 [299; 300) 'y': &impl Trait<u32>
901 [299; 307) 'y.foo2()': i64
902 [313; 314) 'z': S<u16>
903 [313; 321) 'z.foo2()': i64
904 "###
905 );
906}
907
908#[test]
909fn argument_impl_trait_type_args_1() {
910 assert_snapshot!(
911 infer_with_mismatches(r#"
912trait Trait {}
913trait Foo {
914 // this function has an implicit Self param, an explicit type param,
915 // and an implicit impl Trait param!
916 fn bar<T>(x: impl Trait) -> T { loop {} }
917}
918fn foo<T>(x: impl Trait) -> T { loop {} }
919struct S;
920impl Trait for S {}
921struct F;
922impl Foo for F {}
923
924fn test() {
925 Foo::bar(S);
926 <F as Foo>::bar(S);
927 F::bar(S);
928 Foo::bar::<u32>(S);
929 <F as Foo>::bar::<u32>(S);
930
931 foo(S);
932 foo::<u32>(S);
933 foo::<u32, i32>(S); // we should ignore the extraneous i32
934}
935"#, true),
936 @r###"
937 [156; 157) 'x': impl Trait
938 [176; 187) '{ loop {} }': T
939 [178; 185) 'loop {}': !
940 [183; 185) '{}': ()
941 [200; 201) 'x': impl Trait
942 [220; 231) '{ loop {} }': T
943 [222; 229) 'loop {}': !
944 [227; 229) '{}': ()
945 [301; 510) '{ ... i32 }': ()
946 [307; 315) 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown}
947 [307; 318) 'Foo::bar(S)': {unknown}
948 [316; 317) 'S': S
949 [324; 339) '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown}
950 [324; 342) '<F as ...bar(S)': {unknown}
951 [340; 341) 'S': S
952 [348; 354) 'F::bar': fn bar<F, {unknown}>(S) -> {unknown}
953 [348; 357) 'F::bar(S)': {unknown}
954 [355; 356) 'S': S
955 [363; 378) 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32
956 [363; 381) 'Foo::b...32>(S)': u32
957 [379; 380) 'S': S
958 [387; 409) '<F as ...:<u32>': fn bar<F, u32>(S) -> u32
959 [387; 412) '<F as ...32>(S)': u32
960 [410; 411) 'S': S
961 [419; 422) 'foo': fn foo<{unknown}>(S) -> {unknown}
962 [419; 425) 'foo(S)': {unknown}
963 [423; 424) 'S': S
964 [431; 441) 'foo::<u32>': fn foo<u32>(S) -> u32
965 [431; 444) 'foo::<u32>(S)': u32
966 [442; 443) 'S': S
967 [450; 465) 'foo::<u32, i32>': fn foo<u32>(S) -> u32
968 [450; 468) 'foo::<...32>(S)': u32
969 [466; 467) 'S': S
970 "###
971 );
972}
973
974#[test]
975fn argument_impl_trait_type_args_2() {
976 assert_snapshot!(
977 infer_with_mismatches(r#"
978trait Trait {}
979struct S;
980impl Trait for S {}
981struct F<T>;
982impl<T> F<T> {
983 fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} }
984}
985
986fn test() {
987 F.foo(S);
988 F::<u32>.foo(S);
989 F::<u32>.foo::<i32>(S);
990 F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored
991}
992"#, true),
993 @r###"
994 [88; 92) 'self': F<T>
995 [94; 95) 'x': impl Trait
996 [119; 130) '{ loop {} }': (T, U)
997 [121; 128) 'loop {}': !
998 [126; 128) '{}': ()
999 [144; 284) '{ ...ored }': ()
1000 [150; 151) 'F': F<{unknown}>
1001 [150; 158) 'F.foo(S)': ({unknown}, {unknown})
1002 [156; 157) 'S': S
1003 [164; 172) 'F::<u32>': F<u32>
1004 [164; 179) 'F::<u32>.foo(S)': (u32, {unknown})
1005 [177; 178) 'S': S
1006 [185; 193) 'F::<u32>': F<u32>
1007 [185; 207) 'F::<u3...32>(S)': (u32, i32)
1008 [205; 206) 'S': S
1009 [213; 221) 'F::<u32>': F<u32>
1010 [213; 240) 'F::<u3...32>(S)': (u32, i32)
1011 [238; 239) 'S': S
1012 "###
1013 );
1014}
1015
1016#[test]
1017fn argument_impl_trait_to_fn_pointer() {
1018 assert_snapshot!(
1019 infer_with_mismatches(r#"
1020trait Trait {}
1021fn foo(x: impl Trait) { loop {} }
1022struct S;
1023impl Trait for S {}
1024
1025fn test() {
1026 let f: fn(S) -> () = foo;
1027}
1028"#, true),
1029 @r###"
1030 [23; 24) 'x': impl Trait
1031 [38; 49) '{ loop {} }': ()
1032 [40; 47) 'loop {}': !
1033 [45; 47) '{}': ()
1034 [91; 124) '{ ...foo; }': ()
1035 [101; 102) 'f': fn(S) -> ()
1036 [118; 121) 'foo': fn foo(S) -> ()
1037 "###
1038 );
1039}
1040
1041#[test]
853#[ignore] 1042#[ignore]
854fn impl_trait() { 1043fn impl_trait() {
855 assert_snapshot!( 1044 assert_snapshot!(
@@ -994,29 +1183,17 @@ fn weird_bounds() {
994 assert_snapshot!( 1183 assert_snapshot!(
995 infer(r#" 1184 infer(r#"
996trait Trait {} 1185trait Trait {}
997fn test() { 1186fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {
998 let a: impl Trait + 'lifetime = foo;
999 let b: impl 'lifetime = foo;
1000 let b: impl (Trait) = foo;
1001 let b: impl ('lifetime) = foo;
1002 let d: impl ?Sized = foo;
1003 let e: impl Trait + ?Sized = foo;
1004} 1187}
1005"#), 1188"#),
1006 @r###" 1189 @r###"
1007 [26; 237) '{ ...foo; }': () 1190 [24; 25) 'a': impl Trait + {error}
1008 [36; 37) 'a': impl Trait + {error} 1191 [51; 52) 'b': impl {error}
1009 [64; 67) 'foo': impl Trait + {error} 1192 [70; 71) 'c': impl Trait
1010 [77; 78) 'b': impl {error} 1193 [87; 88) 'd': impl {error}
1011 [97; 100) 'foo': impl {error} 1194 [108; 109) 'e': impl {error}
1012 [110; 111) 'b': impl Trait 1195 [124; 125) 'f': impl Trait + {error}
1013 [128; 131) 'foo': impl Trait 1196 [148; 151) '{ }': ()
1014 [141; 142) 'b': impl {error}
1015 [163; 166) 'foo': impl {error}
1016 [176; 177) 'd': impl {error}
1017 [193; 196) 'foo': impl {error}
1018 [206; 207) 'e': impl Trait + {error}
1019 [231; 234) 'foo': impl Trait + {error}
1020 "### 1197 "###
1021 ); 1198 );
1022} 1199}
@@ -1078,26 +1255,26 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
1078 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type 1255 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type
1079 [296; 302) 'get(x)': {unknown} 1256 [296; 302) 'get(x)': {unknown}
1080 [300; 301) 'x': T 1257 [300; 301) 'x': T
1081 [308; 312) 'get2': fn get2<{unknown}, T>(T) -> U 1258 [308; 312) 'get2': fn get2<{unknown}, T>(T) -> {unknown}
1082 [308; 315) 'get2(x)': {unknown} 1259 [308; 315) 'get2(x)': {unknown}
1083 [313; 314) 'x': T 1260 [313; 314) 'x': T
1084 [321; 324) 'get': fn get<impl Trait<Type = i64>>(T) -> <T as Trait>::Type 1261 [321; 324) 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type
1085 [321; 327) 'get(y)': {unknown} 1262 [321; 327) 'get(y)': {unknown}
1086 [325; 326) 'y': impl Trait<Type = i64> 1263 [325; 326) 'y': impl Trait<Type = i64>
1087 [333; 337) 'get2': fn get2<{unknown}, impl Trait<Type = i64>>(T) -> U 1264 [333; 337) 'get2': fn get2<{unknown}, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> {unknown}
1088 [333; 340) 'get2(y)': {unknown} 1265 [333; 340) 'get2(y)': {unknown}
1089 [338; 339) 'y': impl Trait<Type = i64> 1266 [338; 339) 'y': impl Trait<Type = i64>
1090 [346; 349) 'get': fn get<S<u64>>(T) -> <T as Trait>::Type 1267 [346; 349) 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type
1091 [346; 357) 'get(set(S))': u64 1268 [346; 357) 'get(set(S))': u64
1092 [350; 353) 'set': fn set<S<u64>>(T) -> T 1269 [350; 353) 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1093 [350; 356) 'set(S)': S<u64> 1270 [350; 356) 'set(S)': S<u64>
1094 [354; 355) 'S': S<u64> 1271 [354; 355) 'S': S<u64>
1095 [363; 367) 'get2': fn get2<u64, S<u64>>(T) -> U 1272 [363; 367) 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64
1096 [363; 375) 'get2(set(S))': u64 1273 [363; 375) 'get2(set(S))': u64
1097 [368; 371) 'set': fn set<S<u64>>(T) -> T 1274 [368; 371) 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1098 [368; 374) 'set(S)': S<u64> 1275 [368; 374) 'set(S)': S<u64>
1099 [372; 373) 'S': S<u64> 1276 [372; 373) 'S': S<u64>
1100 [381; 385) 'get2': fn get2<str, S<str>>(T) -> U 1277 [381; 385) 'get2': fn get2<str, S<str>>(S<str>) -> str
1101 [381; 395) 'get2(S::<str>)': str 1278 [381; 395) 'get2(S::<str>)': str
1102 [386; 394) 'S::<str>': S<str> 1279 [386; 394) 'S::<str>': S<str>
1103 "### 1280 "###
@@ -1225,6 +1402,32 @@ fn test<T: Trait1, U: Trait2>(x: T, y: U) {
1225} 1402}
1226 1403
1227#[test] 1404#[test]
1405fn super_trait_impl_trait_method_resolution() {
1406 assert_snapshot!(
1407 infer(r#"
1408mod foo {
1409 trait SuperTrait {
1410 fn foo(&self) -> u32 {}
1411 }
1412}
1413trait Trait1: foo::SuperTrait {}
1414
1415fn test(x: &impl Trait1) {
1416 x.foo();
1417}
1418"#),
1419 @r###"
1420 [50; 54) 'self': &Self
1421 [63; 65) '{}': ()
1422 [116; 117) 'x': &impl Trait1
1423 [133; 149) '{ ...o(); }': ()
1424 [139; 140) 'x': &impl Trait1
1425 [139; 146) 'x.foo()': u32
1426 "###
1427 );
1428}
1429
1430#[test]
1228fn super_trait_cycle() { 1431fn super_trait_cycle() {
1229 // This just needs to not crash 1432 // This just needs to not crash
1230 assert_snapshot!( 1433 assert_snapshot!(
@@ -1270,9 +1473,9 @@ fn test() {
1270 [157; 160) '{t}': T 1473 [157; 160) '{t}': T
1271 [158; 159) 't': T 1474 [158; 159) 't': T
1272 [259; 280) '{ ...S)); }': () 1475 [259; 280) '{ ...S)); }': ()
1273 [265; 269) 'get2': fn get2<u64, S<u64>>(T) -> U 1476 [265; 269) 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64
1274 [265; 277) 'get2(set(S))': u64 1477 [265; 277) 'get2(set(S))': u64
1275 [270; 273) 'set': fn set<S<u64>>(T) -> T 1478 [270; 273) 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1276 [270; 276) 'set(S)': S<u64> 1479 [270; 276) 'set(S)': S<u64>
1277 [274; 275) 'S': S<u64> 1480 [274; 275) 'S': S<u64>
1278 "### 1481 "###
@@ -1334,7 +1537,7 @@ fn test() {
1334 [173; 175) '{}': () 1537 [173; 175) '{}': ()
1335 [189; 308) '{ ... 1); }': () 1538 [189; 308) '{ ... 1); }': ()
1336 [199; 200) 'x': Option<u32> 1539 [199; 200) 'x': Option<u32>
1337 [203; 215) 'Option::Some': Some<u32>(T) -> Option<T> 1540 [203; 215) 'Option::Some': Some<u32>(u32) -> Option<u32>
1338 [203; 221) 'Option...(1u32)': Option<u32> 1541 [203; 221) 'Option...(1u32)': Option<u32>
1339 [216; 220) '1u32': u32 1542 [216; 220) '1u32': u32
1340 [227; 228) 'x': Option<u32> 1543 [227; 228) 'x': Option<u32>
@@ -1444,7 +1647,7 @@ fn test() {
1444 [340; 342) '{}': () 1647 [340; 342) '{}': ()
1445 [356; 515) '{ ... S); }': () 1648 [356; 515) '{ ... S); }': ()
1446 [366; 368) 'x1': u64 1649 [366; 368) 'x1': u64
1447 [371; 375) 'foo1': fn foo1<S, u64, |S| -> u64>(T, F) -> U 1650 [371; 375) 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
1448 [371; 394) 'foo1(S...hod())': u64 1651 [371; 394) 'foo1(S...hod())': u64
1449 [376; 377) 'S': S 1652 [376; 377) 'S': S
1450 [379; 393) '|s| s.method()': |S| -> u64 1653 [379; 393) '|s| s.method()': |S| -> u64
@@ -1452,7 +1655,7 @@ fn test() {
1452 [383; 384) 's': S 1655 [383; 384) 's': S
1453 [383; 393) 's.method()': u64 1656 [383; 393) 's.method()': u64
1454 [404; 406) 'x2': u64 1657 [404; 406) 'x2': u64
1455 [409; 413) 'foo2': fn foo2<S, u64, |S| -> u64>(F, T) -> U 1658 [409; 413) 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
1456 [409; 432) 'foo2(|...(), S)': u64 1659 [409; 432) 'foo2(|...(), S)': u64
1457 [414; 428) '|s| s.method()': |S| -> u64 1660 [414; 428) '|s| s.method()': |S| -> u64
1458 [415; 416) 's': S 1661 [415; 416) 's': S
@@ -1605,7 +1808,6 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
1605 1808
1606#[test] 1809#[test]
1607fn unify_impl_trait() { 1810fn unify_impl_trait() {
1608 covers!(insert_vars_for_impl_trait);
1609 assert_snapshot!( 1811 assert_snapshot!(
1610 infer_with_mismatches(r#" 1812 infer_with_mismatches(r#"
1611trait Trait<T> {} 1813trait Trait<T> {}
@@ -1637,26 +1839,26 @@ fn test() -> impl Trait<i32> {
1637 [172; 183) '{ loop {} }': T 1839 [172; 183) '{ loop {} }': T
1638 [174; 181) 'loop {}': ! 1840 [174; 181) 'loop {}': !
1639 [179; 181) '{}': () 1841 [179; 181) '{}': ()
1640 [214; 310) '{ ...t()) }': S<i32> 1842 [214; 310) '{ ...t()) }': S<{unknown}>
1641 [224; 226) 's1': S<u32> 1843 [224; 226) 's1': S<u32>
1642 [229; 230) 'S': S<u32>(T) -> S<T> 1844 [229; 230) 'S': S<u32>(u32) -> S<u32>
1643 [229; 241) 'S(default())': S<u32> 1845 [229; 241) 'S(default())': S<u32>
1644 [231; 238) 'default': fn default<u32>() -> T 1846 [231; 238) 'default': fn default<u32>() -> u32
1645 [231; 240) 'default()': u32 1847 [231; 240) 'default()': u32
1646 [247; 250) 'foo': fn foo(impl Trait<u32>) -> () 1848 [247; 250) 'foo': fn foo(S<u32>) -> ()
1647 [247; 254) 'foo(s1)': () 1849 [247; 254) 'foo(s1)': ()
1648 [251; 253) 's1': S<u32> 1850 [251; 253) 's1': S<u32>
1649 [264; 265) 'x': i32 1851 [264; 265) 'x': i32
1650 [273; 276) 'bar': fn bar<i32>(impl Trait<T>) -> T 1852 [273; 276) 'bar': fn bar<i32>(S<i32>) -> i32
1651 [273; 290) 'bar(S(...lt()))': i32 1853 [273; 290) 'bar(S(...lt()))': i32
1652 [277; 278) 'S': S<i32>(T) -> S<T> 1854 [277; 278) 'S': S<i32>(i32) -> S<i32>
1653 [277; 289) 'S(default())': S<i32> 1855 [277; 289) 'S(default())': S<i32>
1654 [279; 286) 'default': fn default<i32>() -> T 1856 [279; 286) 'default': fn default<i32>() -> i32
1655 [279; 288) 'default()': i32 1857 [279; 288) 'default()': i32
1656 [296; 297) 'S': S<i32>(T) -> S<T> 1858 [296; 297) 'S': S<{unknown}>({unknown}) -> S<{unknown}>
1657 [296; 308) 'S(default())': S<i32> 1859 [296; 308) 'S(default())': S<{unknown}>
1658 [298; 305) 'default': fn default<i32>() -> T 1860 [298; 305) 'default': fn default<{unknown}>() -> {unknown}
1659 [298; 307) 'default()': i32 1861 [298; 307) 'default()': {unknown}
1660 "### 1862 "###
1661 ); 1863 );
1662} 1864}