aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/tests
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/tests')
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs67
-rw-r--r--crates/ra_hir_ty/src/tests/display_source_code.rs50
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs72
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs46
-rw-r--r--crates/ra_hir_ty/src/tests/never_type.rs177
-rw-r--r--crates/ra_hir_ty/src/tests/patterns.rs93
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs75
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs258
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs374
9 files changed, 1151 insertions, 61 deletions
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs
index e6fb3e123..6f777ed8c 100644
--- a/crates/ra_hir_ty/src/tests/coercion.rs
+++ b/crates/ra_hir_ty/src/tests/coercion.rs
@@ -1,6 +1,6 @@
1use super::infer_with_mismatches; 1use super::infer_with_mismatches;
2use insta::assert_snapshot; 2use insta::assert_snapshot;
3use test_utils::covers; 3use test_utils::mark;
4 4
5// Infer with some common definitions and impls. 5// Infer with some common definitions and impls.
6fn infer(source: &str) -> String { 6fn infer(source: &str) -> String {
@@ -116,15 +116,20 @@ fn infer_let_stmt_coerce() {
116 assert_snapshot!( 116 assert_snapshot!(
117 infer(r#" 117 infer(r#"
118fn test() { 118fn test() {
119 let x: &[i32] = &[1]; 119 let x: &[isize] = &[1];
120 let x: *const [isize] = &[1];
120} 121}
121"#), 122"#),
122 @r###" 123 @r###"
123 11..40 '{ ...[1]; }': () 124 11..76 '{ ...[1]; }': ()
124 21..22 'x': &[i32] 125 21..22 'x': &[isize]
125 33..37 '&[1]': &[i32; _] 126 35..39 '&[1]': &[isize; _]
126 34..37 '[1]': [i32; _] 127 36..39 '[1]': [isize; _]
127 35..36 '1': i32 128 37..38 '1': isize
129 49..50 'x': *const [isize]
130 69..73 '&[1]': &[isize; _]
131 70..73 '[1]': [isize; _]
132 71..72 '1': isize
128 "###); 133 "###);
129} 134}
130 135
@@ -339,7 +344,7 @@ fn test(i: i32) {
339 344
340#[test] 345#[test]
341fn coerce_merge_one_by_one1() { 346fn coerce_merge_one_by_one1() {
342 covers!(coerce_merge_fail_fallback); 347 mark::check!(coerce_merge_fail_fallback);
343 348
344 assert_snapshot!( 349 assert_snapshot!(
345 infer(r#" 350 infer(r#"
@@ -384,7 +389,7 @@ fn foo() -> u32 {
384} 389}
385"#, true), 390"#, true),
386 @r###" 391 @r###"
387 17..40 '{ ...own; }': ! 392 17..40 '{ ...own; }': u32
388 23..37 'return unknown': ! 393 23..37 'return unknown': !
389 30..37 'unknown': u32 394 30..37 'unknown': u32
390 "### 395 "###
@@ -514,7 +519,7 @@ fn foo() {
514 27..103 '{ ... }': &u32 519 27..103 '{ ... }': &u32
515 37..82 'if tru... }': () 520 37..82 'if tru... }': ()
516 40..44 'true': bool 521 40..44 'true': bool
517 45..82 '{ ... }': ! 522 45..82 '{ ... }': ()
518 59..71 'return &1u32': ! 523 59..71 'return &1u32': !
519 66..71 '&1u32': &u32 524 66..71 '&1u32': &u32
520 67..71 '1u32': u32 525 67..71 '1u32': u32
@@ -546,6 +551,48 @@ fn test() {
546} 551}
547 552
548#[test] 553#[test]
554fn coerce_fn_items_in_match_arms() {
555 mark::check!(coerce_fn_reification);
556 assert_snapshot!(
557 infer_with_mismatches(r#"
558fn foo1(x: u32) -> isize { 1 }
559fn foo2(x: u32) -> isize { 2 }
560fn foo3(x: u32) -> isize { 3 }
561fn test() {
562 let x = match 1 {
563 1 => foo1,
564 2 => foo2,
565 _ => foo3,
566 };
567}
568"#, true),
569 @r###"
570 9..10 'x': u32
571 26..31 '{ 1 }': isize
572 28..29 '1': isize
573 40..41 'x': u32
574 57..62 '{ 2 }': isize
575 59..60 '2': isize
576 71..72 'x': u32
577 88..93 '{ 3 }': isize
578 90..91 '3': isize
579 104..193 '{ ... }; }': ()
580 114..115 'x': fn(u32) -> isize
581 118..190 'match ... }': fn(u32) -> isize
582 124..125 '1': i32
583 136..137 '1': i32
584 136..137 '1': i32
585 141..145 'foo1': fn foo1(u32) -> isize
586 155..156 '2': i32
587 155..156 '2': i32
588 160..164 'foo2': fn foo2(u32) -> isize
589 174..175 '_': i32
590 179..183 'foo3': fn foo3(u32) -> isize
591 "###
592 );
593}
594
595#[test]
549fn coerce_closure_to_fn_ptr() { 596fn coerce_closure_to_fn_ptr() {
550 assert_snapshot!( 597 assert_snapshot!(
551 infer_with_mismatches(r#" 598 infer_with_mismatches(r#"
diff --git a/crates/ra_hir_ty/src/tests/display_source_code.rs b/crates/ra_hir_ty/src/tests/display_source_code.rs
new file mode 100644
index 000000000..4088b1d22
--- /dev/null
+++ b/crates/ra_hir_ty/src/tests/display_source_code.rs
@@ -0,0 +1,50 @@
1use super::displayed_source_at_pos;
2use crate::test_db::TestDB;
3use ra_db::fixture::WithFixture;
4
5#[test]
6fn qualify_path_to_submodule() {
7 let (db, pos) = TestDB::with_position(
8 r#"
9//- /main.rs
10
11mod foo {
12 pub struct Foo;
13}
14
15fn bar() {
16 let foo: foo::Foo = foo::Foo;
17 foo<|>
18}
19
20"#,
21 );
22 assert_eq!("foo::Foo", displayed_source_at_pos(&db, pos));
23}
24
25#[test]
26fn omit_default_type_parameters() {
27 let (db, pos) = TestDB::with_position(
28 r"
29 //- /main.rs
30 struct Foo<T = u8> { t: T }
31 fn main() {
32 let foo = Foo { t: 5 };
33 foo<|>;
34 }
35 ",
36 );
37 assert_eq!("Foo", displayed_source_at_pos(&db, pos));
38
39 let (db, pos) = TestDB::with_position(
40 r"
41 //- /main.rs
42 struct Foo<K, T = u8> { k: K, t: T }
43 fn main() {
44 let foo = Foo { k: 400, t: 5 };
45 foo<|>;
46 }
47 ",
48 );
49 assert_eq!("Foo<i32>", displayed_source_at_pos(&db, pos));
50}
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs
index 5ddecbdc6..4c6099aa2 100644
--- a/crates/ra_hir_ty/src/tests/macros.rs
+++ b/crates/ra_hir_ty/src/tests/macros.rs
@@ -197,7 +197,7 @@ fn spam() {
197 !0..6 '1isize': isize 197 !0..6 '1isize': isize
198 !0..6 '1isize': isize 198 !0..6 '1isize': isize
199 !0..6 '1isize': isize 199 !0..6 '1isize': isize
200 54..457 '{ ...!(); }': ! 200 54..457 '{ ...!(); }': ()
201 88..109 'spam!(...am!())': {unknown} 201 88..109 'spam!(...am!())': {unknown}
202 115..134 'for _ ...!() {}': () 202 115..134 'for _ ...!() {}': ()
203 119..120 '_': {unknown} 203 119..120 '_': {unknown}
@@ -269,7 +269,7 @@ fn test() { S.foo()<|>; }
269} 269}
270 270
271#[test] 271#[test]
272fn infer_impl_items_generated_by_macros() { 272fn infer_assoc_items_generated_by_macros() {
273 let t = type_at( 273 let t = type_at(
274 r#" 274 r#"
275//- /main.rs 275//- /main.rs
@@ -288,7 +288,7 @@ fn test() { S.foo()<|>; }
288} 288}
289 289
290#[test] 290#[test]
291fn infer_impl_items_generated_by_macros_chain() { 291fn infer_assoc_items_generated_by_macros_chain() {
292 let t = type_at( 292 let t = type_at(
293 r#" 293 r#"
294//- /main.rs 294//- /main.rs
@@ -339,6 +339,46 @@ pub fn baz() -> usize { 31usize }
339} 339}
340 340
341#[test] 341#[test]
342fn infer_macro_with_dollar_crate_is_correct_in_trait_associate_type() {
343 let (db, pos) = TestDB::with_position(
344 r#"
345//- /main.rs crate:main deps:foo
346use foo::Trait;
347
348fn test() {
349 let msg = foo::Message(foo::MessageRef);
350 let r = msg.deref();
351 r<|>;
352}
353
354//- /lib.rs crate:foo
355pub struct MessageRef;
356pub struct Message(MessageRef);
357
358pub trait Trait {
359 type Target;
360 fn deref(&self) -> &Self::Target;
361}
362
363#[macro_export]
364macro_rules! expand {
365 () => {
366 impl Trait for Message {
367 type Target = $crate::MessageRef;
368 fn deref(&self) -> &Self::Target {
369 &self.0
370 }
371 }
372 }
373}
374
375expand!();
376"#,
377 );
378 assert_eq!("&MessageRef", type_at_pos(&db, pos));
379}
380
381#[test]
342fn infer_type_value_non_legacy_macro_use_as() { 382fn infer_type_value_non_legacy_macro_use_as() {
343 assert_snapshot!( 383 assert_snapshot!(
344 infer(r#" 384 infer(r#"
@@ -388,6 +428,32 @@ fn main() {
388} 428}
389 429
390#[test] 430#[test]
431fn infer_local_inner_macros() {
432 let (db, pos) = TestDB::with_position(
433 r#"
434//- /main.rs crate:main deps:foo
435fn test() {
436 let x = foo::foo!(1);
437 x<|>;
438}
439
440//- /lib.rs crate:foo
441#[macro_export(local_inner_macros)]
442macro_rules! foo {
443 (1) => { bar!() };
444}
445
446#[macro_export]
447macro_rules! bar {
448 () => { 42 }
449}
450
451"#,
452 );
453 assert_eq!("i32", type_at_pos(&db, pos));
454}
455
456#[test]
391fn infer_builtin_macros_line() { 457fn infer_builtin_macros_line() {
392 assert_snapshot!( 458 assert_snapshot!(
393 infer(r#" 459 infer(r#"
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index ab87f598a..558a70022 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -17,8 +17,8 @@ impl<T> [T] {
17#[lang = "slice_alloc"] 17#[lang = "slice_alloc"]
18impl<T> [T] {} 18impl<T> [T] {}
19 19
20fn test() { 20fn test(x: &[u8]) {
21 <[_]>::foo(b"foo"); 21 <[_]>::foo(x);
22} 22}
23"#), 23"#),
24 @r###" 24 @r###"
@@ -26,10 +26,11 @@ fn test() {
26 56..79 '{ ... }': T 26 56..79 '{ ... }': T
27 66..73 'loop {}': ! 27 66..73 'loop {}': !
28 71..73 '{}': () 28 71..73 '{}': ()
29 133..160 '{ ...o"); }': () 29 131..132 'x': &[u8]
30 139..149 '<[_]>::foo': fn foo<u8>(&[u8]) -> u8 30 141..163 '{ ...(x); }': ()
31 139..157 '<[_]>:..."foo")': u8 31 147..157 '<[_]>::foo': fn foo<u8>(&[u8]) -> u8
32 150..156 'b"foo"': &[u8] 32 147..160 '<[_]>::foo(x)': u8
33 158..159 'x': &[u8]
33 "### 34 "###
34 ); 35 );
35} 36}
@@ -983,7 +984,7 @@ fn test() { S2.into()<|>; }
983 984
984#[test] 985#[test]
985fn method_resolution_overloaded_method() { 986fn method_resolution_overloaded_method() {
986 test_utils::covers!(impl_self_type_match_without_receiver); 987 test_utils::mark::check!(impl_self_type_match_without_receiver);
987 let t = type_at( 988 let t = type_at(
988 r#" 989 r#"
989//- main.rs 990//- main.rs
@@ -1095,3 +1096,34 @@ fn test() { (S {}).method()<|>; }
1095 ); 1096 );
1096 assert_eq!(t, "()"); 1097 assert_eq!(t, "()");
1097} 1098}
1099
1100#[test]
1101fn dyn_trait_super_trait_not_in_scope() {
1102 assert_snapshot!(
1103 infer(r#"
1104mod m {
1105 pub trait SuperTrait {
1106 fn foo(&self) -> u32 { 0 }
1107 }
1108}
1109trait Trait: m::SuperTrait {}
1110
1111struct S;
1112impl m::SuperTrait for S {}
1113impl Trait for S {}
1114
1115fn test(d: &dyn Trait) {
1116 d.foo();
1117}
1118"#),
1119 @r###"
1120 52..56 'self': &Self
1121 65..70 '{ 0 }': u32
1122 67..68 '0': u32
1123 177..178 'd': &dyn Trait
1124 192..208 '{ ...o(); }': ()
1125 198..199 'd': &dyn Trait
1126 198..205 'd.foo()': u32
1127 "###
1128 );
1129}
diff --git a/crates/ra_hir_ty/src/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs
index a77209480..082c47208 100644
--- a/crates/ra_hir_ty/src/tests/never_type.rs
+++ b/crates/ra_hir_ty/src/tests/never_type.rs
@@ -1,4 +1,6 @@
1use super::type_at; 1use insta::assert_snapshot;
2
3use super::{infer_with_mismatches, type_at};
2 4
3#[test] 5#[test]
4fn infer_never1() { 6fn infer_never1() {
@@ -261,3 +263,176 @@ fn test(a: i32) {
261 ); 263 );
262 assert_eq!(t, "f64"); 264 assert_eq!(t, "f64");
263} 265}
266
267#[test]
268fn diverging_expression_1() {
269 let t = infer_with_mismatches(
270 r#"
271//- /main.rs
272fn test1() {
273 let x: u32 = return;
274}
275fn test2() {
276 let x: u32 = { return; };
277}
278fn test3() {
279 let x: u32 = loop {};
280}
281fn test4() {
282 let x: u32 = { loop {} };
283}
284fn test5() {
285 let x: u32 = { if true { loop {}; } else { loop {}; } };
286}
287fn test6() {
288 let x: u32 = { let y: u32 = { loop {}; }; };
289}
290"#,
291 true,
292 );
293 assert_snapshot!(t, @r###"
294 25..53 '{ ...urn; }': ()
295 35..36 'x': u32
296 44..50 'return': !
297 65..98 '{ ...; }; }': ()
298 75..76 'x': u32
299 84..95 '{ return; }': u32
300 86..92 'return': !
301 110..139 '{ ... {}; }': ()
302 120..121 'x': u32
303 129..136 'loop {}': !
304 134..136 '{}': ()
305 151..184 '{ ...} }; }': ()
306 161..162 'x': u32
307 170..181 '{ loop {} }': u32
308 172..179 'loop {}': !
309 177..179 '{}': ()
310 196..260 '{ ...} }; }': ()
311 206..207 'x': u32
312 215..257 '{ if t...}; } }': u32
313 217..255 'if tru... {}; }': u32
314 220..224 'true': bool
315 225..237 '{ loop {}; }': u32
316 227..234 'loop {}': !
317 232..234 '{}': ()
318 243..255 '{ loop {}; }': u32
319 245..252 'loop {}': !
320 250..252 '{}': ()
321 272..324 '{ ...; }; }': ()
322 282..283 'x': u32
323 291..321 '{ let ...; }; }': u32
324 297..298 'y': u32
325 306..318 '{ loop {}; }': u32
326 308..315 'loop {}': !
327 313..315 '{}': ()
328 "###);
329}
330
331#[test]
332fn diverging_expression_2() {
333 let t = infer_with_mismatches(
334 r#"
335//- /main.rs
336fn test1() {
337 // should give type mismatch
338 let x: u32 = { loop {}; "foo" };
339}
340"#,
341 true,
342 );
343 assert_snapshot!(t, @r###"
344 25..98 '{ ..." }; }': ()
345 68..69 'x': u32
346 77..95 '{ loop...foo" }': &str
347 79..86 'loop {}': !
348 84..86 '{}': ()
349 88..93 '"foo"': &str
350 77..95: expected u32, got &str
351 88..93: expected u32, got &str
352 "###);
353}
354
355#[test]
356fn diverging_expression_3_break() {
357 let t = infer_with_mismatches(
358 r#"
359//- /main.rs
360fn test1() {
361 // should give type mismatch
362 let x: u32 = { loop { break; } };
363}
364fn test2() {
365 // should give type mismatch
366 let x: u32 = { for a in b { break; }; };
367 // should give type mismatch as well
368 let x: u32 = { for a in b {}; };
369 // should give type mismatch as well
370 let x: u32 = { for a in b { return; }; };
371}
372fn test3() {
373 // should give type mismatch
374 let x: u32 = { while true { break; }; };
375 // should give type mismatch as well -- there's an implicit break, even if it's never hit
376 let x: u32 = { while true {}; };
377 // should give type mismatch as well
378 let x: u32 = { while true { return; }; };
379}
380"#,
381 true,
382 );
383 assert_snapshot!(t, @r###"
384 25..99 '{ ...} }; }': ()
385 68..69 'x': u32
386 77..96 '{ loop...k; } }': ()
387 79..94 'loop { break; }': ()
388 84..94 '{ break; }': ()
389 86..91 'break': !
390 77..96: expected u32, got ()
391 79..94: expected u32, got ()
392 111..357 '{ ...; }; }': ()
393 154..155 'x': u32
394 163..189 '{ for ...; }; }': ()
395 165..186 'for a ...eak; }': ()
396 169..170 'a': {unknown}
397 174..175 'b': {unknown}
398 176..186 '{ break; }': ()
399 178..183 'break': !
400 240..241 'x': u32
401 249..267 '{ for ... {}; }': ()
402 251..264 'for a in b {}': ()
403 255..256 'a': {unknown}
404 260..261 'b': {unknown}
405 262..264 '{}': ()
406 318..319 'x': u32
407 327..354 '{ for ...; }; }': ()
408 329..351 'for a ...urn; }': ()
409 333..334 'a': {unknown}
410 338..339 'b': {unknown}
411 340..351 '{ return; }': ()
412 342..348 'return': !
413 163..189: expected u32, got ()
414 249..267: expected u32, got ()
415 327..354: expected u32, got ()
416 369..668 '{ ...; }; }': ()
417 412..413 'x': u32
418 421..447 '{ whil...; }; }': ()
419 423..444 'while ...eak; }': ()
420 429..433 'true': bool
421 434..444 '{ break; }': ()
422 436..441 'break': !
423 551..552 'x': u32
424 560..578 '{ whil... {}; }': ()
425 562..575 'while true {}': ()
426 568..572 'true': bool
427 573..575 '{}': ()
428 629..630 'x': u32
429 638..665 '{ whil...; }; }': ()
430 640..662 'while ...urn; }': ()
431 646..650 'true': bool
432 651..662 '{ return; }': ()
433 653..659 'return': !
434 421..447: expected u32, got ()
435 560..578: expected u32, got ()
436 638..665: expected u32, got ()
437 "###);
438}
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs
index af291092d..fe62587c0 100644
--- a/crates/ra_hir_ty/src/tests/patterns.rs
+++ b/crates/ra_hir_ty/src/tests/patterns.rs
@@ -1,5 +1,5 @@
1use insta::assert_snapshot; 1use insta::assert_snapshot;
2use test_utils::covers; 2use test_utils::mark;
3 3
4use super::{infer, infer_with_mismatches}; 4use super::{infer, infer_with_mismatches};
5 5
@@ -197,7 +197,7 @@ fn test() {
197 197
198#[test] 198#[test]
199fn infer_pattern_match_ergonomics_ref() { 199fn infer_pattern_match_ergonomics_ref() {
200 covers!(match_ergonomics_ref); 200 mark::check!(match_ergonomics_ref);
201 assert_snapshot!( 201 assert_snapshot!(
202 infer(r#" 202 infer(r#"
203fn test() { 203fn test() {
@@ -369,6 +369,45 @@ fn test() {
369} 369}
370 370
371#[test] 371#[test]
372fn enum_variant_through_self_in_pattern() {
373 assert_snapshot!(
374 infer(r#"
375enum E {
376 A { x: usize },
377 B(usize),
378 C
379}
380
381impl E {
382 fn test() {
383 match (loop {}) {
384 Self::A { x } => { x; },
385 Self::B(x) => { x; },
386 Self::C => {},
387 };
388 }
389}
390"#),
391 @r###"
392 76..218 '{ ... }': ()
393 86..211 'match ... }': ()
394 93..100 'loop {}': !
395 98..100 '{}': ()
396 116..129 'Self::A { x }': E
397 126..127 'x': usize
398 133..139 '{ x; }': ()
399 135..136 'x': usize
400 153..163 'Self::B(x)': E
401 161..162 'x': usize
402 167..173 '{ x; }': ()
403 169..170 'x': usize
404 187..194 'Self::C': E
405 198..200 '{}': ()
406 "###
407 );
408}
409
410#[test]
372fn infer_generics_in_patterns() { 411fn infer_generics_in_patterns() {
373 assert_snapshot!( 412 assert_snapshot!(
374 infer(r#" 413 infer(r#"
@@ -481,3 +520,53 @@ fn main() {
481 105..107 '()': () 520 105..107 '()': ()
482 ") 521 ")
483} 522}
523
524#[test]
525fn match_ergonomics_in_closure_params() {
526 assert_snapshot!(
527 infer(r#"
528#[lang = "fn_once"]
529trait FnOnce<Args> {
530 type Output;
531}
532
533fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
534
535fn test() {
536 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
537 foo(&(1, "a"), |(x, y)| x);
538}
539"#),
540 @r###"
541 94..95 't': T
542 100..101 'f': F
543 111..122 '{ loop {} }': U
544 113..120 'loop {}': !
545 118..120 '{}': ()
546 134..233 '{ ... x); }': ()
547 140..143 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32
548 140..167 'foo(&(...y)| x)': i32
549 144..153 '&(1, "a")': &(i32, &str)
550 145..153 '(1, "a")': (i32, &str)
551 146..147 '1': i32
552 149..152 '"a"': &str
553 155..166 '|&(x, y)| x': |&(i32, &str)| -> i32
554 156..163 '&(x, y)': &(i32, &str)
555 157..163 '(x, y)': (i32, &str)
556 158..159 'x': i32
557 161..162 'y': &str
558 165..166 'x': i32
559 204..207 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32
560 204..230 'foo(&(...y)| x)': &i32
561 208..217 '&(1, "a")': &(i32, &str)
562 209..217 '(1, "a")': (i32, &str)
563 210..211 '1': i32
564 213..216 '"a"': &str
565 219..229 '|(x, y)| x': |&(i32, &str)| -> &i32
566 220..226 '(x, y)': (i32, &str)
567 221..222 'x': &i32
568 224..225 'y': &&str
569 228..229 'x': &i32
570 "###
571 );
572}
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs
index 8a1292c7a..1f004bd63 100644
--- a/crates/ra_hir_ty/src/tests/regression.rs
+++ b/crates/ra_hir_ty/src/tests/regression.rs
@@ -1,9 +1,10 @@
1use insta::assert_snapshot; 1use insta::assert_snapshot;
2use test_utils::covers; 2use ra_db::fixture::WithFixture;
3use test_utils::mark;
3 4
4use super::infer;
5use crate::test_db::TestDB; 5use crate::test_db::TestDB;
6use ra_db::fixture::WithFixture; 6
7use super::infer;
7 8
8#[test] 9#[test]
9fn bug_484() { 10fn bug_484() {
@@ -89,8 +90,8 @@ fn quux() {
89 90
90#[test] 91#[test]
91fn recursive_vars() { 92fn recursive_vars() {
92 covers!(type_var_cycles_resolve_completely); 93 mark::check!(type_var_cycles_resolve_completely);
93 covers!(type_var_cycles_resolve_as_possible); 94 mark::check!(type_var_cycles_resolve_as_possible);
94 assert_snapshot!( 95 assert_snapshot!(
95 infer(r#" 96 infer(r#"
96fn test() { 97fn test() {
@@ -112,8 +113,6 @@ fn test() {
112 113
113#[test] 114#[test]
114fn recursive_vars_2() { 115fn recursive_vars_2() {
115 covers!(type_var_cycles_resolve_completely);
116 covers!(type_var_cycles_resolve_as_possible);
117 assert_snapshot!( 116 assert_snapshot!(
118 infer(r#" 117 infer(r#"
119fn test() { 118fn test() {
@@ -170,7 +169,7 @@ fn write() {
170 169
171#[test] 170#[test]
172fn infer_std_crash_2() { 171fn infer_std_crash_2() {
173 covers!(type_var_resolves_to_int_var); 172 mark::check!(type_var_resolves_to_int_var);
174 // caused "equating two type variables, ...", taken from std 173 // caused "equating two type variables, ...", taken from std
175 assert_snapshot!( 174 assert_snapshot!(
176 infer(r#" 175 infer(r#"
@@ -535,6 +534,66 @@ fn foo(b: Bar) {
535} 534}
536 535
537#[test] 536#[test]
537fn issue_4235_name_conflicts() {
538 assert_snapshot!(
539 infer(r#"
540struct FOO {}
541static FOO:FOO = FOO {};
542
543impl FOO {
544 fn foo(&self) {}
545}
546
547fn main() {
548 let a = &FOO;
549 a.foo();
550}
551"#), @r###"
552 32..38 'FOO {}': FOO
553 64..68 'self': &FOO
554 70..72 '{}': ()
555 86..120 '{ ...o(); }': ()
556 96..97 'a': &FOO
557 100..104 '&FOO': &FOO
558 101..104 'FOO': FOO
559 110..111 'a': &FOO
560 110..117 'a.foo()': ()
561"###
562 );
563}
564
565#[test]
566fn issue_4465_dollar_crate_at_type() {
567 assert_snapshot!(
568 infer(r#"
569pub struct Foo {}
570pub fn anything<T>() -> T {
571 loop {}
572}
573macro_rules! foo {
574 () => {{
575 let r: $crate::Foo = anything();
576 r
577 }};
578}
579fn main() {
580 let _a = foo!();
581}
582"#), @r###"
583 45..60 '{ loop {} }': T
584 51..58 'loop {}': !
585 56..58 '{}': ()
586 !0..31 '{letr:...g();r}': Foo
587 !4..5 'r': Foo
588 !18..26 'anything': fn anything<Foo>() -> Foo
589 !18..28 'anything()': Foo
590 !29..30 'r': Foo
591 164..188 '{ ...!(); }': ()
592 174..176 '_a': Foo
593"###);
594}
595
596#[test]
538fn issue_4053_diesel_where_clauses() { 597fn issue_4053_diesel_where_clauses() {
539 assert_snapshot!( 598 assert_snapshot!(
540 infer(r#" 599 infer(r#"
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index 56abc65b8..88309157b 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -179,7 +179,7 @@ fn test(a: u32, b: isize, c: !, d: &str) {
179 17..18 'b': isize 179 17..18 'b': isize
180 27..28 'c': ! 180 27..28 'c': !
181 33..34 'd': &str 181 33..34 'd': &str
182 42..121 '{ ...f32; }': ! 182 42..121 '{ ...f32; }': ()
183 48..49 'a': u32 183 48..49 'a': u32
184 55..56 'b': isize 184 55..56 'b': isize
185 62..63 'c': ! 185 62..63 'c': !
@@ -385,6 +385,26 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
385} 385}
386 386
387#[test] 387#[test]
388fn infer_raw_ref() {
389 assert_snapshot!(
390 infer(r#"
391fn test(a: i32) {
392 &raw mut a;
393 &raw const a;
394}
395"#),
396 @r###"
397 9..10 'a': i32
398 17..54 '{ ...t a; }': ()
399 23..33 '&raw mut a': *mut i32
400 32..33 'a': i32
401 39..51 '&raw const a': *const i32
402 50..51 'a': i32
403 "###
404 );
405}
406
407#[test]
388fn infer_literals() { 408fn infer_literals() {
389 assert_snapshot!( 409 assert_snapshot!(
390 infer(r##" 410 infer(r##"
@@ -414,7 +434,7 @@ fn test() {
414 27..31 '5f32': f32 434 27..31 '5f32': f32
415 37..41 '5f64': f64 435 37..41 '5f64': f64
416 47..54 '"hello"': &str 436 47..54 '"hello"': &str
417 60..68 'b"bytes"': &[u8] 437 60..68 'b"bytes"': &[u8; _]
418 74..77 ''c'': char 438 74..77 ''c'': char
419 83..87 'b'b'': u8 439 83..87 'b'b'': u8
420 93..97 '3.14': f64 440 93..97 '3.14': f64
@@ -422,7 +442,7 @@ fn test() {
422 113..118 'false': bool 442 113..118 'false': bool
423 124..128 'true': bool 443 124..128 'true': bool
424 134..202 'r#" ... "#': &str 444 134..202 'r#" ... "#': &str
425 208..218 'br#"yolo"#': &[u8] 445 208..218 'br#"yolo"#': &[u8; _]
426 "### 446 "###
427 ); 447 );
428} 448}
@@ -576,6 +596,50 @@ impl S {
576} 596}
577 597
578#[test] 598#[test]
599fn infer_self_as_path() {
600 assert_snapshot!(
601 infer(r#"
602struct S1;
603struct S2(isize);
604enum E {
605 V1,
606 V2(u32),
607}
608
609impl S1 {
610 fn test() {
611 Self;
612 }
613}
614impl S2 {
615 fn test() {
616 Self(1);
617 }
618}
619impl E {
620 fn test() {
621 Self::V1;
622 Self::V2(1);
623 }
624}
625"#),
626 @r###"
627 87..108 '{ ... }': ()
628 97..101 'Self': S1
629 135..159 '{ ... }': ()
630 145..149 'Self': S2(isize) -> S2
631 145..152 'Self(1)': S2
632 150..151 '1': isize
633 185..231 '{ ... }': ()
634 195..203 'Self::V1': E
635 213..221 'Self::V2': V2(u32) -> E
636 213..224 'Self::V2(1)': E
637 222..223 '1': u32
638 "###
639 );
640}
641
642#[test]
579fn infer_binary_op() { 643fn infer_binary_op() {
580 assert_snapshot!( 644 assert_snapshot!(
581 infer(r#" 645 infer(r#"
@@ -893,7 +957,7 @@ fn main(foo: Foo) {
893 51..107 'if tru... }': () 957 51..107 'if tru... }': ()
894 54..58 'true': bool 958 54..58 'true': bool
895 59..67 '{ }': () 959 59..67 '{ }': ()
896 73..107 'if fal... }': () 960 73..107 'if fal... }': i32
897 76..81 'false': bool 961 76..81 'false': bool
898 82..107 '{ ... }': i32 962 82..107 '{ ... }': i32
899 92..95 'foo': Foo 963 92..95 'foo': Foo
@@ -935,7 +999,7 @@ fn foo() {
935 29..33 'true': bool 999 29..33 'true': bool
936 34..51 '{ ... }': i32 1000 34..51 '{ ... }': i32
937 44..45 '1': i32 1001 44..45 '1': i32
938 57..80 '{ ... }': ! 1002 57..80 '{ ... }': i32
939 67..73 'return': ! 1003 67..73 'return': !
940 90..93 '_x2': i32 1004 90..93 '_x2': i32
941 96..149 'if tru... }': i32 1005 96..149 'if tru... }': i32
@@ -951,7 +1015,7 @@ fn foo() {
951 186..190 'true': bool 1015 186..190 'true': bool
952 194..195 '3': i32 1016 194..195 '3': i32
953 205..206 '_': bool 1017 205..206 '_': bool
954 210..241 '{ ... }': ! 1018 210..241 '{ ... }': i32
955 224..230 'return': ! 1019 224..230 'return': !
956 257..260 '_x4': i32 1020 257..260 '_x4': i32
957 263..320 'match ... }': i32 1021 263..320 'match ... }': i32
@@ -1687,7 +1751,7 @@ fn foo() -> u32 {
1687 17..59 '{ ...; }; }': () 1751 17..59 '{ ...; }; }': ()
1688 27..28 'x': || -> usize 1752 27..28 'x': || -> usize
1689 31..56 '|| -> ...n 1; }': || -> usize 1753 31..56 '|| -> ...n 1; }': || -> usize
1690 43..56 '{ return 1; }': ! 1754 43..56 '{ return 1; }': usize
1691 45..53 'return 1': ! 1755 45..53 'return 1': !
1692 52..53 '1': usize 1756 52..53 '1': usize
1693 "### 1757 "###
@@ -1706,7 +1770,7 @@ fn foo() -> u32 {
1706 17..48 '{ ...; }; }': () 1770 17..48 '{ ...; }; }': ()
1707 27..28 'x': || -> () 1771 27..28 'x': || -> ()
1708 31..45 '|| { return; }': || -> () 1772 31..45 '|| { return; }': || -> ()
1709 34..45 '{ return; }': ! 1773 34..45 '{ return; }': ()
1710 36..42 'return': ! 1774 36..42 'return': !
1711 "### 1775 "###
1712 ); 1776 );
@@ -1755,3 +1819,181 @@ fn main() {
1755 "### 1819 "###
1756 ); 1820 );
1757} 1821}
1822
1823#[test]
1824fn effects_smoke_test() {
1825 assert_snapshot!(
1826 infer(r#"
1827fn main() {
1828 let x = unsafe { 92 };
1829 let y = async { async { () }.await };
1830 let z = try { () };
1831 let t = 'a: { 92 };
1832}
1833"#),
1834 @r###"
1835 11..131 '{ ...2 }; }': ()
1836 21..22 'x': i32
1837 32..38 '{ 92 }': i32
1838 34..36 '92': i32
1839 48..49 'y': {unknown}
1840 58..80 '{ asyn...wait }': {unknown}
1841 60..78 'async ....await': {unknown}
1842 66..72 '{ () }': ()
1843 68..70 '()': ()
1844 90..91 'z': {unknown}
1845 94..104 'try { () }': {unknown}
1846 98..104 '{ () }': ()
1847 100..102 '()': ()
1848 114..115 't': i32
1849 122..128 '{ 92 }': i32
1850 124..126 '92': i32
1851 "###
1852 )
1853}
1854
1855#[test]
1856fn infer_generic_from_later_assignment() {
1857 assert_snapshot!(
1858 infer(r#"
1859enum Option<T> { Some(T), None }
1860use Option::*;
1861
1862fn test() {
1863 let mut end = None;
1864 loop {
1865 end = Some(true);
1866 }
1867}
1868"#),
1869 @r###"
1870 60..130 '{ ... } }': ()
1871 70..77 'mut end': Option<bool>
1872 80..84 'None': Option<bool>
1873 90..128 'loop {... }': !
1874 95..128 '{ ... }': ()
1875 105..108 'end': Option<bool>
1876 105..121 'end = ...(true)': ()
1877 111..115 'Some': Some<bool>(bool) -> Option<bool>
1878 111..121 'Some(true)': Option<bool>
1879 116..120 'true': bool
1880 "###
1881 );
1882}
1883
1884#[test]
1885fn infer_loop_break_with_val() {
1886 assert_snapshot!(
1887 infer(r#"
1888enum Option<T> { Some(T), None }
1889use Option::*;
1890
1891fn test() {
1892 let x = loop {
1893 if false {
1894 break None;
1895 }
1896
1897 break Some(true);
1898 };
1899}
1900"#),
1901 @r###"
1902 60..169 '{ ... }; }': ()
1903 70..71 'x': Option<bool>
1904 74..166 'loop {... }': Option<bool>
1905 79..166 '{ ... }': ()
1906 89..133 'if fal... }': ()
1907 92..97 'false': bool
1908 98..133 '{ ... }': ()
1909 112..122 'break None': !
1910 118..122 'None': Option<bool>
1911 143..159 'break ...(true)': !
1912 149..153 'Some': Some<bool>(bool) -> Option<bool>
1913 149..159 'Some(true)': Option<bool>
1914 154..158 'true': bool
1915 "###
1916 );
1917}
1918
1919#[test]
1920fn infer_loop_break_without_val() {
1921 assert_snapshot!(
1922 infer(r#"
1923enum Option<T> { Some(T), None }
1924use Option::*;
1925
1926fn test() {
1927 let x = loop {
1928 if false {
1929 break;
1930 }
1931 };
1932}
1933"#),
1934 @r###"
1935 60..137 '{ ... }; }': ()
1936 70..71 'x': ()
1937 74..134 'loop {... }': ()
1938 79..134 '{ ... }': ()
1939 89..128 'if fal... }': ()
1940 92..97 'false': bool
1941 98..128 '{ ... }': ()
1942 112..117 'break': !
1943 "###
1944 );
1945}
1946
1947#[test]
1948fn infer_labelled_break_with_val() {
1949 assert_snapshot!(
1950 infer(r#"
1951fn foo() {
1952 let _x = || 'outer: loop {
1953 let inner = 'inner: loop {
1954 let i = Default::default();
1955 if (break 'outer i) {
1956 loop { break 'inner 5i8; };
1957 } else if true {
1958 break 'inner 6;
1959 }
1960 break 7;
1961 };
1962 break inner < 8;
1963 };
1964}
1965"#),
1966 @r###"
1967 10..336 '{ ... }; }': ()
1968 20..22 '_x': || -> bool
1969 25..333 '|| 'ou... }': || -> bool
1970 28..333 ''outer... }': bool
1971 41..333 '{ ... }': ()
1972 55..60 'inner': i8
1973 63..301 ''inner... }': i8
1974 76..301 '{ ... }': ()
1975 94..95 'i': bool
1976 98..114 'Defaul...efault': {unknown}
1977 98..116 'Defaul...ault()': bool
1978 130..270 'if (br... }': ()
1979 134..148 'break 'outer i': !
1980 147..148 'i': bool
1981 150..209 '{ ... }': ()
1982 168..194 'loop {...5i8; }': !
1983 173..194 '{ brea...5i8; }': ()
1984 175..191 'break ...er 5i8': !
1985 188..191 '5i8': i8
1986 215..270 'if tru... }': ()
1987 218..222 'true': bool
1988 223..270 '{ ... }': ()
1989 241..255 'break 'inner 6': !
1990 254..255 '6': i8
1991 283..290 'break 7': !
1992 289..290 '7': i8
1993 311..326 'break inner < 8': !
1994 317..322 'inner': i8
1995 317..326 'inner < 8': bool
1996 325..326 '8': i8
1997 "###
1998 );
1999}
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index e555c879a..e8778d419 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -1,10 +1,11 @@
1use insta::assert_snapshot; 1use insta::assert_snapshot;
2
3use ra_db::fixture::WithFixture; 2use ra_db::fixture::WithFixture;
3use test_utils::mark;
4 4
5use super::{infer, infer_with_mismatches, type_at, type_at_pos};
6use crate::test_db::TestDB; 5use crate::test_db::TestDB;
7 6
7use super::{infer, infer_with_mismatches, type_at, type_at_pos};
8
8#[test] 9#[test]
9fn infer_await() { 10fn infer_await() {
10 let (db, pos) = TestDB::with_position( 11 let (db, pos) = TestDB::with_position(
@@ -301,7 +302,7 @@ fn test() {
301 302
302#[test] 303#[test]
303fn trait_default_method_self_bound_implements_trait() { 304fn trait_default_method_self_bound_implements_trait() {
304 test_utils::covers!(trait_self_implements_self); 305 mark::check!(trait_self_implements_self);
305 assert_snapshot!( 306 assert_snapshot!(
306 infer(r#" 307 infer(r#"
307trait Trait { 308trait Trait {
@@ -324,7 +325,6 @@ trait Trait {
324 325
325#[test] 326#[test]
326fn trait_default_method_self_bound_implements_super_trait() { 327fn trait_default_method_self_bound_implements_super_trait() {
327 test_utils::covers!(trait_self_implements_self);
328 assert_snapshot!( 328 assert_snapshot!(
329 infer(r#" 329 infer(r#"
330trait SuperTrait { 330trait SuperTrait {
@@ -1617,6 +1617,138 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
1617} 1617}
1618 1618
1619#[test] 1619#[test]
1620fn fn_ptr_and_item() {
1621 assert_snapshot!(
1622 infer(r#"
1623#[lang="fn_once"]
1624trait FnOnce<Args> {
1625 type Output;
1626
1627 fn call_once(self, args: Args) -> Self::Output;
1628}
1629
1630trait Foo<T> {
1631 fn foo(&self) -> T;
1632}
1633
1634struct Bar<T>(T);
1635
1636impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> {
1637 fn foo(&self) -> (A1, R) {}
1638}
1639
1640enum Opt<T> { None, Some(T) }
1641impl<T> Opt<T> {
1642 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {}
1643}
1644
1645fn test() {
1646 let bar: Bar<fn(u8) -> u32>;
1647 bar.foo();
1648
1649 let opt: Opt<u8>;
1650 let f: fn(u8) -> u32;
1651 opt.map(f);
1652}
1653"#),
1654 @r###"
165575..79 'self': Self
165681..85 'args': Args
1657140..144 'self': &Self
1658244..248 'self': &Bar<F>
1659261..263 '{}': ()
1660347..351 'self': Opt<T>
1661353..354 'f': F
1662369..371 '{}': ()
1663385..501 '{ ...(f); }': ()
1664395..398 'bar': Bar<fn(u8) -> u32>
1665424..427 'bar': Bar<fn(u8) -> u32>
1666424..433 'bar.foo()': {unknown}
1667444..447 'opt': Opt<u8>
1668466..467 'f': fn(u8) -> u32
1669488..491 'opt': Opt<u8>
1670488..498 'opt.map(f)': Opt<FnOnce::Output<fn(u8) -> u32, (u8,)>>
1671496..497 'f': fn(u8) -> u32
1672"###
1673 );
1674}
1675
1676#[test]
1677fn fn_trait_deref_with_ty_default() {
1678 assert_snapshot!(
1679 infer(r#"
1680#[lang = "deref"]
1681trait Deref {
1682 type Target;
1683
1684 fn deref(&self) -> &Self::Target;
1685}
1686
1687#[lang="fn_once"]
1688trait FnOnce<Args> {
1689 type Output;
1690
1691 fn call_once(self, args: Args) -> Self::Output;
1692}
1693
1694struct Foo;
1695
1696impl Foo {
1697 fn foo(&self) -> usize {}
1698}
1699
1700struct Lazy<T, F = fn() -> T>(F);
1701
1702impl<T, F> Lazy<T, F> {
1703 pub fn new(f: F) -> Lazy<T, F> {}
1704}
1705
1706impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
1707 type Target = T;
1708}
1709
1710fn test() {
1711 let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo);
1712 let r1 = lazy1.foo();
1713
1714 fn make_foo_fn() -> Foo {}
1715 let make_foo_fn_ptr: fn() -> Foo = make_foo_fn;
1716 let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr);
1717 let r2 = lazy2.foo();
1718}
1719"#),
1720 @r###"
172165..69 'self': &Self
1722166..170 'self': Self
1723172..176 'args': Args
1724240..244 'self': &Foo
1725255..257 '{}': ()
1726335..336 'f': F
1727355..357 '{}': ()
1728444..690 '{ ...o(); }': ()
1729454..459 'lazy1': Lazy<Foo, fn() -> T>
1730476..485 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T>
1731476..493 'Lazy::...| Foo)': Lazy<Foo, fn() -> T>
1732486..492 '|| Foo': || -> T
1733489..492 'Foo': Foo
1734503..505 'r1': {unknown}
1735508..513 'lazy1': Lazy<Foo, fn() -> T>
1736508..519 'lazy1.foo()': {unknown}
1737561..576 'make_foo_fn_ptr': fn() -> Foo
1738592..603 'make_foo_fn': fn make_foo_fn() -> Foo
1739613..618 'lazy2': Lazy<Foo, fn() -> T>
1740635..644 'Lazy::new': fn new<Foo, fn() -> T>(fn() -> T) -> Lazy<Foo, fn() -> T>
1741635..661 'Lazy::...n_ptr)': Lazy<Foo, fn() -> T>
1742645..660 'make_foo_fn_ptr': fn() -> Foo
1743671..673 'r2': {unknown}
1744676..681 'lazy2': Lazy<Foo, fn() -> T>
1745676..687 'lazy2.foo()': {unknown}
1746550..552 '{}': ()
1747"###
1748 );
1749}
1750
1751#[test]
1620fn closure_1() { 1752fn closure_1() {
1621 assert_snapshot!( 1753 assert_snapshot!(
1622 infer(r#" 1754 infer(r#"
@@ -2055,7 +2187,7 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() {
2055#[test] 2187#[test]
2056fn proc_macro_server_types() { 2188fn proc_macro_server_types() {
2057 assert_snapshot!( 2189 assert_snapshot!(
2058 infer_with_mismatches(r#" 2190 infer(r#"
2059macro_rules! with_api { 2191macro_rules! with_api {
2060 ($S:ident, $self:ident, $m:ident) => { 2192 ($S:ident, $self:ident, $m:ident) => {
2061 $m! { 2193 $m! {
@@ -2069,9 +2201,9 @@ macro_rules! with_api {
2069} 2201}
2070macro_rules! associated_item { 2202macro_rules! associated_item {
2071 (type TokenStream) => 2203 (type TokenStream) =>
2072 (type TokenStream: 'static + Clone;); 2204 (type TokenStream: 'static;);
2073 (type Group) => 2205 (type Group) =>
2074 (type Group: 'static + Clone;); 2206 (type Group: 'static;);
2075 ($($item:tt)*) => ($($item)*;) 2207 ($($item:tt)*) => ($($item)*;)
2076} 2208}
2077macro_rules! declare_server_traits { 2209macro_rules! declare_server_traits {
@@ -2083,21 +2215,23 @@ macro_rules! declare_server_traits {
2083 } 2215 }
2084 2216
2085 $(pub trait $name: Types { 2217 $(pub trait $name: Types {
2086 $(associated_item!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)* 2218 $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)*
2087 })* 2219 })*
2088 2220
2089 pub trait Server: Types $(+ $name)* {} 2221 pub trait Server: Types $(+ $name)* {}
2090 impl<S: Types $(+ $name)*> Server for S {} 2222 impl<S: Types $(+ $name)*> Server for S {}
2091 } 2223 }
2092} 2224}
2225
2093with_api!(Self, self_, declare_server_traits); 2226with_api!(Self, self_, declare_server_traits);
2094struct Group {} 2227struct G {}
2095struct TokenStream {} 2228struct T {}
2096struct Rustc; 2229struct Rustc;
2097impl Types for Rustc { 2230impl Types for Rustc {
2098 type TokenStream = TokenStream; 2231 type TokenStream = T;
2099 type Group = Group; 2232 type Group = G;
2100} 2233}
2234
2101fn make<T>() -> T { loop {} } 2235fn make<T>() -> T { loop {} }
2102impl TokenStream for Rustc { 2236impl TokenStream for Rustc {
2103 fn new() -> Self::TokenStream { 2237 fn new() -> Self::TokenStream {
@@ -2105,17 +2239,17 @@ impl TokenStream for Rustc {
2105 make() 2239 make()
2106 } 2240 }
2107} 2241}
2108"#, true), 2242"#),
2109 @r###" 2243 @r###"
2110 1115..1126 '{ loop {} }': T 2244 1062..1073 '{ loop {} }': T
2111 1117..1124 'loop {}': ! 2245 1064..1071 'loop {}': !
2112 1122..1124 '{}': () 2246 1069..1071 '{}': ()
2113 1190..1253 '{ ... }': {unknown} 2247 1137..1200 '{ ... }': T
2114 1204..1209 'group': {unknown} 2248 1151..1156 'group': G
2115 1225..1229 'make': fn make<{unknown}>() -> {unknown} 2249 1172..1176 'make': fn make<G>() -> G
2116 1225..1231 'make()': {unknown} 2250 1172..1178 'make()': G
2117 1241..1245 'make': fn make<{unknown}>() -> {unknown} 2251 1188..1192 'make': fn make<T>() -> T
2118 1241..1247 'make()': {unknown} 2252 1188..1194 'make()': T
2119 "### 2253 "###
2120 ); 2254 );
2121} 2255}
@@ -2468,3 +2602,199 @@ fn test(x: &dyn Foo) {
2468 "### 2602 "###
2469 ); 2603 );
2470} 2604}
2605
2606#[test]
2607fn builtin_copy() {
2608 assert_snapshot!(
2609 infer_with_mismatches(r#"
2610#[lang = "copy"]
2611trait Copy {}
2612
2613struct IsCopy;
2614impl Copy for IsCopy {}
2615struct NotCopy;
2616
2617trait Test { fn test(&self) -> bool; }
2618impl<T: Copy> Test for T {}
2619
2620fn test() {
2621 IsCopy.test();
2622 NotCopy.test();
2623 (IsCopy, IsCopy).test();
2624 (IsCopy, NotCopy).test();
2625}
2626"#, true),
2627 @r###"
2628 111..115 'self': &Self
2629 167..268 '{ ...t(); }': ()
2630 173..179 'IsCopy': IsCopy
2631 173..186 'IsCopy.test()': bool
2632 192..199 'NotCopy': NotCopy
2633 192..206 'NotCopy.test()': {unknown}
2634 212..228 '(IsCop...sCopy)': (IsCopy, IsCopy)
2635 212..235 '(IsCop...test()': bool
2636 213..219 'IsCopy': IsCopy
2637 221..227 'IsCopy': IsCopy
2638 241..258 '(IsCop...tCopy)': (IsCopy, NotCopy)
2639 241..265 '(IsCop...test()': {unknown}
2640 242..248 'IsCopy': IsCopy
2641 250..257 'NotCopy': NotCopy
2642 "###
2643 );
2644}
2645
2646#[test]
2647fn builtin_fn_def_copy() {
2648 assert_snapshot!(
2649 infer_with_mismatches(r#"
2650#[lang = "copy"]
2651trait Copy {}
2652
2653fn foo() {}
2654fn bar<T: Copy>(T) -> T {}
2655struct Struct(usize);
2656enum Enum { Variant(usize) }
2657
2658trait Test { fn test(&self) -> bool; }
2659impl<T: Copy> Test for T {}
2660
2661fn test() {
2662 foo.test();
2663 bar.test();
2664 Struct.test();
2665 Enum::Variant.test();
2666}
2667"#, true),
2668 @r###"
2669 42..44 '{}': ()
2670 61..62 'T': {unknown}
2671 69..71 '{}': ()
2672 69..71: expected T, got ()
2673 146..150 'self': &Self
2674 202..282 '{ ...t(); }': ()
2675 208..211 'foo': fn foo()
2676 208..218 'foo.test()': bool
2677 224..227 'bar': fn bar<{unknown}>({unknown}) -> {unknown}
2678 224..234 'bar.test()': bool
2679 240..246 'Struct': Struct(usize) -> Struct
2680 240..253 'Struct.test()': bool
2681 259..272 'Enum::Variant': Variant(usize) -> Enum
2682 259..279 'Enum::...test()': bool
2683 "###
2684 );
2685}
2686
2687#[test]
2688fn builtin_fn_ptr_copy() {
2689 assert_snapshot!(
2690 infer_with_mismatches(r#"
2691#[lang = "copy"]
2692trait Copy {}
2693
2694trait Test { fn test(&self) -> bool; }
2695impl<T: Copy> Test for T {}
2696
2697fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2698 f1.test();
2699 f2.test();
2700 f3.test();
2701}
2702"#, true),
2703 @r###"
2704 55..59 'self': &Self
2705 109..111 'f1': fn()
2706 119..121 'f2': fn(usize) -> u8
2707 140..142 'f3': fn(u8, u8) -> &u8
2708 163..211 '{ ...t(); }': ()
2709 169..171 'f1': fn()
2710 169..178 'f1.test()': bool
2711 184..186 'f2': fn(usize) -> u8
2712 184..193 'f2.test()': bool
2713 199..201 'f3': fn(u8, u8) -> &u8
2714 199..208 'f3.test()': bool
2715 "###
2716 );
2717}
2718
2719#[test]
2720fn builtin_sized() {
2721 assert_snapshot!(
2722 infer_with_mismatches(r#"
2723#[lang = "sized"]
2724trait Sized {}
2725
2726trait Test { fn test(&self) -> bool; }
2727impl<T: Sized> Test for T {}
2728
2729fn test() {
2730 1u8.test();
2731 (*"foo").test(); // not Sized
2732 (1u8, 1u8).test();
2733 (1u8, *"foo").test(); // not Sized
2734}
2735"#, true),
2736 @r###"
2737 57..61 'self': &Self
2738 114..229 '{ ...ized }': ()
2739 120..123 '1u8': u8
2740 120..130 '1u8.test()': bool
2741 136..151 '(*"foo").test()': {unknown}
2742 137..143 '*"foo"': str
2743 138..143 '"foo"': &str
2744 170..180 '(1u8, 1u8)': (u8, u8)
2745 170..187 '(1u8, ...test()': bool
2746 171..174 '1u8': u8
2747 176..179 '1u8': u8
2748 193..206 '(1u8, *"foo")': (u8, str)
2749 193..213 '(1u8, ...test()': {unknown}
2750 194..197 '1u8': u8
2751 199..205 '*"foo"': str
2752 200..205 '"foo"': &str
2753 "###
2754 );
2755}
2756
2757#[test]
2758fn integer_range_iterate() {
2759 let t = type_at(
2760 r#"
2761//- /main.rs crate:main deps:std
2762fn test() {
2763 for x in 0..100 { x<|>; }
2764}
2765
2766//- /std.rs crate:std
2767pub mod ops {
2768 pub struct Range<Idx> {
2769 pub start: Idx,
2770 pub end: Idx,
2771 }
2772}
2773
2774pub mod iter {
2775 pub trait Iterator {
2776 type Item;
2777 }
2778
2779 pub trait IntoIterator {
2780 type Item;
2781 type IntoIter: Iterator<Item = Self::Item>;
2782 }
2783
2784 impl<T> IntoIterator for T where T: Iterator {
2785 type Item = <T as Iterator>::Item;
2786 type IntoIter = Self;
2787 }
2788}
2789
2790trait Step {}
2791impl Step for i32 {}
2792impl Step for i64 {}
2793
2794impl<A: Step> iter::Iterator for ops::Range<A> {
2795 type Item = A;
2796}
2797"#,
2798 );
2799 assert_eq!(t, "i32");
2800}