aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/tests.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-03-02 13:53:26 +0000
committerFlorian Diebold <[email protected]>2019-03-02 15:42:51 +0000
commitb7fdad8448cbd3a94c2cb877a1d209f3182ca0d5 (patch)
tree5149aa6cb21bd9fe3640a6f8a749000c1f962463 /crates/ra_hir/src/ty/tests.rs
parent00b09bcd8c96c37633964aa40df711dc013a6ca5 (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.rs235
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]
1047fn 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#"
1052trait Trait1 {
1053 fn method(&self) -> u32;
1054}
1055struct S1;
1056impl Trait1 for S1 {}
1057trait Trait2 {
1058 fn method(&self) -> i128;
1059}
1060struct S2;
1061impl Trait2 for S2 {}
1062fn test() {
1063 S1.method(); // -> u32
1064 S2.method(); // -> i128
1065}
1066"#,
1067 );
1068}
1069
1070#[test]
1071fn 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#"
1076struct S;
1077mod foo {
1078 pub trait Trait1 {
1079 fn method(&self) -> u32;
1080 }
1081 impl Trait1 for super::S {}
1082}
1083mod bar {
1084 pub trait Trait2 {
1085 fn method(&self) -> i128;
1086 }
1087 impl Trait2 for super::S {}
1088}
1089
1090mod foo_test {
1091 use super::S;
1092 use super::foo::Trait1;
1093 fn test() {
1094 S.method(); // -> u32
1095 }
1096}
1097
1098mod 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]
1110fn 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#"
1115trait Trait<T> {
1116 fn method(&self) -> T;
1117}
1118struct S;
1119impl Trait<u32> for S {}
1120fn test() {
1121 S.method();
1122}
1123"#,
1124 );
1125}
1126
1127#[test]
1128fn 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#"
1133trait Trait<T> {
1134 fn method(&self) -> T;
1135}
1136struct S<T>(T);
1137impl<U> Trait<U> for S<U> {}
1138fn test() {
1139 S(1u32).method();
1140}
1141"#,
1142 );
1143}
1144
1145#[test]
1146fn infer_trait_assoc_method() {
1147 check_inference(
1148 "infer_trait_assoc_method",
1149 r#"
1150trait Default {
1151 fn default() -> Self;
1152}
1153struct S;
1154impl Default for S {}
1155fn 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]
1165fn infer_from_bound_1() {
1166 check_inference(
1167 "infer_from_bound_1",
1168 r#"
1169trait Trait<T> {}
1170struct S<T>(T);
1171impl<U> Trait<U> for S<U> {}
1172fn foo<T: Trait<u32>>(t: T) {}
1173fn test() {
1174 let s = S(unknown);
1175 foo(s);
1176}
1177"#,
1178 );
1179}
1180
1181#[test]
1182fn infer_from_bound_2() {
1183 check_inference(
1184 "infer_from_bound_2",
1185 r#"
1186trait Trait<T> {}
1187struct S<T>(T);
1188impl<U> Trait<U> for S<U> {}
1189fn foo<U, T: Trait<U>>(t: T) -> U {}
1190fn test() {
1191 let s = S(unknown);
1192 let x: u32 = foo(s);
1193}
1194"#,
1195 );
1196}
1197
1198#[test]
1199fn infer_call_trait_method_on_generic_param_1() {
1200 check_inference(
1201 "infer_call_trait_method_on_generic_param_1",
1202 r#"
1203trait Trait {
1204 fn method() -> u32;
1205}
1206fn test<T: Trait>(t: T) {
1207 t.method();
1208}
1209"#,
1210 );
1211}
1212
1213#[test]
1214fn infer_call_trait_method_on_generic_param_2() {
1215 check_inference(
1216 "infer_call_trait_method_on_generic_param_2",
1217 r#"
1218trait Trait<T> {
1219 fn method() -> T;
1220}
1221fn test<U, T: Trait<U>>(t: T) {
1222 t.method();
1223}
1224"#,
1225 );
1226}
1227
1228#[test]
1229fn infer_with_multiple_trait_impls() {
1230 check_inference(
1231 "infer_with_multiple_trait_impls",
1232 r#"
1233trait Into<T> {
1234 fn into(self) -> T;
1235}
1236struct S;
1237impl Into<u32> for S;
1238impl Into<u64> for S;
1239fn 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]
1249fn infer_project_associated_type() {
1250 check_inference(
1251 "infer_project_associated_type",
1252 r#"
1253trait Iterable {
1254 type Item;
1255}
1256struct S;
1257impl Iterable for S { type Item = u32; }
1258fn 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]
1267fn infer_associated_type_bound() {
1268 check_inference(
1269 "infer_associated_type_bound",
1270 r#"
1271trait Iterable {
1272 type Item;
1273}
1274fn test<T: Iterable<Item=u32>>() {
1275 let y: T::Item = unknown;
1276}
1277"#,
1278 );
1279}
1280
1046fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 1281fn 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);