diff options
author | Florian Diebold <[email protected]> | 2019-03-02 13:53:26 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-03-02 15:42:51 +0000 |
commit | b7fdad8448cbd3a94c2cb877a1d209f3182ca0d5 (patch) | |
tree | 5149aa6cb21bd9fe3640a6f8a749000c1f962463 /crates/ra_hir/src/ty/tests.rs | |
parent | 00b09bcd8c96c37633964aa40df711dc013a6ca5 (diff) |
Add a bunch of tests for type inference involving traits
None of them works correctly yet, of course.
Diffstat (limited to 'crates/ra_hir/src/ty/tests.rs')
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 2fdfb54f4..c1bd8d423 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -1043,6 +1043,241 @@ fn test() { | |||
1043 | ); | 1043 | ); |
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | #[test] | ||
1047 | fn infer_trait_method_simple() { | ||
1048 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
1049 | check_inference( | ||
1050 | "infer_trait_method_simple", | ||
1051 | r#" | ||
1052 | trait Trait1 { | ||
1053 | fn method(&self) -> u32; | ||
1054 | } | ||
1055 | struct S1; | ||
1056 | impl Trait1 for S1 {} | ||
1057 | trait Trait2 { | ||
1058 | fn method(&self) -> i128; | ||
1059 | } | ||
1060 | struct S2; | ||
1061 | impl Trait2 for S2 {} | ||
1062 | fn test() { | ||
1063 | S1.method(); // -> u32 | ||
1064 | S2.method(); // -> i128 | ||
1065 | } | ||
1066 | "#, | ||
1067 | ); | ||
1068 | } | ||
1069 | |||
1070 | #[test] | ||
1071 | fn infer_trait_method_scoped() { | ||
1072 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
1073 | check_inference( | ||
1074 | "infer_trait_method_scoped", | ||
1075 | r#" | ||
1076 | struct S; | ||
1077 | mod foo { | ||
1078 | pub trait Trait1 { | ||
1079 | fn method(&self) -> u32; | ||
1080 | } | ||
1081 | impl Trait1 for super::S {} | ||
1082 | } | ||
1083 | mod bar { | ||
1084 | pub trait Trait2 { | ||
1085 | fn method(&self) -> i128; | ||
1086 | } | ||
1087 | impl Trait2 for super::S {} | ||
1088 | } | ||
1089 | |||
1090 | mod foo_test { | ||
1091 | use super::S; | ||
1092 | use super::foo::Trait1; | ||
1093 | fn test() { | ||
1094 | S.method(); // -> u32 | ||
1095 | } | ||
1096 | } | ||
1097 | |||
1098 | mod bar_test { | ||
1099 | use super::S; | ||
1100 | use super::bar::Trait2; | ||
1101 | fn test() { | ||
1102 | S.method(); // -> i128 | ||
1103 | } | ||
1104 | } | ||
1105 | "#, | ||
1106 | ); | ||
1107 | } | ||
1108 | |||
1109 | #[test] | ||
1110 | fn infer_trait_method_generic_1() { | ||
1111 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
1112 | check_inference( | ||
1113 | "infer_trait_method_generic_1", | ||
1114 | r#" | ||
1115 | trait Trait<T> { | ||
1116 | fn method(&self) -> T; | ||
1117 | } | ||
1118 | struct S; | ||
1119 | impl Trait<u32> for S {} | ||
1120 | fn test() { | ||
1121 | S.method(); | ||
1122 | } | ||
1123 | "#, | ||
1124 | ); | ||
1125 | } | ||
1126 | |||
1127 | #[test] | ||
1128 | fn infer_trait_method_generic_2() { | ||
1129 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
1130 | check_inference( | ||
1131 | "infer_trait_method_generic_2", | ||
1132 | r#" | ||
1133 | trait Trait<T> { | ||
1134 | fn method(&self) -> T; | ||
1135 | } | ||
1136 | struct S<T>(T); | ||
1137 | impl<U> Trait<U> for S<U> {} | ||
1138 | fn test() { | ||
1139 | S(1u32).method(); | ||
1140 | } | ||
1141 | "#, | ||
1142 | ); | ||
1143 | } | ||
1144 | |||
1145 | #[test] | ||
1146 | fn infer_trait_assoc_method() { | ||
1147 | check_inference( | ||
1148 | "infer_trait_assoc_method", | ||
1149 | r#" | ||
1150 | trait Default { | ||
1151 | fn default() -> Self; | ||
1152 | } | ||
1153 | struct S; | ||
1154 | impl Default for S {} | ||
1155 | fn test() { | ||
1156 | let s1: S = Default::default(); | ||
1157 | let s2 = S::default(); | ||
1158 | let s3 = <S as Default>::default(); | ||
1159 | } | ||
1160 | "#, | ||
1161 | ); | ||
1162 | } | ||
1163 | |||
1164 | #[test] | ||
1165 | fn infer_from_bound_1() { | ||
1166 | check_inference( | ||
1167 | "infer_from_bound_1", | ||
1168 | r#" | ||
1169 | trait Trait<T> {} | ||
1170 | struct S<T>(T); | ||
1171 | impl<U> Trait<U> for S<U> {} | ||
1172 | fn foo<T: Trait<u32>>(t: T) {} | ||
1173 | fn test() { | ||
1174 | let s = S(unknown); | ||
1175 | foo(s); | ||
1176 | } | ||
1177 | "#, | ||
1178 | ); | ||
1179 | } | ||
1180 | |||
1181 | #[test] | ||
1182 | fn infer_from_bound_2() { | ||
1183 | check_inference( | ||
1184 | "infer_from_bound_2", | ||
1185 | r#" | ||
1186 | trait Trait<T> {} | ||
1187 | struct S<T>(T); | ||
1188 | impl<U> Trait<U> for S<U> {} | ||
1189 | fn foo<U, T: Trait<U>>(t: T) -> U {} | ||
1190 | fn test() { | ||
1191 | let s = S(unknown); | ||
1192 | let x: u32 = foo(s); | ||
1193 | } | ||
1194 | "#, | ||
1195 | ); | ||
1196 | } | ||
1197 | |||
1198 | #[test] | ||
1199 | fn infer_call_trait_method_on_generic_param_1() { | ||
1200 | check_inference( | ||
1201 | "infer_call_trait_method_on_generic_param_1", | ||
1202 | r#" | ||
1203 | trait Trait { | ||
1204 | fn method() -> u32; | ||
1205 | } | ||
1206 | fn test<T: Trait>(t: T) { | ||
1207 | t.method(); | ||
1208 | } | ||
1209 | "#, | ||
1210 | ); | ||
1211 | } | ||
1212 | |||
1213 | #[test] | ||
1214 | fn infer_call_trait_method_on_generic_param_2() { | ||
1215 | check_inference( | ||
1216 | "infer_call_trait_method_on_generic_param_2", | ||
1217 | r#" | ||
1218 | trait Trait<T> { | ||
1219 | fn method() -> T; | ||
1220 | } | ||
1221 | fn test<U, T: Trait<U>>(t: T) { | ||
1222 | t.method(); | ||
1223 | } | ||
1224 | "#, | ||
1225 | ); | ||
1226 | } | ||
1227 | |||
1228 | #[test] | ||
1229 | fn infer_with_multiple_trait_impls() { | ||
1230 | check_inference( | ||
1231 | "infer_with_multiple_trait_impls", | ||
1232 | r#" | ||
1233 | trait Into<T> { | ||
1234 | fn into(self) -> T; | ||
1235 | } | ||
1236 | struct S; | ||
1237 | impl Into<u32> for S; | ||
1238 | impl Into<u64> for S; | ||
1239 | fn test() { | ||
1240 | let x: u32 = S.into(); | ||
1241 | let y: u64 = S.into(); | ||
1242 | let z = Into::<u64>::into(S); | ||
1243 | } | ||
1244 | "#, | ||
1245 | ); | ||
1246 | } | ||
1247 | |||
1248 | #[test] | ||
1249 | fn infer_project_associated_type() { | ||
1250 | check_inference( | ||
1251 | "infer_project_associated_type", | ||
1252 | r#" | ||
1253 | trait Iterable { | ||
1254 | type Item; | ||
1255 | } | ||
1256 | struct S; | ||
1257 | impl Iterable for S { type Item = u32; } | ||
1258 | fn test<T: Iterable>() { | ||
1259 | let x: <S as Iterable>::Item = 1; | ||
1260 | let y: T::Item = no_matter; | ||
1261 | } | ||
1262 | "#, | ||
1263 | ); | ||
1264 | } | ||
1265 | |||
1266 | #[test] | ||
1267 | fn infer_associated_type_bound() { | ||
1268 | check_inference( | ||
1269 | "infer_associated_type_bound", | ||
1270 | r#" | ||
1271 | trait Iterable { | ||
1272 | type Item; | ||
1273 | } | ||
1274 | fn test<T: Iterable<Item=u32>>() { | ||
1275 | let y: T::Item = unknown; | ||
1276 | } | ||
1277 | "#, | ||
1278 | ); | ||
1279 | } | ||
1280 | |||
1046 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 1281 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { |
1047 | let func = source_binder::function_from_position(db, pos).unwrap(); | 1282 | let func = source_binder::function_from_position(db, pos).unwrap(); |
1048 | let body_source_map = func.body_source_map(db); | 1283 | let body_source_map = func.body_source_map(db); |