aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/tests/simple.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-08-13 15:35:29 +0100
committerAleksey Kladov <[email protected]>2020-08-13 15:35:29 +0100
commit6a77ec7bbe6ddbf663dce9529d11d1bb56c5489a (patch)
treeb6e3d7e0109eb82bca75b5ebc35a7d723542b8dd /crates/ra_hir_ty/src/tests/simple.rs
parent50f8c1ebf23f634b68529603a917e3feeda457fa (diff)
Rename ra_hir_ty -> hir_ty
Diffstat (limited to 'crates/ra_hir_ty/src/tests/simple.rs')
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs2218
1 files changed, 0 insertions, 2218 deletions
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
deleted file mode 100644
index 59eb59d5f..000000000
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ /dev/null
@@ -1,2218 +0,0 @@
1use expect::expect;
2
3use super::{check_infer, check_types};
4
5#[test]
6fn infer_box() {
7 check_types(
8 r#"
9//- /main.rs crate:main deps:std
10fn test() {
11 let x = box 1;
12 let t = (x, box x, box &1, box [1]);
13 t;
14} //^ (Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32; _]>)
15
16//- /std.rs crate:std
17#[prelude_import] use prelude::*;
18mod prelude {}
19
20mod boxed {
21 #[lang = "owned_box"]
22 pub struct Box<T: ?Sized> {
23 inner: *mut T,
24 }
25}
26"#,
27 );
28}
29
30#[test]
31fn infer_adt_self() {
32 check_types(
33 r#"
34enum Nat { Succ(Self), Demo(Nat), Zero }
35
36fn test() {
37 let foo: Nat = Nat::Zero;
38 if let Nat::Succ(x) = foo {
39 x
40 } //^ Nat
41}
42"#,
43 );
44}
45
46#[test]
47fn self_in_struct_lit() {
48 check_infer(
49 r#"
50 //- /main.rs
51 struct S<T> { x: T }
52
53 impl S<u32> {
54 fn foo() {
55 Self { x: 1 };
56 }
57 }
58 "#,
59 expect![[r#"
60 49..79 '{ ... }': ()
61 59..72 'Self { x: 1 }': S<u32>
62 69..70 '1': u32
63 "#]],
64 );
65}
66
67#[test]
68fn type_alias_in_struct_lit() {
69 check_infer(
70 r#"
71 //- /main.rs
72 struct S<T> { x: T }
73
74 type SS = S<u32>;
75
76 fn foo() {
77 SS { x: 1 };
78 }
79 "#,
80 expect![[r#"
81 50..70 '{ ...1 }; }': ()
82 56..67 'SS { x: 1 }': S<u32>
83 64..65 '1': u32
84 "#]],
85 );
86}
87
88#[test]
89fn infer_ranges() {
90 check_types(
91 r#"
92//- /main.rs crate:main deps:core
93fn test() {
94 let a = ..;
95 let b = 1..;
96 let c = ..2u32;
97 let d = 1..2usize;
98 let e = ..=10;
99 let f = 'a'..='z';
100
101 let t = (a, b, c, d, e, f);
102 t;
103} //^ (RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)
104
105//- /core.rs crate:core
106#[prelude_import] use prelude::*;
107mod prelude {}
108
109pub mod ops {
110 pub struct Range<Idx> {
111 pub start: Idx,
112 pub end: Idx,
113 }
114 pub struct RangeFrom<Idx> {
115 pub start: Idx,
116 }
117 struct RangeFull;
118 pub struct RangeInclusive<Idx> {
119 start: Idx,
120 end: Idx,
121 is_empty: u8,
122 }
123 pub struct RangeTo<Idx> {
124 pub end: Idx,
125 }
126 pub struct RangeToInclusive<Idx> {
127 pub end: Idx,
128 }
129}
130"#,
131 );
132}
133
134#[test]
135fn infer_while_let() {
136 check_types(
137 r#"
138enum Option<T> { Some(T), None }
139
140fn test() {
141 let foo: Option<f32> = None;
142 while let Option::Some(x) = foo {
143 x
144 } //^ f32
145}
146"#,
147 );
148}
149
150#[test]
151fn infer_basics() {
152 check_infer(
153 r#"
154 fn test(a: u32, b: isize, c: !, d: &str) {
155 a;
156 b;
157 c;
158 d;
159 1usize;
160 1isize;
161 "test";
162 1.0f32;
163 }"#,
164 expect![[r#"
165 8..9 'a': u32
166 16..17 'b': isize
167 26..27 'c': !
168 32..33 'd': &str
169 41..120 '{ ...f32; }': ()
170 47..48 'a': u32
171 54..55 'b': isize
172 61..62 'c': !
173 68..69 'd': &str
174 75..81 '1usize': usize
175 87..93 '1isize': isize
176 99..105 '"test"': &str
177 111..117 '1.0f32': f32
178 "#]],
179 );
180}
181
182#[test]
183fn infer_let() {
184 check_infer(
185 r#"
186 fn test() {
187 let a = 1isize;
188 let b: usize = 1;
189 let c = b;
190 let d: u32;
191 let e;
192 let f: i32 = e;
193 }
194 "#,
195 expect![[r#"
196 10..117 '{ ...= e; }': ()
197 20..21 'a': isize
198 24..30 '1isize': isize
199 40..41 'b': usize
200 51..52 '1': usize
201 62..63 'c': usize
202 66..67 'b': usize
203 77..78 'd': u32
204 93..94 'e': i32
205 104..105 'f': i32
206 113..114 'e': i32
207 "#]],
208 );
209}
210
211#[test]
212fn infer_paths() {
213 check_infer(
214 r#"
215 fn a() -> u32 { 1 }
216
217 mod b {
218 fn c() -> u32 { 1 }
219 }
220
221 fn test() {
222 a();
223 b::c();
224 }
225 "#,
226 expect![[r#"
227 14..19 '{ 1 }': u32
228 16..17 '1': u32
229 47..52 '{ 1 }': u32
230 49..50 '1': u32
231 66..90 '{ ...c(); }': ()
232 72..73 'a': fn a() -> u32
233 72..75 'a()': u32
234 81..85 'b::c': fn c() -> u32
235 81..87 'b::c()': u32
236 "#]],
237 );
238}
239
240#[test]
241fn infer_path_type() {
242 check_infer(
243 r#"
244 struct S;
245
246 impl S {
247 fn foo() -> i32 { 1 }
248 }
249
250 fn test() {
251 S::foo();
252 <S>::foo();
253 }
254 "#,
255 expect![[r#"
256 40..45 '{ 1 }': i32
257 42..43 '1': i32
258 59..92 '{ ...o(); }': ()
259 65..71 'S::foo': fn foo() -> i32
260 65..73 'S::foo()': i32
261 79..87 '<S>::foo': fn foo() -> i32
262 79..89 '<S>::foo()': i32
263 "#]],
264 );
265}
266
267#[test]
268fn infer_struct() {
269 check_infer(
270 r#"
271 struct A {
272 b: B,
273 c: C,
274 }
275 struct B;
276 struct C(usize);
277
278 fn test() {
279 let c = C(1);
280 B;
281 let a: A = A { b: B, c: C(1) };
282 a.b;
283 a.c;
284 }
285 "#,
286 expect![[r#"
287 71..153 '{ ...a.c; }': ()
288 81..82 'c': C
289 85..86 'C': C(usize) -> C
290 85..89 'C(1)': C
291 87..88 '1': usize
292 95..96 'B': B
293 106..107 'a': A
294 113..132 'A { b:...C(1) }': A
295 120..121 'B': B
296 126..127 'C': C(usize) -> C
297 126..130 'C(1)': C
298 128..129 '1': usize
299 138..139 'a': A
300 138..141 'a.b': B
301 147..148 'a': A
302 147..150 'a.c': C
303 "#]],
304 );
305}
306
307#[test]
308fn infer_enum() {
309 check_infer(
310 r#"
311 enum E {
312 V1 { field: u32 },
313 V2
314 }
315 fn test() {
316 E::V1 { field: 1 };
317 E::V2;
318 }"#,
319 expect![[r#"
320 51..89 '{ ...:V2; }': ()
321 57..75 'E::V1 ...d: 1 }': E
322 72..73 '1': u32
323 81..86 'E::V2': E
324 "#]],
325 );
326}
327
328#[test]
329fn infer_union() {
330 check_infer(
331 r#"
332 union MyUnion {
333 foo: u32,
334 bar: f32,
335 }
336
337 fn test() {
338 let u = MyUnion { foo: 0 };
339 unsafe { baz(u); }
340 let u = MyUnion { bar: 0.0 };
341 unsafe { baz(u); }
342 }
343
344 unsafe fn baz(u: MyUnion) {
345 let inner = u.foo;
346 let inner = u.bar;
347 }
348 "#,
349 expect![[r#"
350 57..172 '{ ...); } }': ()
351 67..68 'u': MyUnion
352 71..89 'MyUnio...o: 0 }': MyUnion
353 86..87 '0': u32
354 95..113 'unsafe...(u); }': ()
355 102..113 '{ baz(u); }': ()
356 104..107 'baz': fn baz(MyUnion)
357 104..110 'baz(u)': ()
358 108..109 'u': MyUnion
359 122..123 'u': MyUnion
360 126..146 'MyUnio... 0.0 }': MyUnion
361 141..144 '0.0': f32
362 152..170 'unsafe...(u); }': ()
363 159..170 '{ baz(u); }': ()
364 161..164 'baz': fn baz(MyUnion)
365 161..167 'baz(u)': ()
366 165..166 'u': MyUnion
367 188..189 'u': MyUnion
368 200..249 '{ ...bar; }': ()
369 210..215 'inner': u32
370 218..219 'u': MyUnion
371 218..223 'u.foo': u32
372 233..238 'inner': f32
373 241..242 'u': MyUnion
374 241..246 'u.bar': f32
375 "#]],
376 );
377}
378
379#[test]
380fn infer_refs() {
381 check_infer(
382 r#"
383 fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
384 a;
385 *a;
386 &a;
387 &mut a;
388 b;
389 *b;
390 &b;
391 c;
392 *c;
393 d;
394 *d;
395 }
396 "#,
397 expect![[r#"
398 8..9 'a': &u32
399 17..18 'b': &mut u32
400 30..31 'c': *const u32
401 45..46 'd': *mut u32
402 58..149 '{ ... *d; }': ()
403 64..65 'a': &u32
404 71..73 '*a': u32
405 72..73 'a': &u32
406 79..81 '&a': &&u32
407 80..81 'a': &u32
408 87..93 '&mut a': &mut &u32
409 92..93 'a': &u32
410 99..100 'b': &mut u32
411 106..108 '*b': u32
412 107..108 'b': &mut u32
413 114..116 '&b': &&mut u32
414 115..116 'b': &mut u32
415 122..123 'c': *const u32
416 129..131 '*c': u32
417 130..131 'c': *const u32
418 137..138 'd': *mut u32
419 144..146 '*d': u32
420 145..146 'd': *mut u32
421 "#]],
422 );
423}
424
425#[test]
426fn infer_raw_ref() {
427 check_infer(
428 r#"
429 fn test(a: i32) {
430 &raw mut a;
431 &raw const a;
432 }
433 "#,
434 expect![[r#"
435 8..9 'a': i32
436 16..53 '{ ...t a; }': ()
437 22..32 '&raw mut a': *mut i32
438 31..32 'a': i32
439 38..50 '&raw const a': *const i32
440 49..50 'a': i32
441 "#]],
442 );
443}
444
445#[test]
446fn infer_literals() {
447 check_infer(
448 r##"
449 fn test() {
450 5i32;
451 5f32;
452 5f64;
453 "hello";
454 b"bytes";
455 'c';
456 b'b';
457 3.14;
458 5000;
459 false;
460 true;
461 r#"
462 //! doc
463 // non-doc
464 mod foo {}
465 "#;
466 br#"yolo"#;
467 }
468 "##,
469 expect![[r##"
470 10..216 '{ ...o"#; }': ()
471 16..20 '5i32': i32
472 26..30 '5f32': f32
473 36..40 '5f64': f64
474 46..53 '"hello"': &str
475 59..67 'b"bytes"': &[u8; _]
476 73..76 ''c'': char
477 82..86 'b'b'': u8
478 92..96 '3.14': f64
479 102..106 '5000': i32
480 112..117 'false': bool
481 123..127 'true': bool
482 133..197 'r#" ... "#': &str
483 203..213 'br#"yolo"#': &[u8; _]
484 "##]],
485 );
486}
487
488#[test]
489fn infer_unary_op() {
490 check_infer(
491 r#"
492 enum SomeType {}
493
494 fn test(x: SomeType) {
495 let b = false;
496 let c = !b;
497 let a = 100;
498 let d: i128 = -a;
499 let e = -100;
500 let f = !!!true;
501 let g = !42;
502 let h = !10u32;
503 let j = !a;
504 -3.14;
505 !3;
506 -x;
507 !x;
508 -"hello";
509 !"hello";
510 }
511 "#,
512 expect![[r#"
513 26..27 'x': SomeType
514 39..271 '{ ...lo"; }': ()
515 49..50 'b': bool
516 53..58 'false': bool
517 68..69 'c': bool
518 72..74 '!b': bool
519 73..74 'b': bool
520 84..85 'a': i128
521 88..91 '100': i128
522 101..102 'd': i128
523 111..113 '-a': i128
524 112..113 'a': i128
525 123..124 'e': i32
526 127..131 '-100': i32
527 128..131 '100': i32
528 141..142 'f': bool
529 145..152 '!!!true': bool
530 146..152 '!!true': bool
531 147..152 '!true': bool
532 148..152 'true': bool
533 162..163 'g': i32
534 166..169 '!42': i32
535 167..169 '42': i32
536 179..180 'h': u32
537 183..189 '!10u32': u32
538 184..189 '10u32': u32
539 199..200 'j': i128
540 203..205 '!a': i128
541 204..205 'a': i128
542 211..216 '-3.14': f64
543 212..216 '3.14': f64
544 222..224 '!3': i32
545 223..224 '3': i32
546 230..232 '-x': {unknown}
547 231..232 'x': SomeType
548 238..240 '!x': {unknown}
549 239..240 'x': SomeType
550 246..254 '-"hello"': {unknown}
551 247..254 '"hello"': &str
552 260..268 '!"hello"': {unknown}
553 261..268 '"hello"': &str
554 "#]],
555 );
556}
557
558#[test]
559fn infer_backwards() {
560 check_infer(
561 r#"
562 fn takes_u32(x: u32) {}
563
564 struct S { i32_field: i32 }
565
566 fn test() -> &mut &f64 {
567 let a = unknown_function();
568 takes_u32(a);
569 let b = unknown_function();
570 S { i32_field: b };
571 let c = unknown_function();
572 &mut &c
573 }
574 "#,
575 expect![[r#"
576 13..14 'x': u32
577 21..23 '{}': ()
578 77..230 '{ ...t &c }': &mut &f64
579 87..88 'a': u32
580 91..107 'unknow...nction': {unknown}
581 91..109 'unknow...tion()': u32
582 115..124 'takes_u32': fn takes_u32(u32)
583 115..127 'takes_u32(a)': ()
584 125..126 'a': u32
585 137..138 'b': i32
586 141..157 'unknow...nction': {unknown}
587 141..159 'unknow...tion()': i32
588 165..183 'S { i3...d: b }': S
589 180..181 'b': i32
590 193..194 'c': f64
591 197..213 'unknow...nction': {unknown}
592 197..215 'unknow...tion()': f64
593 221..228 '&mut &c': &mut &f64
594 226..228 '&c': &f64
595 227..228 'c': f64
596 "#]],
597 );
598}
599
600#[test]
601fn infer_self() {
602 check_infer(
603 r#"
604 struct S;
605
606 impl S {
607 fn test(&self) {
608 self;
609 }
610 fn test2(self: &Self) {
611 self;
612 }
613 fn test3() -> Self {
614 S {}
615 }
616 fn test4() -> Self {
617 Self {}
618 }
619 }
620 "#,
621 expect![[r#"
622 33..37 'self': &S
623 39..60 '{ ... }': ()
624 49..53 'self': &S
625 74..78 'self': &S
626 87..108 '{ ... }': ()
627 97..101 'self': &S
628 132..152 '{ ... }': S
629 142..146 'S {}': S
630 176..199 '{ ... }': S
631 186..193 'Self {}': S
632 "#]],
633 );
634}
635
636#[test]
637fn infer_self_as_path() {
638 check_infer(
639 r#"
640 struct S1;
641 struct S2(isize);
642 enum E {
643 V1,
644 V2(u32),
645 }
646
647 impl S1 {
648 fn test() {
649 Self;
650 }
651 }
652 impl S2 {
653 fn test() {
654 Self(1);
655 }
656 }
657 impl E {
658 fn test() {
659 Self::V1;
660 Self::V2(1);
661 }
662 }
663 "#,
664 expect![[r#"
665 86..107 '{ ... }': ()
666 96..100 'Self': S1
667 134..158 '{ ... }': ()
668 144..148 'Self': S2(isize) -> S2
669 144..151 'Self(1)': S2
670 149..150 '1': isize
671 184..230 '{ ... }': ()
672 194..202 'Self::V1': E
673 212..220 'Self::V2': V2(u32) -> E
674 212..223 'Self::V2(1)': E
675 221..222 '1': u32
676 "#]],
677 );
678}
679
680#[test]
681fn infer_binary_op() {
682 check_infer(
683 r#"
684 fn f(x: bool) -> i32 {
685 0i32
686 }
687
688 fn test() -> bool {
689 let x = a && b;
690 let y = true || false;
691 let z = x == y;
692 let t = x != y;
693 let minus_forty: isize = -40isize;
694 let h = minus_forty <= CONST_2;
695 let c = f(z || y) + 5;
696 let d = b;
697 let g = minus_forty ^= i;
698 let ten: usize = 10;
699 let ten_is_eleven = ten == some_num;
700
701 ten < 3
702 }
703 "#,
704 expect![[r#"
705 5..6 'x': bool
706 21..33 '{ 0i32 }': i32
707 27..31 '0i32': i32
708 53..369 '{ ... < 3 }': bool
709 63..64 'x': bool
710 67..68 'a': bool
711 67..73 'a && b': bool
712 72..73 'b': bool
713 83..84 'y': bool
714 87..91 'true': bool
715 87..100 'true || false': bool
716 95..100 'false': bool
717 110..111 'z': bool
718 114..115 'x': bool
719 114..120 'x == y': bool
720 119..120 'y': bool
721 130..131 't': bool
722 134..135 'x': bool
723 134..140 'x != y': bool
724 139..140 'y': bool
725 150..161 'minus_forty': isize
726 171..179 '-40isize': isize
727 172..179 '40isize': isize
728 189..190 'h': bool
729 193..204 'minus_forty': isize
730 193..215 'minus_...ONST_2': bool
731 208..215 'CONST_2': isize
732 225..226 'c': i32
733 229..230 'f': fn f(bool) -> i32
734 229..238 'f(z || y)': i32
735 229..242 'f(z || y) + 5': i32
736 231..232 'z': bool
737 231..237 'z || y': bool
738 236..237 'y': bool
739 241..242 '5': i32
740 252..253 'd': {unknown}
741 256..257 'b': {unknown}
742 267..268 'g': ()
743 271..282 'minus_forty': isize
744 271..287 'minus_...y ^= i': ()
745 286..287 'i': isize
746 297..300 'ten': usize
747 310..312 '10': usize
748 322..335 'ten_is_eleven': bool
749 338..341 'ten': usize
750 338..353 'ten == some_num': bool
751 345..353 'some_num': usize
752 360..363 'ten': usize
753 360..367 'ten < 3': bool
754 366..367 '3': usize
755 "#]],
756 );
757}
758
759#[test]
760fn infer_shift_op() {
761 check_infer(
762 r#"
763 fn test() {
764 1u32 << 5u8;
765 1u32 >> 5u8;
766 }
767 "#,
768 expect![[r#"
769 10..47 '{ ...5u8; }': ()
770 16..20 '1u32': u32
771 16..27 '1u32 << 5u8': u32
772 24..27 '5u8': u8
773 33..37 '1u32': u32
774 33..44 '1u32 >> 5u8': u32
775 41..44 '5u8': u8
776 "#]],
777 );
778}
779
780#[test]
781fn infer_field_autoderef() {
782 check_infer(
783 r#"
784 struct A {
785 b: B,
786 }
787 struct B;
788
789 fn test1(a: A) {
790 let a1 = a;
791 a1.b;
792 let a2 = &a;
793 a2.b;
794 let a3 = &mut a;
795 a3.b;
796 let a4 = &&&&&&&a;
797 a4.b;
798 let a5 = &mut &&mut &&mut a;
799 a5.b;
800 }
801
802 fn test2(a1: *const A, a2: *mut A) {
803 a1.b;
804 a2.b;
805 }
806 "#,
807 expect![[r#"
808 43..44 'a': A
809 49..212 '{ ...5.b; }': ()
810 59..61 'a1': A
811 64..65 'a': A
812 71..73 'a1': A
813 71..75 'a1.b': B
814 85..87 'a2': &A
815 90..92 '&a': &A
816 91..92 'a': A
817 98..100 'a2': &A
818 98..102 'a2.b': B
819 112..114 'a3': &mut A
820 117..123 '&mut a': &mut A
821 122..123 'a': A
822 129..131 'a3': &mut A
823 129..133 'a3.b': B
824 143..145 'a4': &&&&&&&A
825 148..156 '&&&&&&&a': &&&&&&&A
826 149..156 '&&&&&&a': &&&&&&A
827 150..156 '&&&&&a': &&&&&A
828 151..156 '&&&&a': &&&&A
829 152..156 '&&&a': &&&A
830 153..156 '&&a': &&A
831 154..156 '&a': &A
832 155..156 'a': A
833 162..164 'a4': &&&&&&&A
834 162..166 'a4.b': B
835 176..178 'a5': &mut &&mut &&mut A
836 181..199 '&mut &...&mut a': &mut &&mut &&mut A
837 186..199 '&&mut &&mut a': &&mut &&mut A
838 187..199 '&mut &&mut a': &mut &&mut A
839 192..199 '&&mut a': &&mut A
840 193..199 '&mut a': &mut A
841 198..199 'a': A
842 205..207 'a5': &mut &&mut &&mut A
843 205..209 'a5.b': B
844 223..225 'a1': *const A
845 237..239 'a2': *mut A
846 249..272 '{ ...2.b; }': ()
847 255..257 'a1': *const A
848 255..259 'a1.b': B
849 265..267 'a2': *mut A
850 265..269 'a2.b': B
851 "#]],
852 );
853}
854
855#[test]
856fn infer_argument_autoderef() {
857 check_infer(
858 r#"
859 #[lang = "deref"]
860 pub trait Deref {
861 type Target;
862 fn deref(&self) -> &Self::Target;
863 }
864
865 struct A<T>(T);
866
867 impl<T> A<T> {
868 fn foo(&self) -> &T {
869 &self.0
870 }
871 }
872
873 struct B<T>(T);
874
875 impl<T> Deref for B<T> {
876 type Target = T;
877 fn deref(&self) -> &Self::Target {
878 &self.0
879 }
880 }
881
882 fn test() {
883 let t = A::foo(&&B(B(A(42))));
884 }
885 "#,
886 expect![[r#"
887 67..71 'self': &Self
888 138..142 'self': &A<T>
889 150..173 '{ ... }': &T
890 160..167 '&self.0': &T
891 161..165 'self': &A<T>
892 161..167 'self.0': T
893 254..258 'self': &B<T>
894 277..300 '{ ... }': &T
895 287..294 '&self.0': &T
896 288..292 'self': &B<T>
897 288..294 'self.0': T
898 314..352 '{ ...))); }': ()
899 324..325 't': &i32
900 328..334 'A::foo': fn foo<i32>(&A<i32>) -> &i32
901 328..349 'A::foo...42))))': &i32
902 335..348 '&&B(B(A(42)))': &&B<B<A<i32>>>
903 336..348 '&B(B(A(42)))': &B<B<A<i32>>>
904 337..338 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
905 337..348 'B(B(A(42)))': B<B<A<i32>>>
906 339..340 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
907 339..347 'B(A(42))': B<A<i32>>
908 341..342 'A': A<i32>(i32) -> A<i32>
909 341..346 'A(42)': A<i32>
910 343..345 '42': i32
911 "#]],
912 );
913}
914
915#[test]
916fn infer_method_argument_autoderef() {
917 check_infer(
918 r#"
919 #[lang = "deref"]
920 pub trait Deref {
921 type Target;
922 fn deref(&self) -> &Self::Target;
923 }
924
925 struct A<T>(*mut T);
926
927 impl<T> A<T> {
928 fn foo(&self, x: &A<T>) -> &T {
929 &*x.0
930 }
931 }
932
933 struct B<T>(T);
934
935 impl<T> Deref for B<T> {
936 type Target = T;
937 fn deref(&self) -> &Self::Target {
938 &self.0
939 }
940 }
941
942 fn test(a: A<i32>) {
943 let t = A(0 as *mut _).foo(&&B(B(a)));
944 }
945 "#,
946 expect![[r#"
947 67..71 'self': &Self
948 143..147 'self': &A<T>
949 149..150 'x': &A<T>
950 165..186 '{ ... }': &T
951 175..180 '&*x.0': &T
952 176..180 '*x.0': T
953 177..178 'x': &A<T>
954 177..180 'x.0': *mut T
955 267..271 'self': &B<T>
956 290..313 '{ ... }': &T
957 300..307 '&self.0': &T
958 301..305 'self': &B<T>
959 301..307 'self.0': T
960 325..326 'a': A<i32>
961 336..382 '{ ...))); }': ()
962 346..347 't': &i32
963 350..351 'A': A<i32>(*mut i32) -> A<i32>
964 350..364 'A(0 as *mut _)': A<i32>
965 350..379 'A(0 as...B(a)))': &i32
966 352..353 '0': i32
967 352..363 '0 as *mut _': *mut i32
968 369..378 '&&B(B(a))': &&B<B<A<i32>>>
969 370..378 '&B(B(a))': &B<B<A<i32>>>
970 371..372 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
971 371..378 'B(B(a))': B<B<A<i32>>>
972 373..374 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
973 373..377 'B(a)': B<A<i32>>
974 375..376 'a': A<i32>
975 "#]],
976 );
977}
978
979#[test]
980fn infer_in_elseif() {
981 check_infer(
982 r#"
983 struct Foo { field: i32 }
984 fn main(foo: Foo) {
985 if true {
986
987 } else if false {
988 foo.field
989 }
990 }
991 "#,
992 expect![[r#"
993 34..37 'foo': Foo
994 44..108 '{ ... } }': ()
995 50..106 'if tru... }': ()
996 53..57 'true': bool
997 58..66 '{ }': ()
998 72..106 'if fal... }': i32
999 75..80 'false': bool
1000 81..106 '{ ... }': i32
1001 91..94 'foo': Foo
1002 91..100 'foo.field': i32
1003 "#]],
1004 )
1005}
1006
1007#[test]
1008fn infer_if_match_with_return() {
1009 check_infer(
1010 r#"
1011 fn foo() {
1012 let _x1 = if true {
1013 1
1014 } else {
1015 return;
1016 };
1017 let _x2 = if true {
1018 2
1019 } else {
1020 return
1021 };
1022 let _x3 = match true {
1023 true => 3,
1024 _ => {
1025 return;
1026 }
1027 };
1028 let _x4 = match true {
1029 true => 4,
1030 _ => return
1031 };
1032 }"#,
1033 expect![[r#"
1034 9..322 '{ ... }; }': ()
1035 19..22 '_x1': i32
1036 25..79 'if tru... }': i32
1037 28..32 'true': bool
1038 33..50 '{ ... }': i32
1039 43..44 '1': i32
1040 56..79 '{ ... }': i32
1041 66..72 'return': !
1042 89..92 '_x2': i32
1043 95..148 'if tru... }': i32
1044 98..102 'true': bool
1045 103..120 '{ ... }': i32
1046 113..114 '2': i32
1047 126..148 '{ ... }': !
1048 136..142 'return': !
1049 158..161 '_x3': i32
1050 164..246 'match ... }': i32
1051 170..174 'true': bool
1052 185..189 'true': bool
1053 185..189 'true': bool
1054 193..194 '3': i32
1055 204..205 '_': bool
1056 209..240 '{ ... }': i32
1057 223..229 'return': !
1058 256..259 '_x4': i32
1059 262..319 'match ... }': i32
1060 268..272 'true': bool
1061 283..287 'true': bool
1062 283..287 'true': bool
1063 291..292 '4': i32
1064 302..303 '_': bool
1065 307..313 'return': !
1066 "#]],
1067 )
1068}
1069
1070#[test]
1071fn infer_inherent_method() {
1072 check_infer(
1073 r#"
1074 struct A;
1075
1076 impl A {
1077 fn foo(self, x: u32) -> i32 {}
1078 }
1079
1080 mod b {
1081 impl super::A {
1082 fn bar(&self, x: u64) -> i64 {}
1083 }
1084 }
1085
1086 fn test(a: A) {
1087 a.foo(1);
1088 (&a).bar(1);
1089 a.bar(1);
1090 }
1091 "#,
1092 expect![[r#"
1093 31..35 'self': A
1094 37..38 'x': u32
1095 52..54 '{}': ()
1096 102..106 'self': &A
1097 108..109 'x': u64
1098 123..125 '{}': ()
1099 143..144 'a': A
1100 149..197 '{ ...(1); }': ()
1101 155..156 'a': A
1102 155..163 'a.foo(1)': i32
1103 161..162 '1': u32
1104 169..180 '(&a).bar(1)': i64
1105 170..172 '&a': &A
1106 171..172 'a': A
1107 178..179 '1': u64
1108 186..187 'a': A
1109 186..194 'a.bar(1)': i64
1110 192..193 '1': u64
1111 "#]],
1112 );
1113}
1114
1115#[test]
1116fn infer_inherent_method_str() {
1117 check_infer(
1118 r#"
1119 #[lang = "str"]
1120 impl str {
1121 fn foo(&self) -> i32 {}
1122 }
1123
1124 fn test() {
1125 "foo".foo();
1126 }
1127 "#,
1128 expect![[r#"
1129 39..43 'self': &str
1130 52..54 '{}': ()
1131 68..88 '{ ...o(); }': ()
1132 74..79 '"foo"': &str
1133 74..85 '"foo".foo()': i32
1134 "#]],
1135 );
1136}
1137
1138#[test]
1139fn infer_tuple() {
1140 check_infer(
1141 r#"
1142 fn test(x: &str, y: isize) {
1143 let a: (u32, &str) = (1, "a");
1144 let b = (a, x);
1145 let c = (y, x);
1146 let d = (c, x);
1147 let e = (1, "e");
1148 let f = (e, "d");
1149 }
1150 "#,
1151 expect![[r#"
1152 8..9 'x': &str
1153 17..18 'y': isize
1154 27..169 '{ ...d"); }': ()
1155 37..38 'a': (u32, &str)
1156 54..62 '(1, "a")': (u32, &str)
1157 55..56 '1': u32
1158 58..61 '"a"': &str
1159 72..73 'b': ((u32, &str), &str)
1160 76..82 '(a, x)': ((u32, &str), &str)
1161 77..78 'a': (u32, &str)
1162 80..81 'x': &str
1163 92..93 'c': (isize, &str)
1164 96..102 '(y, x)': (isize, &str)
1165 97..98 'y': isize
1166 100..101 'x': &str
1167 112..113 'd': ((isize, &str), &str)
1168 116..122 '(c, x)': ((isize, &str), &str)
1169 117..118 'c': (isize, &str)
1170 120..121 'x': &str
1171 132..133 'e': (i32, &str)
1172 136..144 '(1, "e")': (i32, &str)
1173 137..138 '1': i32
1174 140..143 '"e"': &str
1175 154..155 'f': ((i32, &str), &str)
1176 158..166 '(e, "d")': ((i32, &str), &str)
1177 159..160 'e': (i32, &str)
1178 162..165 '"d"': &str
1179 "#]],
1180 );
1181}
1182
1183#[test]
1184fn infer_array() {
1185 check_infer(
1186 r#"
1187 fn test(x: &str, y: isize) {
1188 let a = [x];
1189 let b = [a, a];
1190 let c = [b, b];
1191
1192 let d = [y, 1, 2, 3];
1193 let d = [1, y, 2, 3];
1194 let e = [y];
1195 let f = [d, d];
1196 let g = [e, e];
1197
1198 let h = [1, 2];
1199 let i = ["a", "b"];
1200
1201 let b = [a, ["b"]];
1202 let x: [u8; 0] = [];
1203 }
1204 "#,
1205 expect![[r#"
1206 8..9 'x': &str
1207 17..18 'y': isize
1208 27..292 '{ ... []; }': ()
1209 37..38 'a': [&str; _]
1210 41..44 '[x]': [&str; _]
1211 42..43 'x': &str
1212 54..55 'b': [[&str; _]; _]
1213 58..64 '[a, a]': [[&str; _]; _]
1214 59..60 'a': [&str; _]
1215 62..63 'a': [&str; _]
1216 74..75 'c': [[[&str; _]; _]; _]
1217 78..84 '[b, b]': [[[&str; _]; _]; _]
1218 79..80 'b': [[&str; _]; _]
1219 82..83 'b': [[&str; _]; _]
1220 95..96 'd': [isize; _]
1221 99..111 '[y, 1, 2, 3]': [isize; _]
1222 100..101 'y': isize
1223 103..104 '1': isize
1224 106..107 '2': isize
1225 109..110 '3': isize
1226 121..122 'd': [isize; _]
1227 125..137 '[1, y, 2, 3]': [isize; _]
1228 126..127 '1': isize
1229 129..130 'y': isize
1230 132..133 '2': isize
1231 135..136 '3': isize
1232 147..148 'e': [isize; _]
1233 151..154 '[y]': [isize; _]
1234 152..153 'y': isize
1235 164..165 'f': [[isize; _]; _]
1236 168..174 '[d, d]': [[isize; _]; _]
1237 169..170 'd': [isize; _]
1238 172..173 'd': [isize; _]
1239 184..185 'g': [[isize; _]; _]
1240 188..194 '[e, e]': [[isize; _]; _]
1241 189..190 'e': [isize; _]
1242 192..193 'e': [isize; _]
1243 205..206 'h': [i32; _]
1244 209..215 '[1, 2]': [i32; _]
1245 210..211 '1': i32
1246 213..214 '2': i32
1247 225..226 'i': [&str; _]
1248 229..239 '["a", "b"]': [&str; _]
1249 230..233 '"a"': &str
1250 235..238 '"b"': &str
1251 250..251 'b': [[&str; _]; _]
1252 254..264 '[a, ["b"]]': [[&str; _]; _]
1253 255..256 'a': [&str; _]
1254 258..263 '["b"]': [&str; _]
1255 259..262 '"b"': &str
1256 274..275 'x': [u8; _]
1257 287..289 '[]': [u8; _]
1258 "#]],
1259 );
1260}
1261
1262#[test]
1263fn infer_struct_generics() {
1264 check_infer(
1265 r#"
1266 struct A<T> {
1267 x: T,
1268 }
1269
1270 fn test(a1: A<u32>, i: i32) {
1271 a1.x;
1272 let a2 = A { x: i };
1273 a2.x;
1274 let a3 = A::<i128> { x: 1 };
1275 a3.x;
1276 }
1277 "#,
1278 expect![[r#"
1279 35..37 'a1': A<u32>
1280 47..48 'i': i32
1281 55..146 '{ ...3.x; }': ()
1282 61..63 'a1': A<u32>
1283 61..65 'a1.x': u32
1284 75..77 'a2': A<i32>
1285 80..90 'A { x: i }': A<i32>
1286 87..88 'i': i32
1287 96..98 'a2': A<i32>
1288 96..100 'a2.x': i32
1289 110..112 'a3': A<i128>
1290 115..133 'A::<i1...x: 1 }': A<i128>
1291 130..131 '1': i128
1292 139..141 'a3': A<i128>
1293 139..143 'a3.x': i128
1294 "#]],
1295 );
1296}
1297
1298#[test]
1299fn infer_tuple_struct_generics() {
1300 check_infer(
1301 r#"
1302 struct A<T>(T);
1303 enum Option<T> { Some(T), None }
1304 use Option::*;
1305
1306 fn test() {
1307 A(42);
1308 A(42u128);
1309 Some("x");
1310 Option::Some("x");
1311 None;
1312 let x: Option<i64> = None;
1313 }
1314 "#,
1315 expect![[r#"
1316 75..183 '{ ...one; }': ()
1317 81..82 'A': A<i32>(i32) -> A<i32>
1318 81..86 'A(42)': A<i32>
1319 83..85 '42': i32
1320 92..93 'A': A<u128>(u128) -> A<u128>
1321 92..101 'A(42u128)': A<u128>
1322 94..100 '42u128': u128
1323 107..111 'Some': Some<&str>(&str) -> Option<&str>
1324 107..116 'Some("x")': Option<&str>
1325 112..115 '"x"': &str
1326 122..134 'Option::Some': Some<&str>(&str) -> Option<&str>
1327 122..139 'Option...e("x")': Option<&str>
1328 135..138 '"x"': &str
1329 145..149 'None': Option<{unknown}>
1330 159..160 'x': Option<i64>
1331 176..180 'None': Option<i64>
1332 "#]],
1333 );
1334}
1335
1336#[test]
1337fn infer_function_generics() {
1338 check_infer(
1339 r#"
1340 fn id<T>(t: T) -> T { t }
1341
1342 fn test() {
1343 id(1u32);
1344 id::<i128>(1);
1345 let x: u64 = id(1);
1346 }
1347 "#,
1348 expect![[r#"
1349 9..10 't': T
1350 20..25 '{ t }': T
1351 22..23 't': T
1352 37..97 '{ ...(1); }': ()
1353 43..45 'id': fn id<u32>(u32) -> u32
1354 43..51 'id(1u32)': u32
1355 46..50 '1u32': u32
1356 57..67 'id::<i128>': fn id<i128>(i128) -> i128
1357 57..70 'id::<i128>(1)': i128
1358 68..69 '1': i128
1359 80..81 'x': u64
1360 89..91 'id': fn id<u64>(u64) -> u64
1361 89..94 'id(1)': u64
1362 92..93 '1': u64
1363 "#]],
1364 );
1365}
1366
1367#[test]
1368fn infer_impl_generics_basic() {
1369 check_infer(
1370 r#"
1371 struct A<T1, T2> {
1372 x: T1,
1373 y: T2,
1374 }
1375 impl<Y, X> A<X, Y> {
1376 fn x(self) -> X {
1377 self.x
1378 }
1379 fn y(self) -> Y {
1380 self.y
1381 }
1382 fn z<T>(self, t: T) -> (X, Y, T) {
1383 (self.x, self.y, t)
1384 }
1385 }
1386
1387 fn test() -> i128 {
1388 let a = A { x: 1u64, y: 1i64 };
1389 a.x();
1390 a.y();
1391 a.z(1i128);
1392 a.z::<u128>(1);
1393 }
1394 "#,
1395 expect![[r#"
1396 73..77 'self': A<X, Y>
1397 84..106 '{ ... }': X
1398 94..98 'self': A<X, Y>
1399 94..100 'self.x': X
1400 116..120 'self': A<X, Y>
1401 127..149 '{ ... }': Y
1402 137..141 'self': A<X, Y>
1403 137..143 'self.y': Y
1404 162..166 'self': A<X, Y>
1405 168..169 't': T
1406 187..222 '{ ... }': (X, Y, T)
1407 197..216 '(self.....y, t)': (X, Y, T)
1408 198..202 'self': A<X, Y>
1409 198..204 'self.x': X
1410 206..210 'self': A<X, Y>
1411 206..212 'self.y': Y
1412 214..215 't': T
1413 244..341 '{ ...(1); }': ()
1414 254..255 'a': A<u64, i64>
1415 258..280 'A { x:...1i64 }': A<u64, i64>
1416 265..269 '1u64': u64
1417 274..278 '1i64': i64
1418 286..287 'a': A<u64, i64>
1419 286..291 'a.x()': u64
1420 297..298 'a': A<u64, i64>
1421 297..302 'a.y()': i64
1422 308..309 'a': A<u64, i64>
1423 308..318 'a.z(1i128)': (u64, i64, i128)
1424 312..317 '1i128': i128
1425 324..325 'a': A<u64, i64>
1426 324..338 'a.z::<u128>(1)': (u64, i64, u128)
1427 336..337 '1': u128
1428 "#]],
1429 );
1430}
1431
1432#[test]
1433fn infer_impl_generics_with_autoderef() {
1434 check_infer(
1435 r#"
1436 enum Option<T> {
1437 Some(T),
1438 None,
1439 }
1440 impl<T> Option<T> {
1441 fn as_ref(&self) -> Option<&T> {}
1442 }
1443 fn test(o: Option<u32>) {
1444 (&o).as_ref();
1445 o.as_ref();
1446 }
1447 "#,
1448 expect![[r#"
1449 77..81 'self': &Option<T>
1450 97..99 '{}': ()
1451 110..111 'o': Option<u32>
1452 126..164 '{ ...f(); }': ()
1453 132..145 '(&o).as_ref()': Option<&u32>
1454 133..135 '&o': &Option<u32>
1455 134..135 'o': Option<u32>
1456 151..152 'o': Option<u32>
1457 151..161 'o.as_ref()': Option<&u32>
1458 "#]],
1459 );
1460}
1461
1462#[test]
1463fn infer_generic_chain() {
1464 check_infer(
1465 r#"
1466 struct A<T> {
1467 x: T,
1468 }
1469 impl<T2> A<T2> {
1470 fn x(self) -> T2 {
1471 self.x
1472 }
1473 }
1474 fn id<T>(t: T) -> T { t }
1475
1476 fn test() -> i128 {
1477 let x = 1;
1478 let y = id(x);
1479 let a = A { x: id(y) };
1480 let z = id(a.x);
1481 let b = A { x: z };
1482 b.x()
1483 }
1484 "#,
1485 expect![[r#"
1486 52..56 'self': A<T2>
1487 64..86 '{ ... }': T2
1488 74..78 'self': A<T2>
1489 74..80 'self.x': T2
1490 98..99 't': T
1491 109..114 '{ t }': T
1492 111..112 't': T
1493 134..254 '{ ....x() }': i128
1494 144..145 'x': i128
1495 148..149 '1': i128
1496 159..160 'y': i128
1497 163..165 'id': fn id<i128>(i128) -> i128
1498 163..168 'id(x)': i128
1499 166..167 'x': i128
1500 178..179 'a': A<i128>
1501 182..196 'A { x: id(y) }': A<i128>
1502 189..191 'id': fn id<i128>(i128) -> i128
1503 189..194 'id(y)': i128
1504 192..193 'y': i128
1505 206..207 'z': i128
1506 210..212 'id': fn id<i128>(i128) -> i128
1507 210..217 'id(a.x)': i128
1508 213..214 'a': A<i128>
1509 213..216 'a.x': i128
1510 227..228 'b': A<i128>
1511 231..241 'A { x: z }': A<i128>
1512 238..239 'z': i128
1513 247..248 'b': A<i128>
1514 247..252 'b.x()': i128
1515 "#]],
1516 );
1517}
1518
1519#[test]
1520fn infer_associated_const() {
1521 check_infer(
1522 r#"
1523 struct Struct;
1524
1525 impl Struct {
1526 const FOO: u32 = 1;
1527 }
1528
1529 enum Enum {}
1530
1531 impl Enum {
1532 const BAR: u32 = 2;
1533 }
1534
1535 trait Trait {
1536 const ID: u32;
1537 }
1538
1539 struct TraitTest;
1540
1541 impl Trait for TraitTest {
1542 const ID: u32 = 5;
1543 }
1544
1545 fn test() {
1546 let x = Struct::FOO;
1547 let y = Enum::BAR;
1548 let z = TraitTest::ID;
1549 }
1550 "#,
1551 expect![[r#"
1552 51..52 '1': u32
1553 104..105 '2': u32
1554 212..213 '5': u32
1555 228..306 '{ ...:ID; }': ()
1556 238..239 'x': u32
1557 242..253 'Struct::FOO': u32
1558 263..264 'y': u32
1559 267..276 'Enum::BAR': u32
1560 286..287 'z': u32
1561 290..303 'TraitTest::ID': u32
1562 "#]],
1563 );
1564}
1565
1566#[test]
1567fn infer_type_alias() {
1568 check_infer(
1569 r#"
1570 struct A<X, Y> { x: X, y: Y }
1571 type Foo = A<u32, i128>;
1572 type Bar<T> = A<T, u128>;
1573 type Baz<U, V> = A<V, U>;
1574 fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) {
1575 x.x;
1576 x.y;
1577 y.x;
1578 y.y;
1579 z.x;
1580 z.y;
1581 }
1582 "#,
1583 expect![[r#"
1584 115..116 'x': A<u32, i128>
1585 123..124 'y': A<&str, u128>
1586 137..138 'z': A<u8, i8>
1587 153..210 '{ ...z.y; }': ()
1588 159..160 'x': A<u32, i128>
1589 159..162 'x.x': u32
1590 168..169 'x': A<u32, i128>
1591 168..171 'x.y': i128
1592 177..178 'y': A<&str, u128>
1593 177..180 'y.x': &str
1594 186..187 'y': A<&str, u128>
1595 186..189 'y.y': u128
1596 195..196 'z': A<u8, i8>
1597 195..198 'z.x': u8
1598 204..205 'z': A<u8, i8>
1599 204..207 'z.y': i8
1600 "#]],
1601 )
1602}
1603
1604#[test]
1605fn recursive_type_alias() {
1606 check_infer(
1607 r#"
1608 struct A<X> {}
1609 type Foo = Foo;
1610 type Bar = A<Bar>;
1611 fn test(x: Foo) {}
1612 "#,
1613 expect![[r#"
1614 58..59 'x': {unknown}
1615 66..68 '{}': ()
1616 "#]],
1617 )
1618}
1619
1620#[test]
1621fn infer_type_param() {
1622 check_infer(
1623 r#"
1624 fn id<T>(x: T) -> T {
1625 x
1626 }
1627
1628 fn clone<T>(x: &T) -> T {
1629 *x
1630 }
1631
1632 fn test() {
1633 let y = 10u32;
1634 id(y);
1635 let x: bool = clone(z);
1636 id::<i128>(1);
1637 }
1638 "#,
1639 expect![[r#"
1640 9..10 'x': T
1641 20..29 '{ x }': T
1642 26..27 'x': T
1643 43..44 'x': &T
1644 55..65 '{ *x }': T
1645 61..63 '*x': T
1646 62..63 'x': &T
1647 77..157 '{ ...(1); }': ()
1648 87..88 'y': u32
1649 91..96 '10u32': u32
1650 102..104 'id': fn id<u32>(u32) -> u32
1651 102..107 'id(y)': u32
1652 105..106 'y': u32
1653 117..118 'x': bool
1654 127..132 'clone': fn clone<bool>(&bool) -> bool
1655 127..135 'clone(z)': bool
1656 133..134 'z': &bool
1657 141..151 'id::<i128>': fn id<i128>(i128) -> i128
1658 141..154 'id::<i128>(1)': i128
1659 152..153 '1': i128
1660 "#]],
1661 );
1662}
1663
1664#[test]
1665fn infer_const() {
1666 check_infer(
1667 r#"
1668 struct Foo;
1669 impl Foo { const ASSOC_CONST: u32 = 0; }
1670 const GLOBAL_CONST: u32 = 101;
1671 fn test() {
1672 const LOCAL_CONST: u32 = 99;
1673 let x = LOCAL_CONST;
1674 let z = GLOBAL_CONST;
1675 let id = Foo::ASSOC_CONST;
1676 }
1677 "#,
1678 expect![[r#"
1679 48..49 '0': u32
1680 79..82 '101': u32
1681 94..212 '{ ...NST; }': ()
1682 137..138 'x': u32
1683 141..152 'LOCAL_CONST': u32
1684 162..163 'z': u32
1685 166..178 'GLOBAL_CONST': u32
1686 188..190 'id': u32
1687 193..209 'Foo::A..._CONST': u32
1688 125..127 '99': u32
1689 "#]],
1690 );
1691}
1692
1693#[test]
1694fn infer_static() {
1695 check_infer(
1696 r#"
1697 static GLOBAL_STATIC: u32 = 101;
1698 static mut GLOBAL_STATIC_MUT: u32 = 101;
1699 fn test() {
1700 static LOCAL_STATIC: u32 = 99;
1701 static mut LOCAL_STATIC_MUT: u32 = 99;
1702 let x = LOCAL_STATIC;
1703 let y = LOCAL_STATIC_MUT;
1704 let z = GLOBAL_STATIC;
1705 let w = GLOBAL_STATIC_MUT;
1706 }
1707 "#,
1708 expect![[r#"
1709 28..31 '101': u32
1710 69..72 '101': u32
1711 84..279 '{ ...MUT; }': ()
1712 172..173 'x': u32
1713 176..188 'LOCAL_STATIC': u32
1714 198..199 'y': u32
1715 202..218 'LOCAL_...IC_MUT': u32
1716 228..229 'z': u32
1717 232..245 'GLOBAL_STATIC': u32
1718 255..256 'w': u32
1719 259..276 'GLOBAL...IC_MUT': u32
1720 117..119 '99': u32
1721 160..162 '99': u32
1722 "#]],
1723 );
1724}
1725
1726#[test]
1727fn shadowing_primitive() {
1728 check_types(
1729 r#"
1730struct i32;
1731struct Foo;
1732
1733impl i32 { fn foo(&self) -> Foo { Foo } }
1734
1735fn main() {
1736 let x: i32 = i32;
1737 x.foo();
1738 //^ Foo
1739}"#,
1740 );
1741}
1742
1743#[test]
1744fn not_shadowing_primitive_by_module() {
1745 check_types(
1746 r#"
1747//- /str.rs
1748fn foo() {}
1749
1750//- /main.rs
1751mod str;
1752fn foo() -> &'static str { "" }
1753
1754fn main() {
1755 foo();
1756 //^ &str
1757}"#,
1758 );
1759}
1760
1761#[test]
1762fn not_shadowing_module_by_primitive() {
1763 check_types(
1764 r#"
1765//- /str.rs
1766fn foo() -> u32 {0}
1767
1768//- /main.rs
1769mod str;
1770fn foo() -> &'static str { "" }
1771
1772fn main() {
1773 str::foo();
1774 //^ u32
1775}"#,
1776 );
1777}
1778
1779// This test is actually testing the shadowing behavior within hir_def. It
1780// lives here because the testing infrastructure in hir_def isn't currently
1781// capable of asserting the necessary conditions.
1782#[test]
1783fn should_be_shadowing_imports() {
1784 check_types(
1785 r#"
1786mod a {
1787 pub fn foo() -> i8 {0}
1788 pub struct foo { a: i8 }
1789}
1790mod b { pub fn foo () -> u8 {0} }
1791mod c { pub struct foo { a: u8 } }
1792mod d {
1793 pub use super::a::*;
1794 pub use super::c::foo;
1795 pub use super::b::foo;
1796}
1797
1798fn main() {
1799 d::foo();
1800 //^ u8
1801 d::foo{a:0};
1802 //^ u8
1803}"#,
1804 );
1805}
1806
1807#[test]
1808fn closure_return() {
1809 check_infer(
1810 r#"
1811 fn foo() -> u32 {
1812 let x = || -> usize { return 1; };
1813 }
1814 "#,
1815 expect![[r#"
1816 16..58 '{ ...; }; }': ()
1817 26..27 'x': || -> usize
1818 30..55 '|| -> ...n 1; }': || -> usize
1819 42..55 '{ return 1; }': usize
1820 44..52 'return 1': !
1821 51..52 '1': usize
1822 "#]],
1823 );
1824}
1825
1826#[test]
1827fn closure_return_unit() {
1828 check_infer(
1829 r#"
1830 fn foo() -> u32 {
1831 let x = || { return; };
1832 }
1833 "#,
1834 expect![[r#"
1835 16..47 '{ ...; }; }': ()
1836 26..27 'x': || -> ()
1837 30..44 '|| { return; }': || -> ()
1838 33..44 '{ return; }': ()
1839 35..41 'return': !
1840 "#]],
1841 );
1842}
1843
1844#[test]
1845fn closure_return_inferred() {
1846 check_infer(
1847 r#"
1848 fn foo() -> u32 {
1849 let x = || { "test" };
1850 }
1851 "#,
1852 expect![[r#"
1853 16..46 '{ ..." }; }': ()
1854 26..27 'x': || -> &str
1855 30..43 '|| { "test" }': || -> &str
1856 33..43 '{ "test" }': &str
1857 35..41 '"test"': &str
1858 "#]],
1859 );
1860}
1861
1862#[test]
1863fn fn_pointer_return() {
1864 check_infer(
1865 r#"
1866 struct Vtable {
1867 method: fn(),
1868 }
1869
1870 fn main() {
1871 let vtable = Vtable { method: || {} };
1872 let m = vtable.method;
1873 }
1874 "#,
1875 expect![[r#"
1876 47..120 '{ ...hod; }': ()
1877 57..63 'vtable': Vtable
1878 66..90 'Vtable...| {} }': Vtable
1879 83..88 '|| {}': || -> ()
1880 86..88 '{}': ()
1881 100..101 'm': fn()
1882 104..110 'vtable': Vtable
1883 104..117 'vtable.method': fn()
1884 "#]],
1885 );
1886}
1887
1888#[test]
1889fn effects_smoke_test() {
1890 check_infer(
1891 r#"
1892 fn main() {
1893 let x = unsafe { 92 };
1894 let y = async { async { () }.await };
1895 let z = try { () };
1896 let t = 'a: { 92 };
1897 }
1898 "#,
1899 expect![[r#"
1900 10..130 '{ ...2 }; }': ()
1901 20..21 'x': i32
1902 24..37 'unsafe { 92 }': i32
1903 31..37 '{ 92 }': i32
1904 33..35 '92': i32
1905 47..48 'y': {unknown}
1906 57..79 '{ asyn...wait }': {unknown}
1907 59..77 'async ....await': {unknown}
1908 65..71 '{ () }': ()
1909 67..69 '()': ()
1910 89..90 'z': {unknown}
1911 93..103 'try { () }': {unknown}
1912 97..103 '{ () }': ()
1913 99..101 '()': ()
1914 113..114 't': i32
1915 121..127 '{ 92 }': i32
1916 123..125 '92': i32
1917 "#]],
1918 )
1919}
1920
1921#[test]
1922fn infer_generic_from_later_assignment() {
1923 check_infer(
1924 r#"
1925 enum Option<T> { Some(T), None }
1926 use Option::*;
1927
1928 fn test() {
1929 let mut end = None;
1930 loop {
1931 end = Some(true);
1932 }
1933 }
1934 "#,
1935 expect![[r#"
1936 59..129 '{ ... } }': ()
1937 69..76 'mut end': Option<bool>
1938 79..83 'None': Option<bool>
1939 89..127 'loop {... }': !
1940 94..127 '{ ... }': ()
1941 104..107 'end': Option<bool>
1942 104..120 'end = ...(true)': ()
1943 110..114 'Some': Some<bool>(bool) -> Option<bool>
1944 110..120 'Some(true)': Option<bool>
1945 115..119 'true': bool
1946 "#]],
1947 );
1948}
1949
1950#[test]
1951fn infer_loop_break_with_val() {
1952 check_infer(
1953 r#"
1954 enum Option<T> { Some(T), None }
1955 use Option::*;
1956
1957 fn test() {
1958 let x = loop {
1959 if false {
1960 break None;
1961 }
1962
1963 break Some(true);
1964 };
1965 }
1966 "#,
1967 expect![[r#"
1968 59..168 '{ ... }; }': ()
1969 69..70 'x': Option<bool>
1970 73..165 'loop {... }': Option<bool>
1971 78..165 '{ ... }': ()
1972 88..132 'if fal... }': ()
1973 91..96 'false': bool
1974 97..132 '{ ... }': ()
1975 111..121 'break None': !
1976 117..121 'None': Option<bool>
1977 142..158 'break ...(true)': !
1978 148..152 'Some': Some<bool>(bool) -> Option<bool>
1979 148..158 'Some(true)': Option<bool>
1980 153..157 'true': bool
1981 "#]],
1982 );
1983}
1984
1985#[test]
1986fn infer_loop_break_without_val() {
1987 check_infer(
1988 r#"
1989 enum Option<T> { Some(T), None }
1990 use Option::*;
1991
1992 fn test() {
1993 let x = loop {
1994 if false {
1995 break;
1996 }
1997 };
1998 }
1999 "#,
2000 expect![[r#"
2001 59..136 '{ ... }; }': ()
2002 69..70 'x': ()
2003 73..133 'loop {... }': ()
2004 78..133 '{ ... }': ()
2005 88..127 'if fal... }': ()
2006 91..96 'false': bool
2007 97..127 '{ ... }': ()
2008 111..116 'break': !
2009 "#]],
2010 );
2011}
2012
2013#[test]
2014fn infer_labelled_break_with_val() {
2015 check_infer(
2016 r#"
2017 fn foo() {
2018 let _x = || 'outer: loop {
2019 let inner = 'inner: loop {
2020 let i = Default::default();
2021 if (break 'outer i) {
2022 loop { break 'inner 5i8; };
2023 } else if true {
2024 break 'inner 6;
2025 }
2026 break 7;
2027 };
2028 break inner < 8;
2029 };
2030 }
2031 "#,
2032 expect![[r#"
2033 9..335 '{ ... }; }': ()
2034 19..21 '_x': || -> bool
2035 24..332 '|| 'ou... }': || -> bool
2036 27..332 ''outer... }': bool
2037 40..332 '{ ... }': ()
2038 54..59 'inner': i8
2039 62..300 ''inner... }': i8
2040 75..300 '{ ... }': ()
2041 93..94 'i': bool
2042 97..113 'Defaul...efault': {unknown}
2043 97..115 'Defaul...ault()': bool
2044 129..269 'if (br... }': ()
2045 133..147 'break 'outer i': !
2046 146..147 'i': bool
2047 149..208 '{ ... }': ()
2048 167..193 'loop {...5i8; }': !
2049 172..193 '{ brea...5i8; }': ()
2050 174..190 'break ...er 5i8': !
2051 187..190 '5i8': i8
2052 214..269 'if tru... }': ()
2053 217..221 'true': bool
2054 222..269 '{ ... }': ()
2055 240..254 'break 'inner 6': !
2056 253..254 '6': i8
2057 282..289 'break 7': !
2058 288..289 '7': i8
2059 310..325 'break inner < 8': !
2060 316..321 'inner': i8
2061 316..325 'inner < 8': bool
2062 324..325 '8': i8
2063 "#]],
2064 );
2065}
2066
2067#[test]
2068fn generic_default() {
2069 check_infer(
2070 r#"
2071 struct Thing<T = ()> { t: T }
2072 enum OtherThing<T = ()> {
2073 One { t: T },
2074 Two(T),
2075 }
2076
2077 fn test(t1: Thing, t2: OtherThing, t3: Thing<i32>, t4: OtherThing<i32>) {
2078 t1.t;
2079 t3.t;
2080 match t2 {
2081 OtherThing::One { t } => { t; },
2082 OtherThing::Two(t) => { t; },
2083 }
2084 match t4 {
2085 OtherThing::One { t } => { t; },
2086 OtherThing::Two(t) => { t; },
2087 }
2088 }
2089 "#,
2090 expect![[r#"
2091 97..99 't1': Thing<()>
2092 108..110 't2': OtherThing<()>
2093 124..126 't3': Thing<i32>
2094 140..142 't4': OtherThing<i32>
2095 161..384 '{ ... } }': ()
2096 167..169 't1': Thing<()>
2097 167..171 't1.t': ()
2098 177..179 't3': Thing<i32>
2099 177..181 't3.t': i32
2100 187..282 'match ... }': ()
2101 193..195 't2': OtherThing<()>
2102 206..227 'OtherT... { t }': OtherThing<()>
2103 224..225 't': ()
2104 231..237 '{ t; }': ()
2105 233..234 't': ()
2106 247..265 'OtherT...Two(t)': OtherThing<()>
2107 263..264 't': ()
2108 269..275 '{ t; }': ()
2109 271..272 't': ()
2110 287..382 'match ... }': ()
2111 293..295 't4': OtherThing<i32>
2112 306..327 'OtherT... { t }': OtherThing<i32>
2113 324..325 't': i32
2114 331..337 '{ t; }': ()
2115 333..334 't': i32
2116 347..365 'OtherT...Two(t)': OtherThing<i32>
2117 363..364 't': i32
2118 369..375 '{ t; }': ()
2119 371..372 't': i32
2120 "#]],
2121 );
2122}
2123
2124#[test]
2125fn generic_default_in_struct_literal() {
2126 check_infer(
2127 r#"
2128 struct Thing<T = ()> { t: T }
2129 enum OtherThing<T = ()> {
2130 One { t: T },
2131 Two(T),
2132 }
2133
2134 fn test() {
2135 let x = Thing { t: loop {} };
2136 let y = Thing { t: () };
2137 let z = Thing { t: 1i32 };
2138 if let Thing { t } = z {
2139 t;
2140 }
2141
2142 let a = OtherThing::One { t: 1i32 };
2143 let b = OtherThing::Two(1i32);
2144 }
2145 "#,
2146 expect![[r#"
2147 99..319 '{ ...32); }': ()
2148 109..110 'x': Thing<!>
2149 113..133 'Thing ...p {} }': Thing<!>
2150 124..131 'loop {}': !
2151 129..131 '{}': ()
2152 143..144 'y': Thing<()>
2153 147..162 'Thing { t: () }': Thing<()>
2154 158..160 '()': ()
2155 172..173 'z': Thing<i32>
2156 176..193 'Thing ...1i32 }': Thing<i32>
2157 187..191 '1i32': i32
2158 199..240 'if let... }': ()
2159 206..217 'Thing { t }': Thing<i32>
2160 214..215 't': i32
2161 220..221 'z': Thing<i32>
2162 222..240 '{ ... }': ()
2163 232..233 't': i32
2164 250..251 'a': OtherThing<i32>
2165 254..281 'OtherT...1i32 }': OtherThing<i32>
2166 275..279 '1i32': i32
2167 291..292 'b': OtherThing<i32>
2168 295..310 'OtherThing::Two': Two<i32>(i32) -> OtherThing<i32>
2169 295..316 'OtherT...(1i32)': OtherThing<i32>
2170 311..315 '1i32': i32
2171 "#]],
2172 );
2173}
2174
2175#[test]
2176fn generic_default_depending_on_other_type_arg() {
2177 // FIXME: the {unknown} is a bug
2178 check_infer(
2179 r#"
2180 struct Thing<T = u128, F = fn() -> T> { t: T }
2181
2182 fn test(t1: Thing<u32>, t2: Thing) {
2183 t1;
2184 t2;
2185 Thing::<_> { t: 1u32 };
2186 }
2187 "#,
2188 expect![[r#"
2189 56..58 't1': Thing<u32, fn() -> u32>
2190 72..74 't2': Thing<u128, fn() -> u128>
2191 83..130 '{ ...2 }; }': ()
2192 89..91 't1': Thing<u32, fn() -> u32>
2193 97..99 't2': Thing<u128, fn() -> u128>
2194 105..127 'Thing:...1u32 }': Thing<u32, fn() -> {unknown}>
2195 121..125 '1u32': u32
2196 "#]],
2197 );
2198}
2199
2200#[test]
2201fn generic_default_depending_on_other_type_arg_forward() {
2202 // the {unknown} here is intentional, as defaults are not allowed to
2203 // refer to type parameters coming later
2204 check_infer(
2205 r#"
2206 struct Thing<F = fn() -> T, T = u128> { t: T }
2207
2208 fn test(t1: Thing) {
2209 t1;
2210 }
2211 "#,
2212 expect![[r#"
2213 56..58 't1': Thing<fn() -> {unknown}, u128>
2214 67..78 '{ t1; }': ()
2215 73..75 't1': Thing<fn() -> {unknown}, u128>
2216 "#]],
2217 );
2218}