aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-06-20 15:37:50 +0100
committerFlorian Diebold <[email protected]>2021-06-20 18:12:06 +0100
commit04fbdce426ac8e618ac8b5d136c58cf3427bdd6c (patch)
treeda6096bc68eb33c405c56ac7a9f4f60c235891e6 /crates/hir_ty
parent679bb21633d6bbbf04b4cba5cb70f73cc5f5de19 (diff)
Unify check_mismatches and check_types
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/src/test_db.rs10
-rw-r--r--crates/hir_ty/src/tests.rs151
-rw-r--r--crates/hir_ty/src/tests/coercion.rs4
-rw-r--r--crates/hir_ty/src/tests/macros.rs27
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs264
-rw-r--r--crates/hir_ty/src/tests/patterns.rs4
-rw-r--r--crates/hir_ty/src/tests/regression.rs11
-rw-r--r--crates/hir_ty/src/tests/simple.rs18
-rw-r--r--crates/hir_ty/src/tests/traits.rs244
9 files changed, 353 insertions, 380 deletions
diff --git a/crates/hir_ty/src/test_db.rs b/crates/hir_ty/src/test_db.rs
index 4640ea821..b99a03492 100644
--- a/crates/hir_ty/src/test_db.rs
+++ b/crates/hir_ty/src/test_db.rs
@@ -86,16 +86,20 @@ impl FileLoader for TestDB {
86} 86}
87 87
88impl TestDB { 88impl TestDB {
89 pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId { 89 pub(crate) fn module_for_file_opt(&self, file_id: FileId) -> Option<ModuleId> {
90 for &krate in self.relevant_crates(file_id).iter() { 90 for &krate in self.relevant_crates(file_id).iter() {
91 let crate_def_map = self.crate_def_map(krate); 91 let crate_def_map = self.crate_def_map(krate);
92 for (local_id, data) in crate_def_map.modules() { 92 for (local_id, data) in crate_def_map.modules() {
93 if data.origin.file_id() == Some(file_id) { 93 if data.origin.file_id() == Some(file_id) {
94 return crate_def_map.module_id(local_id); 94 return Some(crate_def_map.module_id(local_id));
95 } 95 }
96 } 96 }
97 } 97 }
98 panic!("Can't find module for file") 98 None
99 }
100
101 pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId {
102 self.module_for_file_opt(file_id).unwrap()
99 } 103 }
100 104
101 pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> { 105 pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index b873585c4..c4f981b44 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -59,14 +59,16 @@ fn setup_tracing() -> Option<tracing::subscriber::DefaultGuard> {
59} 59}
60 60
61fn check_types(ra_fixture: &str) { 61fn check_types(ra_fixture: &str) {
62 check_types_impl(ra_fixture, false) 62 check_impl(ra_fixture, false, true)
63} 63}
64 64
65fn check_types_source_code(ra_fixture: &str) { 65fn check_types_source_code(ra_fixture: &str) {
66 // TODO
66 check_types_impl(ra_fixture, true) 67 check_types_impl(ra_fixture, true)
67} 68}
68 69
69fn check_types_impl(ra_fixture: &str, display_source: bool) { 70fn check_types_impl(ra_fixture: &str, display_source: bool) {
71 // TODO
70 let _tracing = setup_tracing(); 72 let _tracing = setup_tracing();
71 let db = TestDB::with_files(ra_fixture); 73 let db = TestDB::with_files(ra_fixture);
72 let mut checked_one = false; 74 let mut checked_one = false;
@@ -88,22 +90,47 @@ fn check_types_impl(ra_fixture: &str, display_source: bool) {
88} 90}
89 91
90fn check_no_mismatches(ra_fixture: &str) { 92fn check_no_mismatches(ra_fixture: &str) {
91 check_mismatches_impl(ra_fixture, true) 93 check_impl(ra_fixture, true, false)
92} 94}
93 95
94#[allow(unused)] 96fn check(ra_fixture: &str) {
95fn check_mismatches(ra_fixture: &str) { 97 check_impl(ra_fixture, false, false)
96 check_mismatches_impl(ra_fixture, false)
97} 98}
98 99
99fn check_mismatches_impl(ra_fixture: &str, allow_none: bool) { 100fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool) {
100 let _tracing = setup_tracing(); 101 let _tracing = setup_tracing();
101 let (db, file_id) = TestDB::with_single_file(ra_fixture); 102 let (db, files) = TestDB::with_many_files(ra_fixture);
102 let module = db.module_for_file(file_id); 103
103 let def_map = module.def_map(&db); 104 let mut had_annotations = false;
105 let mut mismatches = HashMap::new();
106 let mut types = HashMap::new();
107 for (file_id, annotations) in db.extract_annotations() {
108 for (range, expected) in annotations {
109 let file_range = FileRange { file_id, range };
110 if only_types {
111 types.insert(file_range, expected);
112 } else if expected.starts_with("type: ") {
113 types.insert(file_range, expected.trim_start_matches("type: ").to_string());
114 } else if expected.starts_with("expected") {
115 mismatches.insert(file_range, expected);
116 } else {
117 panic!("unexpected annotation: {}", expected);
118 }
119 had_annotations = true;
120 }
121 }
122 assert!(had_annotations || allow_none, "no `//^` annotations found");
104 123
105 let mut defs: Vec<DefWithBodyId> = Vec::new(); 124 let mut defs: Vec<DefWithBodyId> = Vec::new();
106 visit_module(&db, &def_map, module.local_id, &mut |it| defs.push(it)); 125 for file_id in files {
126 let module = db.module_for_file_opt(file_id);
127 let module = match module {
128 Some(m) => m,
129 None => continue,
130 };
131 let def_map = module.def_map(&db);
132 visit_module(&db, &def_map, module.local_id, &mut |it| defs.push(it));
133 }
107 defs.sort_by_key(|def| match def { 134 defs.sort_by_key(|def| match def {
108 DefWithBodyId::FunctionId(it) => { 135 DefWithBodyId::FunctionId(it) => {
109 let loc = it.lookup(&db); 136 let loc = it.lookup(&db);
@@ -118,25 +145,46 @@ fn check_mismatches_impl(ra_fixture: &str, allow_none: bool) {
118 loc.source(&db).value.syntax().text_range().start() 145 loc.source(&db).value.syntax().text_range().start()
119 } 146 }
120 }); 147 });
121 let mut mismatches = HashMap::new(); 148 let mut unexpected_type_mismatches = String::new();
122 let mut push_mismatch = |src_ptr: InFile<SyntaxNode>, mismatch: TypeMismatch| {
123 let range = src_ptr.value.text_range();
124 if src_ptr.file_id.call_node(&db).is_some() {
125 panic!("type mismatch in macro expansion");
126 }
127 let file_range = FileRange { file_id: src_ptr.file_id.original_file(&db), range };
128 let actual = format!(
129 "expected {}, got {}",
130 mismatch.expected.display_test(&db),
131 mismatch.actual.display_test(&db)
132 );
133 mismatches.insert(file_range, actual);
134 };
135 for def in defs { 149 for def in defs {
136 let (_body, body_source_map) = db.body_with_source_map(def); 150 let (_body, body_source_map) = db.body_with_source_map(def);
137 let inference_result = db.infer(def); 151 let inference_result = db.infer(def);
152
153 for (pat, ty) in inference_result.type_of_pat.iter() {
154 let node = match body_source_map.pat_syntax(pat) {
155 Ok(sp) => {
156 let root = db.parse_or_expand(sp.file_id).unwrap();
157 sp.map(|ptr| {
158 ptr.either(
159 |it| it.to_node(&root).syntax().clone(),
160 |it| it.to_node(&root).syntax().clone(),
161 )
162 })
163 }
164 Err(SyntheticSyntax) => continue,
165 };
166 let range = node.as_ref().original_file_range(&db);
167 if let Some(annotation) = types.remove(&range) {
168 assert_eq!(ty.display_test(&db).to_string(), annotation);
169 }
170 }
171
172 for (expr, ty) in inference_result.type_of_expr.iter() {
173 let node = match body_source_map.expr_syntax(expr) {
174 Ok(sp) => {
175 let root = db.parse_or_expand(sp.file_id).unwrap();
176 sp.map(|ptr| ptr.to_node(&root).syntax().clone())
177 }
178 Err(SyntheticSyntax) => continue,
179 };
180 let range = node.as_ref().original_file_range(&db);
181 if let Some(annotation) = types.remove(&range) {
182 assert_eq!(ty.display_test(&db).to_string(), annotation);
183 }
184 }
185
138 for (pat, mismatch) in inference_result.pat_type_mismatches() { 186 for (pat, mismatch) in inference_result.pat_type_mismatches() {
139 let syntax_ptr = match body_source_map.pat_syntax(pat) { 187 let node = match body_source_map.pat_syntax(pat) {
140 Ok(sp) => { 188 Ok(sp) => {
141 let root = db.parse_or_expand(sp.file_id).unwrap(); 189 let root = db.parse_or_expand(sp.file_id).unwrap();
142 sp.map(|ptr| { 190 sp.map(|ptr| {
@@ -148,7 +196,17 @@ fn check_mismatches_impl(ra_fixture: &str, allow_none: bool) {
148 } 196 }
149 Err(SyntheticSyntax) => continue, 197 Err(SyntheticSyntax) => continue,
150 }; 198 };
151 push_mismatch(syntax_ptr, mismatch.clone()); 199 let range = node.as_ref().original_file_range(&db);
200 let actual = format!(
201 "expected {}, got {}",
202 mismatch.expected.display_test(&db),
203 mismatch.actual.display_test(&db)
204 );
205 if let Some(annotation) = mismatches.remove(&range) {
206 assert_eq!(actual, annotation);
207 } else {
208 format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual);
209 }
152 } 210 }
153 for (expr, mismatch) in inference_result.expr_type_mismatches() { 211 for (expr, mismatch) in inference_result.expr_type_mismatches() {
154 let node = match body_source_map.expr_syntax(expr) { 212 let node = match body_source_map.expr_syntax(expr) {
@@ -158,28 +216,37 @@ fn check_mismatches_impl(ra_fixture: &str, allow_none: bool) {
158 } 216 }
159 Err(SyntheticSyntax) => continue, 217 Err(SyntheticSyntax) => continue,
160 }; 218 };
161 push_mismatch(node, mismatch.clone()); 219 let range = node.as_ref().original_file_range(&db);
162 } 220 let actual = format!(
163 } 221 "expected {}, got {}",
164 let mut checked_one = false; 222 mismatch.expected.display_test(&db),
165 for (file_id, annotations) in db.extract_annotations() { 223 mismatch.actual.display_test(&db)
166 for (range, expected) in annotations { 224 );
167 let file_range = FileRange { file_id, range }; 225 if let Some(annotation) = mismatches.remove(&range) {
168 if let Some(mismatch) = mismatches.remove(&file_range) { 226 assert_eq!(actual, annotation);
169 assert_eq!(mismatch, expected);
170 } else { 227 } else {
171 assert!(false, "Expected mismatch not encountered: {}\n", expected); 228 format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual);
172 } 229 }
173 checked_one = true;
174 } 230 }
175 } 231 }
232
176 let mut buf = String::new(); 233 let mut buf = String::new();
177 for (range, mismatch) in mismatches { 234 if !unexpected_type_mismatches.is_empty() {
178 format_to!(buf, "{:?}: {}\n", range.range, mismatch,); 235 format_to!(buf, "Unexpected type mismatches:\n{}", unexpected_type_mismatches);
179 } 236 }
180 assert!(buf.is_empty(), "Unexpected type mismatches:\n{}", buf); 237 if !mismatches.is_empty() {
181 238 format_to!(buf, "Unchecked mismatch annotations:\n");
182 assert!(checked_one || allow_none, "no `//^` annotations found"); 239 for m in mismatches {
240 format_to!(buf, "{:?}: {}\n", m.0.range, m.1);
241 }
242 }
243 if !types.is_empty() {
244 format_to!(buf, "Unchecked type annotations:\n");
245 for t in types {
246 format_to!(buf, "{:?}: type {}\n", t.0.range, t.1);
247 }
248 }
249 assert!(buf.is_empty(), "{}", buf);
183} 250}
184 251
185fn type_at_range(db: &TestDB, pos: FileRange) -> Ty { 252fn type_at_range(db: &TestDB, pos: FileRange) -> Ty {
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs
index 713b74165..24ce5bcca 100644
--- a/crates/hir_ty/src/tests/coercion.rs
+++ b/crates/hir_ty/src/tests/coercion.rs
@@ -842,9 +842,9 @@ fn infer_two_closures_lub() {
842fn foo(c: i32) { 842fn foo(c: i32) {
843 let add = |a: i32, b: i32| a + b; 843 let add = |a: i32, b: i32| a + b;
844 let sub = |a, b| a - b; 844 let sub = |a, b| a - b;
845 //^ |i32, i32| -> i32 845 //^^^^^^^^^^^^ |i32, i32| -> i32
846 if c > 42 { add } else { sub }; 846 if c > 42 { add } else { sub };
847 //^ fn(i32, i32) -> i32 847 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fn(i32, i32) -> i32
848} 848}
849 "#, 849 "#,
850 ) 850 )
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index d14103aab..6c3d46caf 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -435,11 +435,11 @@ fn processes_impls_generated_by_macros() {
435macro_rules! m { 435macro_rules! m {
436 ($ident:ident) => (impl Trait for $ident {}) 436 ($ident:ident) => (impl Trait for $ident {})
437} 437}
438trait Trait { fn foo(self) -> u128 {} } 438trait Trait { fn foo(self) -> u128 { 0 } }
439struct S; 439struct S;
440m!(S); 440m!(S);
441fn test() { S.foo(); } 441fn test() { S.foo(); }
442 //^ u128 442 //^^^^^^^ u128
443"#, 443"#,
444 ); 444 );
445} 445}
@@ -457,7 +457,7 @@ impl S {
457} 457}
458 458
459fn test() { S.foo(); } 459fn test() { S.foo(); }
460 //^ u128 460 //^^^^^^^ u128
461"#, 461"#,
462 ); 462 );
463} 463}
@@ -479,7 +479,7 @@ impl S {
479} 479}
480 480
481fn test() { S.foo(); } 481fn test() { S.foo(); }
482 //^ u128 482 //^^^^^^^ u128
483"#, 483"#,
484 ); 484 );
485} 485}
@@ -743,7 +743,7 @@ include!("foo.rs");
743 743
744fn main() { 744fn main() {
745 bar(); 745 bar();
746} //^ u32 746} //^^^^^ u32
747 747
748//- /foo.rs 748//- /foo.rs
749fn bar() -> u32 {0} 749fn bar() -> u32 {0}
@@ -781,7 +781,7 @@ include!("f/foo.rs");
781 781
782fn main() { 782fn main() {
783 bar::bar(); 783 bar::bar();
784} //^ u32 784} //^^^^^^^^^^ u32
785 785
786//- /f/foo.rs 786//- /f/foo.rs
787pub mod bar; 787pub mod bar;
@@ -879,7 +879,7 @@ include!(concat!("f", "oo.rs"));
879 879
880fn main() { 880fn main() {
881 bar(); 881 bar();
882} //^ u32 882} //^^^^^ u32
883 883
884//- /foo.rs 884//- /foo.rs
885fn bar() -> u32 {0} 885fn bar() -> u32 {0}
@@ -905,7 +905,7 @@ include!(concat!(env!("OUT_DIR"), "/foo.rs"));
905 905
906fn main() { 906fn main() {
907 bar(); 907 bar();
908} //^ {unknown} 908} //^^^^^ {unknown}
909 909
910//- /foo.rs 910//- /foo.rs
911fn bar() -> u32 {0} 911fn bar() -> u32 {0}
@@ -923,7 +923,7 @@ macro_rules! include {() => {}}
923include!("main.rs"); 923include!("main.rs");
924 924
925fn main() { 925fn main() {
926 0 926 0;
927} //^ i32 927} //^ i32
928"#, 928"#,
929 ); 929 );
@@ -979,7 +979,7 @@ fn infer_derive_clone_simple() {
979struct S; 979struct S;
980fn test() { 980fn test() {
981 S.clone(); 981 S.clone();
982} //^ S 982} //^^^^^^^^^ S
983 983
984//- /lib.rs crate:core 984//- /lib.rs crate:core
985pub mod prelude { 985pub mod prelude {
@@ -1028,7 +1028,7 @@ pub struct S;
1028use core::S; 1028use core::S;
1029fn test() { 1029fn test() {
1030 S.clone(); 1030 S.clone();
1031} //^ S 1031} //^^^^^^^^^ S
1032"#, 1032"#,
1033 ); 1033 );
1034} 1034}
@@ -1044,7 +1044,8 @@ struct S;
1044struct Wrapper<T>(T); 1044struct Wrapper<T>(T);
1045struct NonClone; 1045struct NonClone;
1046fn test() { 1046fn test() {
1047 (Wrapper(S).clone(), Wrapper(NonClone).clone()); 1047 let x = (Wrapper(S).clone(), Wrapper(NonClone).clone());
1048 x;
1048 //^ (Wrapper<S>, {unknown}) 1049 //^ (Wrapper<S>, {unknown})
1049} 1050}
1050 1051
@@ -1079,7 +1080,7 @@ struct S{}
1079 1080
1080fn test() { 1081fn test() {
1081 S{}; 1082 S{};
1082} //^ S 1083} //^^^ S
1083"#, 1084"#,
1084 ); 1085 );
1085} 1086}
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index d9b5ee9cf..3f7a37295 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -257,7 +257,7 @@ fn test() {
257mod foo { 257mod foo {
258 struct S; 258 struct S;
259 impl S { 259 impl S {
260 fn thing() -> i128 {} 260 fn thing() -> i128 { 0 }
261 } 261 }
262} 262}
263"#, 263"#,
@@ -267,164 +267,128 @@ mod foo {
267#[test] 267#[test]
268fn infer_trait_method_simple() { 268fn infer_trait_method_simple() {
269 // the trait implementation is intentionally incomplete -- it shouldn't matter 269 // the trait implementation is intentionally incomplete -- it shouldn't matter
270 check_infer( 270 check_types(
271 r#" 271 r#"
272 trait Trait1 { 272trait Trait1 {
273 fn method(&self) -> u32; 273 fn method(&self) -> u32;
274 } 274}
275 struct S1; 275struct S1;
276 impl Trait1 for S1 {} 276impl Trait1 for S1 {}
277 trait Trait2 { 277trait Trait2 {
278 fn method(&self) -> i128; 278 fn method(&self) -> i128;
279 } 279}
280 struct S2; 280struct S2;
281 impl Trait2 for S2 {} 281impl Trait2 for S2 {}
282 fn test() { 282fn test() {
283 S1.method(); // -> u32 283 S1.method();
284 S2.method(); // -> i128 284 //^^^^^^^^^^^ u32
285 } 285 S2.method(); // -> i128
286 //^^^^^^^^^^^ i128
287}
286 "#, 288 "#,
287 expect![[r#"
288 30..34 'self': &Self
289 109..113 'self': &Self
290 169..227 '{ ...i128 }': ()
291 175..177 'S1': S1
292 175..186 'S1.method()': u32
293 202..204 'S2': S2
294 202..213 'S2.method()': i128
295 "#]],
296 ); 289 );
297} 290}
298 291
299#[test] 292#[test]
300fn infer_trait_method_scoped() { 293fn infer_trait_method_scoped() {
301 // the trait implementation is intentionally incomplete -- it shouldn't matter 294 // the trait implementation is intentionally incomplete -- it shouldn't matter
302 check_infer( 295 check_types(
303 r#" 296 r#"
304 struct S; 297struct S;
305 mod foo { 298mod foo {
306 pub trait Trait1 { 299 pub trait Trait1 {
307 fn method(&self) -> u32; 300 fn method(&self) -> u32;
308 } 301 }
309 impl Trait1 for super::S {} 302 impl Trait1 for super::S {}
310 } 303}
311 mod bar { 304mod bar {
312 pub trait Trait2 { 305 pub trait Trait2 {
313 fn method(&self) -> i128; 306 fn method(&self) -> i128;
314 } 307 }
315 impl Trait2 for super::S {} 308 impl Trait2 for super::S {}
316 } 309}
317 310
318 mod foo_test { 311mod foo_test {
319 use super::S; 312 use super::S;
320 use super::foo::Trait1; 313 use super::foo::Trait1;
321 fn test() { 314 fn test() {
322 S.method(); // -> u32 315 S.method();
323 } 316 //^^^^^^^^^^ u32
324 } 317 }
318}
325 319
326 mod bar_test { 320mod bar_test {
327 use super::S; 321 use super::S;
328 use super::bar::Trait2; 322 use super::bar::Trait2;
329 fn test() { 323 fn test() {
330 S.method(); // -> i128 324 S.method();
331 } 325 //^^^^^^^^^^ i128
332 } 326 }
327}
333 "#, 328 "#,
334 expect![[r#"
335 62..66 'self': &Self
336 168..172 'self': &Self
337 299..336 '{ ... }': ()
338 309..310 'S': S
339 309..319 'S.method()': u32
340 415..453 '{ ... }': ()
341 425..426 'S': S
342 425..435 'S.method()': i128
343 "#]],
344 ); 329 );
345} 330}
346 331
347#[test] 332#[test]
348fn infer_trait_method_generic_1() { 333fn infer_trait_method_generic_1() {
349 // the trait implementation is intentionally incomplete -- it shouldn't matter 334 // the trait implementation is intentionally incomplete -- it shouldn't matter
350 check_infer( 335 check_types(
351 r#" 336 r#"
352 trait Trait<T> { 337trait Trait<T> {
353 fn method(&self) -> T; 338 fn method(&self) -> T;
354 } 339}
355 struct S; 340struct S;
356 impl Trait<u32> for S {} 341impl Trait<u32> for S {}
357 fn test() { 342fn test() {
358 S.method(); 343 S.method();
359 } 344 //^^^^^^^^^^ u32
345}
360 "#, 346 "#,
361 expect![[r#"
362 32..36 'self': &Self
363 91..110 '{ ...d(); }': ()
364 97..98 'S': S
365 97..107 'S.method()': u32
366 "#]],
367 ); 347 );
368} 348}
369 349
370#[test] 350#[test]
371fn infer_trait_method_generic_more_params() { 351fn infer_trait_method_generic_more_params() {
372 // the trait implementation is intentionally incomplete -- it shouldn't matter 352 // the trait implementation is intentionally incomplete -- it shouldn't matter
373 check_infer( 353 check_types(
374 r#" 354 r#"
375 trait Trait<T1, T2, T3> { 355trait Trait<T1, T2, T3> {
376 fn method1(&self) -> (T1, T2, T3); 356 fn method1(&self) -> (T1, T2, T3);
377 fn method2(&self) -> (T3, T2, T1); 357 fn method2(&self) -> (T3, T2, T1);
378 } 358}
379 struct S1; 359struct S1;
380 impl Trait<u8, u16, u32> for S1 {} 360impl Trait<u8, u16, u32> for S1 {}
381 struct S2; 361struct S2;
382 impl<T> Trait<i8, i16, T> for S2 {} 362impl<T> Trait<i8, i16, T> for S2 {}
383 fn test() { 363fn test() {
384 S1.method1(); // u8, u16, u32 364 S1.method1();
385 S1.method2(); // u32, u16, u8 365 //^^^^^^^^^^^^ (u8, u16, u32)
386 S2.method1(); // i8, i16, {unknown} 366 S1.method2();
387 S2.method2(); // {unknown}, i16, i8 367 //^^^^^^^^^^^^ (u32, u16, u8)
388 } 368 S2.method1();
369 //^^^^^^^^^^^^ (i8, i16, {unknown})
370 S2.method2();
371 //^^^^^^^^^^^^ ({unknown}, i16, i8)
372}
389 "#, 373 "#,
390 expect![[r#"
391 42..46 'self': &Self
392 81..85 'self': &Self
393 209..360 '{ ..., i8 }': ()
394 215..217 'S1': S1
395 215..227 'S1.method1()': (u8, u16, u32)
396 249..251 'S1': S1
397 249..261 'S1.method2()': (u32, u16, u8)
398 283..285 'S2': S2
399 283..295 'S2.method1()': (i8, i16, {unknown})
400 323..325 'S2': S2
401 323..335 'S2.method2()': ({unknown}, i16, i8)
402 "#]],
403 ); 374 );
404} 375}
405 376
406#[test] 377#[test]
407fn infer_trait_method_generic_2() { 378fn infer_trait_method_generic_2() {
408 // the trait implementation is intentionally incomplete -- it shouldn't matter 379 // the trait implementation is intentionally incomplete -- it shouldn't matter
409 check_infer( 380 check_types(
410 r#" 381 r#"
411 trait Trait<T> { 382trait Trait<T> {
412 fn method(&self) -> T; 383 fn method(&self) -> T;
413 } 384}
414 struct S<T>(T); 385struct S<T>(T);
415 impl<U> Trait<U> for S<U> {} 386impl<U> Trait<U> for S<U> {}
416 fn test() { 387fn test() {
417 S(1u32).method(); 388 S(1u32).method();
418 } 389 //^^^^^^^^^^^^^^^^ u32
390}
419 "#, 391 "#,
420 expect![[r#"
421 32..36 'self': &Self
422 101..126 '{ ...d(); }': ()
423 107..108 'S': S<u32>(u32) -> S<u32>
424 107..114 'S(1u32)': S<u32>
425 107..123 'S(1u32...thod()': u32
426 109..113 '1u32': u32
427 "#]],
428 ); 392 );
429} 393}
430 394
@@ -685,10 +649,10 @@ fn method_resolution_unify_impl_self_type() {
685 check_types( 649 check_types(
686 r#" 650 r#"
687struct S<T>; 651struct S<T>;
688impl S<u32> { fn foo(&self) -> u8 {} } 652impl S<u32> { fn foo(&self) -> u8 { 0 } }
689impl S<i32> { fn foo(&self) -> i8 {} } 653impl S<i32> { fn foo(&self) -> i8 { 0 } }
690fn test() { (S::<u32>.foo(), S::<i32>.foo()); } 654fn test() { (S::<u32>.foo(), S::<i32>.foo()); }
691 //^ (u8, i8) 655 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (u8, i8)
692"#, 656"#,
693 ); 657 );
694} 658}
@@ -702,7 +666,7 @@ struct S;
702impl S { fn foo(&self) -> i8 { 0 } } 666impl S { fn foo(&self) -> i8 { 0 } }
703impl Trait for S { fn foo(self) -> u128 { 0 } } 667impl Trait for S { fn foo(self) -> u128 { 0 } }
704fn test() { S.foo(); } 668fn test() { S.foo(); }
705 //^ u128 669 //^^^^^^^ u128
706"#, 670"#,
707 ); 671 );
708} 672}
@@ -716,7 +680,7 @@ struct S;
716impl Clone for S {} 680impl Clone for S {}
717impl Clone for &S {} 681impl Clone for &S {}
718fn test() { (S.clone(), (&S).clone(), (&&S).clone()); } 682fn test() { (S.clone(), (&S).clone(), (&&S).clone()); }
719 //^ (S, S, &S) 683 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (S, S, &S)
720"#, 684"#,
721 ); 685 );
722} 686}
@@ -730,7 +694,7 @@ struct S;
730impl S { fn foo(self) -> i8 { 0 } } 694impl S { fn foo(self) -> i8 { 0 } }
731impl Trait for &S { fn foo(self) -> u128 { 0 } } 695impl Trait for &S { fn foo(self) -> u128 { 0 } }
732fn test() { (&S).foo(); } 696fn test() { (&S).foo(); }
733 //^ u128 697 //^^^^^^^^^^ u128
734"#, 698"#,
735 ); 699 );
736} 700}
@@ -744,7 +708,7 @@ struct S;
744impl S { fn foo(self) -> i8 { 0 } } 708impl S { fn foo(self) -> i8 { 0 } }
745impl Trait for S { fn foo(self) -> u128 { 0 } } 709impl Trait for S { fn foo(self) -> u128 { 0 } }
746fn test() { S.foo(); } 710fn test() { S.foo(); }
747 //^ i8 711 //^^^^^^^ i8
748"#, 712"#,
749 ); 713 );
750} 714}
@@ -758,7 +722,7 @@ struct S;
758impl S { fn foo(&self) -> i8 { 0 } } 722impl S { fn foo(&self) -> i8 { 0 } }
759impl Trait for &S { fn foo(self) -> u128 { 0 } } 723impl Trait for &S { fn foo(self) -> u128 { 0 } }
760fn test() { S.foo(); } 724fn test() { S.foo(); }
761 //^ i8 725 //^^^^^^^ i8
762"#, 726"#,
763 ); 727 );
764} 728}
@@ -771,7 +735,7 @@ trait Trait { fn foo(self) -> u128; }
771struct S; 735struct S;
772impl Trait for S { fn foo(self) -> u128 { 0 } } 736impl Trait for S { fn foo(self) -> u128 { 0 } }
773fn test() { (&S).foo(); } 737fn test() { (&S).foo(); }
774 //^ u128 738 //^^^^^^^^^^ u128
775"#, 739"#,
776 ); 740 );
777} 741}
@@ -784,7 +748,7 @@ fn method_resolution_unsize_array() {
784fn test() { 748fn test() {
785 let a = [1, 2, 3]; 749 let a = [1, 2, 3];
786 a.len(); 750 a.len();
787} //^ usize 751} //^^^^^^^ usize
788"#, 752"#,
789 ); 753 );
790} 754}
@@ -799,7 +763,7 @@ impl Clone for S {}
799 763
800fn test() { 764fn test() {
801 S.clone(); 765 S.clone();
802 //^ S 766 //^^^^^^^^^ S
803} 767}
804 768
805//- /lib.rs crate:core 769//- /lib.rs crate:core
@@ -823,7 +787,7 @@ trait Trait { fn foo(self) -> u128; }
823struct S; 787struct S;
824impl<T> Trait for T where T: UnknownTrait {} 788impl<T> Trait for T where T: UnknownTrait {}
825fn test() { (&S).foo(); } 789fn test() { (&S).foo(); }
826 //^ u128 790 //^^^^^^^^^^ u128
827"#, 791"#,
828 ); 792 );
829} 793}
@@ -841,7 +805,7 @@ trait Trait { fn foo(self) -> u128; }
841struct S; 805struct S;
842impl<T> Trait for T where T: Clone {} 806impl<T> Trait for T where T: Clone {}
843fn test() { (&S).foo(); } 807fn test() { (&S).foo(); }
844 //^ {unknown} 808 //^^^^^^^^^^ {unknown}
845"#, 809"#,
846 ); 810 );
847} 811}
@@ -856,7 +820,7 @@ trait Trait { fn foo(self) -> u128; }
856struct S; 820struct S;
857impl<T: Clone> Trait for T {} 821impl<T: Clone> Trait for T {}
858fn test() { (&S).foo(); } 822fn test() { (&S).foo(); }
859 //^ {unknown} 823 //^^^^^^^^^^ {unknown}
860"#, 824"#,
861 ); 825 );
862} 826}
@@ -871,7 +835,7 @@ struct S;
871impl Clone for S {} 835impl Clone for S {}
872impl<T> Trait for T where T: Clone {} 836impl<T> Trait for T where T: Clone {}
873fn test() { S.foo(); } 837fn test() { S.foo(); }
874 //^ u128 838 //^^^^^^^ u128
875"#, 839"#,
876 ); 840 );
877} 841}
@@ -887,7 +851,7 @@ struct S2;
887impl From<S2> for S1 {} 851impl From<S2> for S1 {}
888impl<T, U> Into<U> for T where U: From<T> {} 852impl<T, U> Into<U> for T where U: From<T> {}
889fn test() { S2.into(); } 853fn test() { S2.into(); }
890 //^ {unknown} 854 //^^^^^^^^^ {unknown}
891"#, 855"#,
892 ); 856 );
893} 857}
@@ -903,7 +867,7 @@ struct S2;
903impl From<S2> for S1 {} 867impl From<S2> for S1 {}
904impl<T, U: From<T>> Into<U> for T {} 868impl<T, U: From<T>> Into<U> for T {}
905fn test() { S2.into(); } 869fn test() { S2.into(); }
906 //^ {unknown} 870 //^^^^^^^^^ {unknown}
907"#, 871"#,
908 ); 872 );
909} 873}
@@ -933,7 +897,7 @@ fn main() {
933 let a = Wrapper::<Foo<f32>>::new(1.0); 897 let a = Wrapper::<Foo<f32>>::new(1.0);
934 let b = Wrapper::<Bar<f32>>::new(1.0); 898 let b = Wrapper::<Bar<f32>>::new(1.0);
935 (a, b); 899 (a, b);
936 //^ (Wrapper<Foo<f32>>, Wrapper<Bar<f32>>) 900 //^^^^^^ (Wrapper<Foo<f32>>, Wrapper<Bar<f32>>)
937} 901}
938"#, 902"#,
939 ); 903 );
@@ -947,7 +911,7 @@ fn method_resolution_encountering_fn_type() {
947fn foo() {} 911fn foo() {}
948trait FnOnce { fn call(self); } 912trait FnOnce { fn call(self); }
949fn test() { foo.call(); } 913fn test() { foo.call(); }
950 //^ {unknown} 914 //^^^^^^^^^^ {unknown}
951"#, 915"#,
952 ); 916 );
953} 917}
@@ -1013,7 +977,7 @@ where
1013 Wrapper<T>: a::Foo, 977 Wrapper<T>: a::Foo,
1014{ 978{
1015 t.foo(); 979 t.foo();
1016} //^ {unknown} 980} //^^^^^^^ {unknown}
1017"#, 981"#,
1018 ); 982 );
1019} 983}
@@ -1030,7 +994,7 @@ impl A<i32> {
1030 994
1031fn main() { 995fn main() {
1032 A::from(3); 996 A::from(3);
1033} //^ A<i32> 997} //^^^^^^^^^^ A<i32>
1034"#, 998"#,
1035 ); 999 );
1036} 1000}
@@ -1058,7 +1022,7 @@ trait FnX {}
1058impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {} 1022impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {}
1059 1023
1060fn test() { (S {}).method(); } 1024fn test() { (S {}).method(); }
1061 //^ () 1025 //^^^^^^^^^^^^^^^ ()
1062"#, 1026"#,
1063 ); 1027 );
1064} 1028}
@@ -1143,8 +1107,8 @@ impl<T> Slice<T> {
1143 1107
1144fn main() { 1108fn main() {
1145 let foo: Slice<u32>; 1109 let foo: Slice<u32>;
1146 (foo.into_vec()); // we don't actually support arbitrary self types, but we shouldn't crash at least 1110 foo.into_vec(); // we shouldn't crash on this at least
1147} //^ {unknown} 1111} //^^^^^^^^^^^^^^ {unknown}
1148"#, 1112"#,
1149 ); 1113 );
1150} 1114}
@@ -1165,7 +1129,7 @@ impl dyn Foo + '_ {
1165fn main() { 1129fn main() {
1166 let f = &42u32 as &dyn Foo; 1130 let f = &42u32 as &dyn Foo;
1167 f.dyn_foo(); 1131 f.dyn_foo();
1168 // ^u32 1132 // ^^^^^^^^^^^ u32
1169} 1133}
1170"#, 1134"#,
1171 ); 1135 );
@@ -1376,11 +1340,11 @@ pub trait IntoIterator {
1376 1340
1377impl<T> IntoIterator for [T; 1] { 1341impl<T> IntoIterator for [T; 1] {
1378 type Out = T; 1342 type Out = T;
1379 fn into_iter(self) -> Self::Out {} 1343 fn into_iter(self) -> Self::Out { loop {} }
1380} 1344}
1381impl<'a, T> IntoIterator for &'a [T] { 1345impl<'a, T> IntoIterator for &'a [T] {
1382 type Out = &'a T; 1346 type Out = &'a T;
1383 fn into_iter(self) -> Self::Out {} 1347 fn into_iter(self) -> Self::Out { loop {} }
1384} 1348}
1385 "#, 1349 "#,
1386 ); 1350 );
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index 5adbe9c45..47aa30d2e 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -1,6 +1,6 @@
1use expect_test::expect; 1use expect_test::expect;
2 2
3use super::{check_infer, check_infer_with_mismatches, check_mismatches, check_types}; 3use super::{check, check_infer, check_infer_with_mismatches, check_types};
4 4
5#[test] 5#[test]
6fn infer_pattern() { 6fn infer_pattern() {
@@ -518,7 +518,7 @@ fn infer_generics_in_patterns() {
518 518
519#[test] 519#[test]
520fn infer_const_pattern() { 520fn infer_const_pattern() {
521 check_mismatches( 521 check(
522 r#" 522 r#"
523enum Option<T> { None } 523enum Option<T> { None }
524use Option::None; 524use Option::None;
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index 0f418ea49..8c5e8954c 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -1,6 +1,6 @@
1use expect_test::expect; 1use expect_test::expect;
2 2
3use super::{check_infer, check_types}; 3use super::{check_infer, check_no_mismatches, check_types};
4 4
5#[test] 5#[test]
6fn bug_484() { 6fn bug_484() {
@@ -422,20 +422,20 @@ fn issue_2683_chars_impl() {
422pub struct Chars<'a> {} 422pub struct Chars<'a> {}
423impl<'a> Iterator for Chars<'a> { 423impl<'a> Iterator for Chars<'a> {
424 type Item = char; 424 type Item = char;
425 fn next(&mut self) -> Option<char> {} 425 fn next(&mut self) -> Option<char> { loop {} }
426} 426}
427 427
428fn test() { 428fn test() {
429 let chars: Chars<'_>; 429 let chars: Chars<'_>;
430 (chars.next(), chars.nth(1)); 430 (chars.next(), chars.nth(1));
431} //^ (Option<char>, Option<char>) 431} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (Option<char>, Option<char>)
432"#, 432"#,
433 ); 433 );
434} 434}
435 435
436#[test] 436#[test]
437fn issue_3642_bad_macro_stackover() { 437fn issue_3642_bad_macro_stackover() {
438 check_types( 438 check_no_mismatches(
439 r#" 439 r#"
440#[macro_export] 440#[macro_export]
441macro_rules! match_ast { 441macro_rules! match_ast {
@@ -452,7 +452,6 @@ macro_rules! match_ast {
452 452
453fn main() { 453fn main() {
454 let anchor = match_ast! { 454 let anchor = match_ast! {
455 //^ ()
456 match parent { 455 match parent {
457 as => {}, 456 as => {},
458 _ => return None 457 _ => return None
@@ -956,7 +955,7 @@ trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> {
956 955
957fn clone_iter<T>(s: Iter<T>) { 956fn clone_iter<T>(s: Iter<T>) {
958 s.inner.clone_box(); 957 s.inner.clone_box();
959 //^^^^^^^^^^^^^^^^^^^ () 958 //^^^^^^^^^^^^^^^^^^^ ()
960} 959}
961"#, 960"#,
962 ) 961 )
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 108ff3179..b4bcc6d95 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -60,7 +60,7 @@ enum Nat { Succ(Self), Demo(Nat), Zero }
60fn test() { 60fn test() {
61 let foo: Nat = Nat::Zero; 61 let foo: Nat = Nat::Zero;
62 if let Nat::Succ(x) = foo { 62 if let Nat::Succ(x) = foo {
63 x 63 x;
64 } //^ Nat 64 } //^ Nat
65} 65}
66"#, 66"#,
@@ -138,7 +138,7 @@ enum Option<T> { Some(T), None }
138fn test() { 138fn test() {
139 let foo: Option<f32> = None; 139 let foo: Option<f32> = None;
140 while let Option::Some(x) = foo { 140 while let Option::Some(x) = foo {
141 x 141 x;
142 } //^ f32 142 } //^ f32
143} 143}
144"#, 144"#,
@@ -1745,7 +1745,7 @@ impl i32 { fn foo(&self) -> Foo { Foo } }
1745fn main() { 1745fn main() {
1746 let x: i32 = i32; 1746 let x: i32 = i32;
1747 x.foo(); 1747 x.foo();
1748 //^ Foo 1748 //^^^^^^^ Foo
1749}"#, 1749}"#,
1750 ); 1750 );
1751} 1751}
@@ -1763,7 +1763,7 @@ fn main() {
1763 fn inner() {} 1763 fn inner() {}
1764 let x: i32 = i32; 1764 let x: i32 = i32;
1765 x.foo(); 1765 x.foo();
1766 //^ Foo 1766 //^^^^^^^ Foo
1767}"#, 1767}"#,
1768 ); 1768 );
1769} 1769}
@@ -1781,7 +1781,7 @@ fn foo() -> &'static str { "" }
1781 1781
1782fn main() { 1782fn main() {
1783 foo(); 1783 foo();
1784 //^ &str 1784 //^^^^^ &str
1785}"#, 1785}"#,
1786 ); 1786 );
1787} 1787}
@@ -1799,7 +1799,7 @@ fn foo() -> &'static str { "" }
1799 1799
1800fn main() { 1800fn main() {
1801 str::foo(); 1801 str::foo();
1802 //^ u32 1802 //^^^^^^^^^^ u32
1803}"#, 1803}"#,
1804 ); 1804 );
1805} 1805}
@@ -1825,9 +1825,9 @@ mod d {
1825 1825
1826fn main() { 1826fn main() {
1827 d::foo(); 1827 d::foo();
1828 //^ u8 1828 //^^^^^^^^ u8
1829 d::foo{a:0}; 1829 d::foo{a:0};
1830 //^ u8 1830 //^^^^^^^^^^^ foo
1831}"#, 1831}"#,
1832 ); 1832 );
1833} 1833}
@@ -2677,7 +2677,7 @@ fn prelude_2015() {
2677//- /main.rs edition:2015 crate:main deps:core 2677//- /main.rs edition:2015 crate:main deps:core
2678fn f() { 2678fn f() {
2679 Rust; 2679 Rust;
2680 //^ Rust 2680 //^^^^ Rust
2681} 2681}
2682 2682
2683//- /core.rs crate:core 2683//- /core.rs crate:core
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 279a1354a..a0ddad570 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -1,6 +1,7 @@
1use cov_mark::check;
1use expect_test::expect; 2use expect_test::expect;
2 3
3use super::{check_infer, check_infer_with_mismatches, check_types}; 4use super::{check, check_infer, check_infer_with_mismatches, check_types};
4 5
5#[test] 6#[test]
6fn infer_await() { 7fn infer_await() {
@@ -285,7 +286,7 @@ mod ops {
285 286
286#[test] 287#[test]
287fn infer_from_bound_1() { 288fn infer_from_bound_1() {
288 check_infer( 289 check_types(
289 r#" 290 r#"
290trait Trait<T> {} 291trait Trait<T> {}
291struct S<T>(T); 292struct S<T>(T);
@@ -293,99 +294,62 @@ impl<U> Trait<U> for S<U> {}
293fn foo<T: Trait<u32>>(t: T) {} 294fn foo<T: Trait<u32>>(t: T) {}
294fn test() { 295fn test() {
295 let s = S(unknown); 296 let s = S(unknown);
297 // ^^^^^^^ u32
296 foo(s); 298 foo(s);
297}"#, 299}"#,
298 expect![[r#"
299 85..86 't': T
300 91..93 '{}': ()
301 104..143 '{ ...(s); }': ()
302 114..115 's': S<u32>
303 118..119 'S': S<u32>(u32) -> S<u32>
304 118..128 'S(unknown)': S<u32>
305 120..127 'unknown': u32
306 134..137 'foo': fn foo<S<u32>>(S<u32>)
307 134..140 'foo(s)': ()
308 138..139 's': S<u32>
309 "#]],
310 ); 300 );
311} 301}
312 302
313#[test] 303#[test]
314fn infer_from_bound_2() { 304fn infer_from_bound_2() {
315 check_infer( 305 check_types(
316 r#" 306 r#"
317trait Trait<T> {} 307trait Trait<T> {}
318struct S<T>(T); 308struct S<T>(T);
319impl<U> Trait<U> for S<U> {} 309impl<U> Trait<U> for S<U> {}
320fn foo<U, T: Trait<U>>(t: T) -> U {} 310fn foo<U, T: Trait<U>>(t: T) -> U { loop {} }
321fn test() { 311fn test() {
322 let s = S(unknown); 312 let s = S(unknown);
313 // ^^^^^^^ u32
323 let x: u32 = foo(s); 314 let x: u32 = foo(s);
324}"#, 315}"#,
325 expect![[r#"
326 86..87 't': T
327 97..99 '{}': ()
328 110..162 '{ ...(s); }': ()
329 120..121 's': S<u32>
330 124..125 'S': S<u32>(u32) -> S<u32>
331 124..134 'S(unknown)': S<u32>
332 126..133 'unknown': u32
333 144..145 'x': u32
334 153..156 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32
335 153..159 'foo(s)': u32
336 157..158 's': S<u32>
337 "#]],
338 ); 316 );
339} 317}
340 318
341#[test] 319#[test]
342fn trait_default_method_self_bound_implements_trait() { 320fn trait_default_method_self_bound_implements_trait() {
343 cov_mark::check!(trait_self_implements_self); 321 cov_mark::check!(trait_self_implements_self);
344 check_infer( 322 check(
345 r#" 323 r#"
346trait Trait { 324trait Trait {
347 fn foo(&self) -> i64; 325 fn foo(&self) -> i64;
348 fn bar(&self) -> { 326 fn bar(&self) -> () {
349 let x = self.foo(); 327 self.foo();
328 // ^^^^^^^^^^ type: i64
350 } 329 }
351}"#, 330}"#,
352 expect![[r#"
353 26..30 'self': &Self
354 52..56 'self': &Self
355 61..96 '{ ... }': ()
356 75..76 'x': i64
357 79..83 'self': &Self
358 79..89 'self.foo()': i64
359 "#]],
360 ); 331 );
361} 332}
362 333
363#[test] 334#[test]
364fn trait_default_method_self_bound_implements_super_trait() { 335fn trait_default_method_self_bound_implements_super_trait() {
365 check_infer( 336 check(
366 r#" 337 r#"
367trait SuperTrait { 338trait SuperTrait {
368 fn foo(&self) -> i64; 339 fn foo(&self) -> i64;
369} 340}
370trait Trait: SuperTrait { 341trait Trait: SuperTrait {
371 fn bar(&self) -> { 342 fn bar(&self) -> () {
372 let x = self.foo(); 343 self.foo();
344 // ^^^^^^^^^^ type: i64
373 } 345 }
374}"#, 346}"#,
375 expect![[r#"
376 31..35 'self': &Self
377 85..89 'self': &Self
378 94..129 '{ ... }': ()
379 108..109 'x': i64
380 112..116 'self': &Self
381 112..122 'self.foo()': i64
382 "#]],
383 ); 347 );
384} 348}
385 349
386#[test] 350#[test]
387fn infer_project_associated_type() { 351fn infer_project_associated_type() {
388 check_infer( 352 check_types(
389 r#" 353 r#"
390trait Iterable { 354trait Iterable {
391 type Item; 355 type Item;
@@ -394,89 +358,62 @@ struct S;
394impl Iterable for S { type Item = u32; } 358impl Iterable for S { type Item = u32; }
395fn test<T: Iterable>() { 359fn test<T: Iterable>() {
396 let x: <S as Iterable>::Item = 1; 360 let x: <S as Iterable>::Item = 1;
397 let y: <T as Iterable>::Item = no_matter; 361 // ^ u32
398 let z: T::Item = no_matter; 362 let y: <T as Iterable>::Item = u;
399 let a: <T>::Item = no_matter; 363 // ^ Iterable::Item<T>
364 let z: T::Item = u;
365 // ^ Iterable::Item<T>
366 let a: <T>::Item = u;
367 // ^ Iterable::Item<T>
400}"#, 368}"#,
401 expect![[r#"
402 108..261 '{ ...ter; }': ()
403 118..119 'x': u32
404 145..146 '1': u32
405 156..157 'y': Iterable::Item<T>
406 183..192 'no_matter': Iterable::Item<T>
407 202..203 'z': Iterable::Item<T>
408 215..224 'no_matter': Iterable::Item<T>
409 234..235 'a': Iterable::Item<T>
410 249..258 'no_matter': Iterable::Item<T>
411 "#]],
412 ); 369 );
413} 370}
414 371
415#[test] 372#[test]
416fn infer_return_associated_type() { 373fn infer_return_associated_type() {
417 check_infer( 374 check_types(
418 r#" 375 r#"
419trait Iterable { 376trait Iterable {
420 type Item; 377 type Item;
421} 378}
422struct S; 379struct S;
423impl Iterable for S { type Item = u32; } 380impl Iterable for S { type Item = u32; }
424fn foo1<T: Iterable>(t: T) -> T::Item {} 381fn foo1<T: Iterable>(t: T) -> T::Item { loop {} }
425fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} 382fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item { loop {} }
426fn foo3<T: Iterable>(t: T) -> <T>::Item {} 383fn foo3<T: Iterable>(t: T) -> <T>::Item { loop {} }
427fn test() { 384fn test() {
428 let x = foo1(S); 385 foo1(S);
429 let y = foo2(S); 386 // ^^^^^^^ u32
430 let z = foo3(S); 387 foo2(S);
388 // ^^^^^^^ u32
389 foo3(S);
390 // ^^^^^^^ u32
431}"#, 391}"#,
432 expect![[r#"
433 106..107 't': T
434 123..125 '{}': ()
435 147..148 't': T
436 178..180 '{}': ()
437 202..203 't': T
438 221..223 '{}': ()
439 234..300 '{ ...(S); }': ()
440 244..245 'x': u32
441 248..252 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item
442 248..255 'foo1(S)': u32
443 253..254 'S': S
444 265..266 'y': u32
445 269..273 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item
446 269..276 'foo2(S)': u32
447 274..275 'S': S
448 286..287 'z': u32
449 290..294 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item
450 290..297 'foo3(S)': u32
451 295..296 'S': S
452 "#]],
453 ); 392 );
454} 393}
455 394
456#[test] 395#[test]
457fn infer_associated_type_bound() { 396fn infer_associated_type_bound() {
458 check_infer( 397 check_types(
459 r#" 398 r#"
460trait Iterable { 399trait Iterable {
461 type Item; 400 type Item;
462} 401}
463fn test<T: Iterable<Item=u32>>() { 402fn test<T: Iterable<Item=u32>>() {
464 let y: T::Item = unknown; 403 let y: T::Item = unknown;
404 // ^^^^^^^ u32
465}"#, 405}"#,
466 expect![[r#"
467 67..100 '{ ...own; }': ()
468 77..78 'y': u32
469 90..97 'unknown': u32
470 "#]],
471 ); 406 );
472} 407}
473 408
474#[test] 409#[test]
475fn infer_const_body() { 410fn infer_const_body() {
411 // FIXME make check_types work with other bodies
476 check_infer( 412 check_infer(
477 r#" 413 r#"
478const A: u32 = 1 + 1; 414const A: u32 = 1 + 1;
479static B: u64 = { let x = 1; x };"#, 415static B: u64 = { let x = 1; x };
416"#,
480 expect![[r#" 417 expect![[r#"
481 15..16 '1': u32 418 15..16 '1': u32
482 15..20 '1 + 1': u32 419 15..20 '1 + 1': u32
@@ -637,12 +574,12 @@ impl<T> core::ops::Deref for Arc<T> {
637 574
638struct S; 575struct S;
639impl S { 576impl S {
640 fn foo(&self) -> u128 {} 577 fn foo(&self) -> u128 { 0 }
641} 578}
642 579
643fn test(s: Arc<S>) { 580fn test(s: Arc<S>) {
644 (*s, s.foo()); 581 (*s, s.foo());
645} //^ (S, u128) 582} //^^^^^^^^^^^^^ (S, u128)
646"#, 583"#,
647 ); 584 );
648} 585}
@@ -653,7 +590,7 @@ fn deref_trait_with_inference_var() {
653 r#" 590 r#"
654//- minicore: deref 591//- minicore: deref
655struct Arc<T>; 592struct Arc<T>;
656fn new_arc<T>() -> Arc<T> {} 593fn new_arc<T>() -> Arc<T> { Arc }
657impl<T> core::ops::Deref for Arc<T> { 594impl<T> core::ops::Deref for Arc<T> {
658 type Target = T; 595 type Target = T;
659} 596}
@@ -663,8 +600,8 @@ fn foo(a: Arc<S>) {}
663 600
664fn test() { 601fn test() {
665 let a = new_arc(); 602 let a = new_arc();
666 let b = (*a); 603 let b = *a;
667 //^ S 604 //^^ S
668 foo(a); 605 foo(a);
669} 606}
670"#, 607"#,
@@ -684,7 +621,7 @@ impl core::ops::Deref for S {
684 621
685fn test(s: S) { 622fn test(s: S) {
686 s.foo(); 623 s.foo();
687} //^ {unknown} 624} //^^^^^^^ {unknown}
688"#, 625"#,
689 ); 626 );
690} 627}
@@ -701,12 +638,12 @@ impl<T: ?Sized> core::ops::Deref for Arc<T> {
701 638
702struct S; 639struct S;
703impl S { 640impl S {
704 fn foo(&self) -> u128 {} 641 fn foo(&self) -> u128 { 0 }
705} 642}
706 643
707fn test(s: Arc<S>) { 644fn test(s: Arc<S>) {
708 (*s, s.foo()); 645 (*s, s.foo());
709} //^ (S, u128) 646} //^^^^^^^^^^^^^ (S, u128)
710"#, 647"#,
711 ); 648 );
712} 649}
@@ -720,11 +657,11 @@ struct S;
720trait Trait<T> {} 657trait Trait<T> {}
721impl Trait<u32> for S {} 658impl Trait<u32> for S {}
722 659
723fn foo<T: Trait<U>, U>(t: T) -> U {} 660fn foo<T: Trait<U>, U>(t: T) -> U { loop {} }
724 661
725fn test(s: S) { 662fn test(s: S) {
726 (foo(s)); 663 foo(s);
727} //^ u32 664} //^^^^^^ u32
728"#, 665"#,
729 ); 666 );
730} 667}
@@ -741,12 +678,12 @@ impl Trait<isize> for S {}
741 678
742struct O; 679struct O;
743impl O { 680impl O {
744 fn foo<T: Trait<U>, U>(&self, t: T) -> U {} 681 fn foo<T: Trait<U>, U>(&self, t: T) -> U { loop {} }
745} 682}
746 683
747fn test() { 684fn test() {
748 O.foo(S); 685 O.foo(S);
749} //^ isize 686} //^^^^^^^^ isize
750"#, 687"#,
751 ); 688 );
752} 689}
@@ -761,12 +698,12 @@ trait Trait<T> {}
761impl Trait<i64> for S {} 698impl Trait<i64> for S {}
762 699
763impl S { 700impl S {
764 fn foo<U>(&self) -> U where Self: Trait<U> {} 701 fn foo<U>(&self) -> U where Self: Trait<U> { loop {} }
765} 702}
766 703
767fn test() { 704fn test() {
768 S.foo(); 705 S.foo();
769} //^ i64 706} //^^^^^^^ i64
770"#, 707"#,
771 ); 708 );
772} 709}
@@ -782,12 +719,12 @@ impl Trait<&str> for S {}
782 719
783struct O<T>; 720struct O<T>;
784impl<U, T: Trait<U>> O<T> { 721impl<U, T: Trait<U>> O<T> {
785 fn foo(&self) -> U {} 722 fn foo(&self) -> U { loop {} }
786} 723}
787 724
788fn test(o: O<S>) { 725fn test(o: O<S>) {
789 o.foo(); 726 o.foo();
790} //^ &str 727} //^^^^^^^ &str
791"#, 728"#,
792 ); 729 );
793} 730}
@@ -802,7 +739,7 @@ struct S;
802impl Clone for S {} 739impl Clone for S {}
803impl<T> Trait for T where T: Clone {} 740impl<T> Trait for T where T: Clone {}
804fn test<T: Clone>(t: T) { t.foo(); } 741fn test<T: Clone>(t: T) { t.foo(); }
805 //^ u128 742 //^^^^^^^ u128
806"#, 743"#,
807 ); 744 );
808} 745}
@@ -818,7 +755,7 @@ struct S;
818impl Clone for S {} 755impl Clone for S {}
819impl<T> Trait for T where T: Clone {} 756impl<T> Trait for T where T: Clone {}
820fn test<T>(t: T) { t.foo(); } 757fn test<T>(t: T) { t.foo(); }
821 //^ {unknown} 758 //^^^^^^^ {unknown}
822"#, 759"#,
823 ); 760 );
824} 761}
@@ -831,7 +768,7 @@ trait Trait { fn foo(self) -> u128; }
831struct S; 768struct S;
832impl Trait for S {} 769impl Trait for S {}
833fn test<T: Trait>(t: T) { t.foo(); } 770fn test<T: Trait>(t: T) { t.foo(); }
834 //^ u128 771 //^^^^^^^ u128
835"#, 772"#,
836 ); 773 );
837} 774}
@@ -844,7 +781,7 @@ trait Trait { fn foo(self) -> u128; }
844struct S; 781struct S;
845impl Trait for S {} 782impl Trait for S {}
846fn test<T>(t: T) { t.foo(); } 783fn test<T>(t: T) { t.foo(); }
847 //^ {unknown} 784 //^^^^^^^ {unknown}
848"#, 785"#,
849 ); 786 );
850} 787}
@@ -858,8 +795,8 @@ trait Trait {}
858impl<T> core::ops::Deref for T where T: Trait { 795impl<T> core::ops::Deref for T where T: Trait {
859 type Target = i128; 796 type Target = i128;
860} 797}
861fn test<T: Trait>(t: T) { (*t); } 798fn test<T: Trait>(t: T) { *t; }
862 //^ i128 799 //^^ i128
863"#, 800"#,
864 ); 801 );
865} 802}
@@ -1380,12 +1317,12 @@ fn error_bound_chalk() {
1380 check_types( 1317 check_types(
1381 r#" 1318 r#"
1382trait Trait { 1319trait Trait {
1383 fn foo(&self) -> u32 {} 1320 fn foo(&self) -> u32 { 0 }
1384} 1321}
1385 1322
1386fn test(x: (impl Trait + UnknownTrait)) { 1323fn test(x: (impl Trait + UnknownTrait)) {
1387 x.foo(); 1324 x.foo();
1388} //^ u32 1325} //^^^^^^^ u32
1389"#, 1326"#,
1390 ); 1327 );
1391} 1328}
@@ -1476,7 +1413,7 @@ trait Clone {
1476fn api_walkthrough() { 1413fn api_walkthrough() {
1477 for node in foo() { 1414 for node in foo() {
1478 node.clone(); 1415 node.clone();
1479 } //^ {unknown} 1416 } //^^^^^^^^^^^^ {unknown}
1480} 1417}
1481"#, 1418"#,
1482 ); 1419 );
@@ -1513,13 +1450,13 @@ fn where_clause_trait_in_scope_for_method_resolution() {
1513 r#" 1450 r#"
1514mod foo { 1451mod foo {
1515 trait Trait { 1452 trait Trait {
1516 fn foo(&self) -> u32 {} 1453 fn foo(&self) -> u32 { 0 }
1517 } 1454 }
1518} 1455}
1519 1456
1520fn test<T: foo::Trait>(x: T) { 1457fn test<T: foo::Trait>(x: T) {
1521 x.foo(); 1458 x.foo();
1522} //^ u32 1459} //^^^^^^^ u32
1523"#, 1460"#,
1524 ); 1461 );
1525} 1462}
@@ -1982,7 +1919,7 @@ fn fn_item_fn_trait() {
1982//- minicore: fn 1919//- minicore: fn
1983struct S; 1920struct S;
1984 1921
1985fn foo() -> S {} 1922fn foo() -> S { S }
1986 1923
1987fn takes_closure<U, F: FnOnce() -> U>(f: F) -> U { f() } 1924fn takes_closure<U, F: FnOnce() -> U>(f: F) -> U { f() }
1988 1925
@@ -2009,7 +1946,7 @@ trait Trait2 {
2009fn test<T: Trait>() where T::Item: Trait2 { 1946fn test<T: Trait>() where T::Item: Trait2 {
2010 let x: T::Item = no_matter; 1947 let x: T::Item = no_matter;
2011 x.foo(); 1948 x.foo();
2012} //^ u32 1949} //^^^^^^^ u32
2013"#, 1950"#,
2014 ); 1951 );
2015} 1952}
@@ -2029,7 +1966,7 @@ trait Trait2 {
2029fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> { 1966fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> {
2030 let x: T::Item = no_matter; 1967 let x: T::Item = no_matter;
2031 x.foo(); 1968 x.foo();
2032} //^ u32 1969} //^^^^^^^ u32
2033"#, 1970"#,
2034 ); 1971 );
2035} 1972}
@@ -2092,7 +2029,7 @@ impl Trait for S {
2092 2029
2093fn test() { 2030fn test() {
2094 S.f(); 2031 S.f();
2095} //^ u32 2032} //^^^^^ u32
2096"#, 2033"#,
2097 ); 2034 );
2098} 2035}
@@ -2120,7 +2057,7 @@ where
2120 2057
2121fn foo<I: Interner>(interner: &I, t: Ty<I>) { 2058fn foo<I: Interner>(interner: &I, t: Ty<I>) {
2122 fold(interner, t); 2059 fold(interner, t);
2123} //^ Ty<I> 2060} //^^^^^^^^^^^^^^^^^ Ty<I>
2124"#, 2061"#,
2125 ); 2062 );
2126} 2063}
@@ -2139,7 +2076,7 @@ impl Trait<Self> for S {}
2139 2076
2140fn test() { 2077fn test() {
2141 S.foo(); 2078 S.foo();
2142} //^ () 2079} //^^^^^^^ ()
2143"#, 2080"#,
2144 ); 2081 );
2145} 2082}
@@ -2158,7 +2095,7 @@ impl Trait for S<Self> {}
2158 2095
2159fn test() { 2096fn test() {
2160 S.foo(); 2097 S.foo();
2161} //^ {unknown} 2098} //^^^^^^^ {unknown}
2162"#, 2099"#,
2163 ); 2100 );
2164} 2101}
@@ -2176,7 +2113,7 @@ trait Trait2<T> {}
2176 2113
2177fn test<T: Trait>() where T: Trait2<T::Item> { 2114fn test<T: Trait>() where T: Trait2<T::Item> {
2178 let x: T::Item = no_matter; 2115 let x: T::Item = no_matter;
2179} //^ {unknown} 2116} //^^^^^^^^^ {unknown}
2180"#, 2117"#,
2181 ); 2118 );
2182} 2119}
@@ -2193,7 +2130,7 @@ trait Trait<T> {
2193 2130
2194fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> { 2131fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
2195 let x: T::Item = no_matter; 2132 let x: T::Item = no_matter;
2196} //^ {unknown} 2133} //^^^^^^^^^ {unknown}
2197"#, 2134"#,
2198 ); 2135 );
2199} 2136}
@@ -2211,7 +2148,7 @@ trait Trait {
2211 2148
2212fn test<T>() where T: Trait<OtherItem = T::Item> { 2149fn test<T>() where T: Trait<OtherItem = T::Item> {
2213 let x: T::Item = no_matter; 2150 let x: T::Item = no_matter;
2214} //^ Trait::Item<T> 2151} //^^^^^^^^^ Trait::Item<T>
2215"#, 2152"#,
2216 ); 2153 );
2217} 2154}
@@ -2243,7 +2180,7 @@ fn test<T>(t: T) where T: UnificationStoreMut {
2243 t.push(x); 2180 t.push(x);
2244 let y: Key<T>; 2181 let y: Key<T>;
2245 (x, y); 2182 (x, y);
2246} //^ (UnificationStoreBase::Key<T>, UnificationStoreBase::Key<T>) 2183} //^^^^^^ (UnificationStoreBase::Key<T>, UnificationStoreBase::Key<T>)
2247"#, 2184"#,
2248 ); 2185 );
2249} 2186}
@@ -2268,7 +2205,7 @@ impl<T: Iterator> Iterator for S<T> {
2268fn test<I: Iterator<Item: OtherTrait<u32>>>() { 2205fn test<I: Iterator<Item: OtherTrait<u32>>>() {
2269 let x: <S<I> as Iterator>::Item; 2206 let x: <S<I> as Iterator>::Item;
2270 x.foo(); 2207 x.foo();
2271} //^ u32 2208} //^^^^^^^ u32
2272"#, 2209"#,
2273 ); 2210 );
2274} 2211}
@@ -2470,7 +2407,7 @@ impl<T: Trait> Trait for S<T> {
2470fn test<T: Trait>() { 2407fn test<T: Trait>() {
2471 let y: <S<T> as Trait>::Item = no_matter; 2408 let y: <S<T> as Trait>::Item = no_matter;
2472 y.foo(); 2409 y.foo();
2473} //^ u32 2410} //^^^^^^^ u32
2474"#, 2411"#,
2475 ); 2412 );
2476} 2413}
@@ -2490,7 +2427,7 @@ trait Trait {
2490 2427
2491fn test(x: Box<dyn Trait>) { 2428fn test(x: Box<dyn Trait>) {
2492 x.foo(); 2429 x.foo();
2493} //^ () 2430} //^^^^^^^ ()
2494"#, 2431"#,
2495 ); 2432 );
2496} 2433}
@@ -2509,7 +2446,7 @@ impl ToOwned for str {
2509} 2446}
2510fn test() { 2447fn test() {
2511 "foo".to_owned(); 2448 "foo".to_owned();
2512} //^ String 2449} //^^^^^^^^^^^^^^^^ String
2513"#, 2450"#,
2514 ); 2451 );
2515} 2452}
@@ -2649,7 +2586,7 @@ impl<T:A> B for T {
2649 2586
2650fn main() { 2587fn main() {
2651 Bar::foo(); 2588 Bar::foo();
2652} //^ Foo 2589} //^^^^^^^^^^ Foo
2653"#, 2590"#,
2654 ); 2591 );
2655} 2592}
@@ -3002,7 +2939,7 @@ fn test() {
3002 S.get(1); 2939 S.get(1);
3003 //^^^^^^^^ u128 2940 //^^^^^^^^ u128
3004 S.get(1.); 2941 S.get(1.);
3005 //^^^^^^^^ f32 2942 //^^^^^^^^^ f32
3006} 2943}
3007 "#, 2944 "#,
3008 ); 2945 );
@@ -3477,14 +3414,12 @@ trait Convert {
3477 fn new() -> Self; 3414 fn new() -> Self;
3478} 3415}
3479impl Convert for u32 { 3416impl Convert for u32 {
3480 fn new() -> Self { 3417 fn new() -> Self { 0 }
3481 0
3482 }
3483} 3418}
3484 3419
3485async fn get_accounts() -> Result<u32, ()> { 3420async fn get_accounts() -> Result<u32, ()> {
3486 let ret = Fooey.collect(); 3421 let ret = Fooey.collect();
3487 // ^ u32 3422 // ^^^^^^^^^^^^^^^ u32
3488 Ok(ret) 3423 Ok(ret)
3489} 3424}
3490"#, 3425"#,
@@ -3493,6 +3428,7 @@ async fn get_accounts() -> Result<u32, ()> {
3493 3428
3494#[test] 3429#[test]
3495fn local_impl_1() { 3430fn local_impl_1() {
3431 check!(block_local_impls);
3496 check_types( 3432 check_types(
3497 r#" 3433 r#"
3498trait Trait<T> { 3434trait Trait<T> {
@@ -3502,7 +3438,7 @@ trait Trait<T> {
3502fn test() { 3438fn test() {
3503 struct S; 3439 struct S;
3504 impl Trait<u32> for S { 3440 impl Trait<u32> for S {
3505 fn foo(&self) { 0 } 3441 fn foo(&self) -> u32 { 0 }
3506 } 3442 }
3507 3443
3508 S.foo(); 3444 S.foo();
@@ -3514,6 +3450,7 @@ fn test() {
3514 3450
3515#[test] 3451#[test]
3516fn local_impl_2() { 3452fn local_impl_2() {
3453 check!(block_local_impls);
3517 check_types( 3454 check_types(
3518 r#" 3455 r#"
3519struct S; 3456struct S;
@@ -3523,7 +3460,7 @@ fn test() {
3523 fn foo(&self) -> T; 3460 fn foo(&self) -> T;
3524 } 3461 }
3525 impl Trait<u32> for S { 3462 impl Trait<u32> for S {
3526 fn foo(&self) { 0 } 3463 fn foo(&self) -> u32 { 0 }
3527 } 3464 }
3528 3465
3529 S.foo(); 3466 S.foo();
@@ -3535,6 +3472,7 @@ fn test() {
3535 3472
3536#[test] 3473#[test]
3537fn local_impl_3() { 3474fn local_impl_3() {
3475 check!(block_local_impls);
3538 check_types( 3476 check_types(
3539 r#" 3477 r#"
3540trait Trait<T> { 3478trait Trait<T> {
@@ -3547,7 +3485,7 @@ fn test() {
3547 struct S2; 3485 struct S2;
3548 3486
3549 impl Trait<S1> for S2 { 3487 impl Trait<S1> for S2 {
3550 fn foo(&self) { S1 } 3488 fn foo(&self) -> S1 { S1 }
3551 } 3489 }
3552 3490
3553 S2.foo(); 3491 S2.foo();