diff options
Diffstat (limited to 'crates/hir_ty/src/tests')
-rw-r--r-- | crates/hir_ty/src/tests/macros.rs | 199 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/method_resolution.rs | 37 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/regression.rs | 38 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/simple.rs | 54 |
4 files changed, 327 insertions, 1 deletions
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs index b8e373ed8..6588aa46c 100644 --- a/crates/hir_ty/src/tests/macros.rs +++ b/crates/hir_ty/src/tests/macros.rs | |||
@@ -1074,3 +1074,202 @@ fn macro_in_arm() { | |||
1074 | "#]], | 1074 | "#]], |
1075 | ); | 1075 | ); |
1076 | } | 1076 | } |
1077 | |||
1078 | #[test] | ||
1079 | fn macro_in_type_alias_position() { | ||
1080 | check_infer( | ||
1081 | r#" | ||
1082 | macro_rules! U32 { | ||
1083 | () => { u32 }; | ||
1084 | } | ||
1085 | |||
1086 | trait Foo { | ||
1087 | type Ty; | ||
1088 | } | ||
1089 | |||
1090 | impl<T> Foo for T { | ||
1091 | type Ty = U32!(); | ||
1092 | } | ||
1093 | |||
1094 | type TayTo = U32!(); | ||
1095 | |||
1096 | fn testy() { | ||
1097 | let a: <() as Foo>::Ty; | ||
1098 | let b: TayTo; | ||
1099 | } | ||
1100 | "#, | ||
1101 | expect![[r#" | ||
1102 | 147..196 '{ ...yTo; }': () | ||
1103 | 157..158 'a': u32 | ||
1104 | 185..186 'b': u32 | ||
1105 | "#]], | ||
1106 | ); | ||
1107 | } | ||
1108 | |||
1109 | #[test] | ||
1110 | fn nested_macro_in_type_alias_position() { | ||
1111 | check_infer( | ||
1112 | r#" | ||
1113 | macro_rules! U32Inner2 { | ||
1114 | () => { u32 }; | ||
1115 | } | ||
1116 | |||
1117 | macro_rules! U32Inner1 { | ||
1118 | () => { U32Inner2!() }; | ||
1119 | } | ||
1120 | |||
1121 | macro_rules! U32 { | ||
1122 | () => { U32Inner1!() }; | ||
1123 | } | ||
1124 | |||
1125 | trait Foo { | ||
1126 | type Ty; | ||
1127 | } | ||
1128 | |||
1129 | impl<T> Foo for T { | ||
1130 | type Ty = U32!(); | ||
1131 | } | ||
1132 | |||
1133 | type TayTo = U32!(); | ||
1134 | |||
1135 | fn testy() { | ||
1136 | let a: <() as Foo>::Ty; | ||
1137 | let b: TayTo; | ||
1138 | } | ||
1139 | "#, | ||
1140 | expect![[r#" | ||
1141 | 259..308 '{ ...yTo; }': () | ||
1142 | 269..270 'a': u32 | ||
1143 | 297..298 'b': u32 | ||
1144 | "#]], | ||
1145 | ); | ||
1146 | } | ||
1147 | |||
1148 | #[test] | ||
1149 | fn macros_in_type_alias_position_generics() { | ||
1150 | check_infer( | ||
1151 | r#" | ||
1152 | struct Foo<A, B>(A, B); | ||
1153 | |||
1154 | macro_rules! U32 { | ||
1155 | () => { u32 }; | ||
1156 | } | ||
1157 | |||
1158 | macro_rules! Bar { | ||
1159 | () => { Foo<U32!(), U32!()> }; | ||
1160 | } | ||
1161 | |||
1162 | trait Moo { | ||
1163 | type Ty; | ||
1164 | } | ||
1165 | |||
1166 | impl<T> Moo for T { | ||
1167 | type Ty = Bar!(); | ||
1168 | } | ||
1169 | |||
1170 | type TayTo = Bar!(); | ||
1171 | |||
1172 | fn main() { | ||
1173 | let a: <() as Moo>::Ty; | ||
1174 | let b: TayTo; | ||
1175 | } | ||
1176 | "#, | ||
1177 | expect![[r#" | ||
1178 | 228..277 '{ ...yTo; }': () | ||
1179 | 238..239 'a': Foo<u32, u32> | ||
1180 | 266..267 'b': Foo<u32, u32> | ||
1181 | "#]], | ||
1182 | ); | ||
1183 | } | ||
1184 | |||
1185 | #[test] | ||
1186 | fn macros_in_type_position() { | ||
1187 | check_infer( | ||
1188 | r#" | ||
1189 | struct Foo<A, B>(A, B); | ||
1190 | |||
1191 | macro_rules! U32 { | ||
1192 | () => { u32 }; | ||
1193 | } | ||
1194 | |||
1195 | macro_rules! Bar { | ||
1196 | () => { Foo<U32!(), U32!()> }; | ||
1197 | } | ||
1198 | |||
1199 | fn main() { | ||
1200 | let a: Bar!(); | ||
1201 | } | ||
1202 | "#, | ||
1203 | expect![[r#" | ||
1204 | 133..155 '{ ...!(); }': () | ||
1205 | 143..144 'a': Foo<u32, u32> | ||
1206 | "#]], | ||
1207 | ); | ||
1208 | } | ||
1209 | |||
1210 | #[test] | ||
1211 | fn macros_in_type_generics() { | ||
1212 | check_infer( | ||
1213 | r#" | ||
1214 | struct Foo<A, B>(A, B); | ||
1215 | |||
1216 | macro_rules! U32 { | ||
1217 | () => { u32 }; | ||
1218 | } | ||
1219 | |||
1220 | macro_rules! Bar { | ||
1221 | () => { Foo<U32!(), U32!()> }; | ||
1222 | } | ||
1223 | |||
1224 | trait Moo { | ||
1225 | type Ty; | ||
1226 | } | ||
1227 | |||
1228 | impl<T> Moo for T { | ||
1229 | type Ty = Foo<Bar!(), Bar!()>; | ||
1230 | } | ||
1231 | |||
1232 | type TayTo = Foo<Bar!(), U32!()>; | ||
1233 | |||
1234 | fn main() { | ||
1235 | let a: <() as Moo>::Ty; | ||
1236 | let b: TayTo; | ||
1237 | } | ||
1238 | "#, | ||
1239 | expect![[r#" | ||
1240 | 254..303 '{ ...yTo; }': () | ||
1241 | 264..265 'a': Foo<Foo<u32, u32>, Foo<u32, u32>> | ||
1242 | 292..293 'b': Foo<Foo<u32, u32>, u32> | ||
1243 | "#]], | ||
1244 | ); | ||
1245 | } | ||
1246 | |||
1247 | #[test] | ||
1248 | fn infinitely_recursive_macro_type() { | ||
1249 | check_infer( | ||
1250 | r#" | ||
1251 | struct Bar<T, X>(T, X); | ||
1252 | |||
1253 | macro_rules! Foo { | ||
1254 | () => { Foo!() } | ||
1255 | } | ||
1256 | |||
1257 | macro_rules! U32 { | ||
1258 | () => { u32 } | ||
1259 | } | ||
1260 | |||
1261 | type A = Foo!(); | ||
1262 | type B = Bar<Foo!(), U32!()>; | ||
1263 | |||
1264 | fn main() { | ||
1265 | let a: A; | ||
1266 | let b: B; | ||
1267 | } | ||
1268 | "#, | ||
1269 | expect![[r#" | ||
1270 | 166..197 '{ ...: B; }': () | ||
1271 | 176..177 'a': {unknown} | ||
1272 | 190..191 'b': Bar<{unknown}, u32> | ||
1273 | "#]], | ||
1274 | ); | ||
1275 | } | ||
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs index 4b2c82b41..a4c132bc5 100644 --- a/crates/hir_ty/src/tests/method_resolution.rs +++ b/crates/hir_ty/src/tests/method_resolution.rs | |||
@@ -1294,7 +1294,7 @@ mod b { | |||
1294 | } | 1294 | } |
1295 | 1295 | ||
1296 | #[test] | 1296 | #[test] |
1297 | fn impl_in_unnamed_const() { | 1297 | fn trait_impl_in_unnamed_const() { |
1298 | check_types( | 1298 | check_types( |
1299 | r#" | 1299 | r#" |
1300 | struct S; | 1300 | struct S; |
@@ -1314,3 +1314,38 @@ fn f() { | |||
1314 | "#, | 1314 | "#, |
1315 | ); | 1315 | ); |
1316 | } | 1316 | } |
1317 | |||
1318 | #[test] | ||
1319 | fn inherent_impl_in_unnamed_const() { | ||
1320 | check_types( | ||
1321 | r#" | ||
1322 | struct S; | ||
1323 | |||
1324 | const _: () = { | ||
1325 | impl S { | ||
1326 | fn method(&self) -> u16 { 0 } | ||
1327 | |||
1328 | pub(super) fn super_method(&self) -> u16 { 0 } | ||
1329 | |||
1330 | pub(crate) fn crate_method(&self) -> u16 { 0 } | ||
1331 | |||
1332 | pub fn pub_method(&self) -> u16 { 0 } | ||
1333 | } | ||
1334 | }; | ||
1335 | |||
1336 | fn f() { | ||
1337 | S.method(); | ||
1338 | //^^^^^^^^^^ u16 | ||
1339 | |||
1340 | S.super_method(); | ||
1341 | //^^^^^^^^^^^^^^^^ u16 | ||
1342 | |||
1343 | S.crate_method(); | ||
1344 | //^^^^^^^^^^^^^^^^ u16 | ||
1345 | |||
1346 | S.pub_method(); | ||
1347 | //^^^^^^^^^^^^^^ u16 | ||
1348 | } | ||
1349 | "#, | ||
1350 | ); | ||
1351 | } | ||
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index 9cd9f473d..d14f5c9bb 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs | |||
@@ -1012,3 +1012,41 @@ fn lifetime_from_chalk_during_deref() { | |||
1012 | "#, | 1012 | "#, |
1013 | ) | 1013 | ) |
1014 | } | 1014 | } |
1015 | |||
1016 | #[test] | ||
1017 | fn issue_8686() { | ||
1018 | check_infer( | ||
1019 | r#" | ||
1020 | pub trait Try: FromResidual { | ||
1021 | type Output; | ||
1022 | type Residual; | ||
1023 | } | ||
1024 | pub trait FromResidual<R = <Self as Try>::Residual> { | ||
1025 | fn from_residual(residual: R) -> Self; | ||
1026 | } | ||
1027 | |||
1028 | struct ControlFlow<B, C>; | ||
1029 | impl<B, C> Try for ControlFlow<B, C> { | ||
1030 | type Output = C; | ||
1031 | type Residual = ControlFlow<B, !>; | ||
1032 | } | ||
1033 | impl<B, C> FromResidual for ControlFlow<B, C> { | ||
1034 | fn from_residual(r: ControlFlow<B, !>) -> Self { ControlFlow } | ||
1035 | } | ||
1036 | |||
1037 | fn test() { | ||
1038 | ControlFlow::from_residual(ControlFlow::<u32, !>); | ||
1039 | } | ||
1040 | "#, | ||
1041 | expect![[r#" | ||
1042 | 144..152 'residual': R | ||
1043 | 365..366 'r': ControlFlow<B, !> | ||
1044 | 395..410 '{ ControlFlow }': ControlFlow<B, C> | ||
1045 | 397..408 'ControlFlow': ControlFlow<B, C> | ||
1046 | 424..482 '{ ...!>); }': () | ||
1047 | 430..456 'Contro...sidual': fn from_residual<ControlFlow<u32, {unknown}>, ControlFlow<u32, !>>(ControlFlow<u32, !>) -> ControlFlow<u32, {unknown}> | ||
1048 | 430..479 'Contro...2, !>)': ControlFlow<u32, {unknown}> | ||
1049 | 457..478 'Contro...32, !>': ControlFlow<u32, !> | ||
1050 | "#]], | ||
1051 | ); | ||
1052 | } | ||
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 84c5c05fd..0eefd70f2 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs | |||
@@ -1029,6 +1029,42 @@ fn infer_in_elseif() { | |||
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | #[test] | 1031 | #[test] |
1032 | fn infer_closure_unify() { | ||
1033 | check_infer( | ||
1034 | r#" | ||
1035 | fn foo(f: bool) { | ||
1036 | let a = |x| x; | ||
1037 | let b = |x| x; | ||
1038 | let id = if f { a } else { b }; | ||
1039 | id(123); | ||
1040 | } | ||
1041 | "#, | ||
1042 | expect![[r#" | ||
1043 | 7..8 'f': bool | ||
1044 | 16..106 '{ ...23); }': () | ||
1045 | 26..27 'a': |i32| -> i32 | ||
1046 | 30..35 '|x| x': |i32| -> i32 | ||
1047 | 31..32 'x': i32 | ||
1048 | 34..35 'x': i32 | ||
1049 | 45..46 'b': |i32| -> i32 | ||
1050 | 49..54 '|x| x': |i32| -> i32 | ||
1051 | 50..51 'x': i32 | ||
1052 | 53..54 'x': i32 | ||
1053 | 64..66 'id': |i32| -> i32 | ||
1054 | 69..90 'if f {... { b }': |i32| -> i32 | ||
1055 | 72..73 'f': bool | ||
1056 | 74..79 '{ a }': |i32| -> i32 | ||
1057 | 76..77 'a': |i32| -> i32 | ||
1058 | 85..90 '{ b }': |i32| -> i32 | ||
1059 | 87..88 'b': |i32| -> i32 | ||
1060 | 96..98 'id': |i32| -> i32 | ||
1061 | 96..103 'id(123)': i32 | ||
1062 | 99..102 '123': i32 | ||
1063 | "#]], | ||
1064 | ) | ||
1065 | } | ||
1066 | |||
1067 | #[test] | ||
1032 | fn infer_if_match_with_return() { | 1068 | fn infer_if_match_with_return() { |
1033 | check_infer( | 1069 | check_infer( |
1034 | r#" | 1070 | r#" |
@@ -1765,6 +1801,24 @@ fn main() { | |||
1765 | } | 1801 | } |
1766 | 1802 | ||
1767 | #[test] | 1803 | #[test] |
1804 | fn shadowing_primitive_with_inner_items() { | ||
1805 | check_types( | ||
1806 | r#" | ||
1807 | struct i32; | ||
1808 | struct Foo; | ||
1809 | |||
1810 | impl i32 { fn foo(&self) -> Foo { Foo } } | ||
1811 | |||
1812 | fn main() { | ||
1813 | fn inner() {} | ||
1814 | let x: i32 = i32; | ||
1815 | x.foo(); | ||
1816 | //^ Foo | ||
1817 | }"#, | ||
1818 | ); | ||
1819 | } | ||
1820 | |||
1821 | #[test] | ||
1768 | fn not_shadowing_primitive_by_module() { | 1822 | fn not_shadowing_primitive_by_module() { |
1769 | check_types( | 1823 | check_types( |
1770 | r#" | 1824 | r#" |