1 use expect_test::expect;
2
3 use super::{check, check_infer, check_no_mismatches, check_types};
4
5 #[test]
infer_box()6 fn infer_box() {
7 check_types(
8 r#"
9 //- /main.rs crate:main deps:std
10 fn 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; 1]>)
15
16 //- /std.rs crate:std
17 #[prelude_import] use prelude::*;
18 mod prelude {}
19
20 mod boxed {
21 #[lang = "owned_box"]
22 pub struct Box<T: ?Sized> {
23 inner: *mut T,
24 }
25 }
26 "#,
27 );
28 }
29
30 #[test]
infer_box_with_allocator()31 fn infer_box_with_allocator() {
32 check_types(
33 r#"
34 //- /main.rs crate:main deps:std
35 fn test() {
36 let x = box 1;
37 let t = (x, box x, box &1, box [1]);
38 t;
39 } //^ (Box<i32, {unknown}>, Box<Box<i32, {unknown}>, {unknown}>, Box<&i32, {unknown}>, Box<[i32; 1], {unknown}>)
40
41 //- /std.rs crate:std
42 #[prelude_import] use prelude::*;
43 mod boxed {
44 #[lang = "owned_box"]
45 pub struct Box<T: ?Sized, A: Allocator> {
46 inner: *mut T,
47 allocator: A,
48 }
49 }
50 "#,
51 );
52 }
53
54 #[test]
infer_adt_self()55 fn infer_adt_self() {
56 check_types(
57 r#"
58 enum Nat { Succ(Self), Demo(Nat), Zero }
59
60 fn test() {
61 let foo: Nat = Nat::Zero;
62 if let Nat::Succ(x) = foo {
63 x;
64 } //^ Nat
65 }
66 "#,
67 );
68 }
69
70 #[test]
self_in_struct_lit()71 fn self_in_struct_lit() {
72 check_infer(
73 r#"
74 //- /main.rs
75 struct S<T> { x: T }
76
77 impl S<u32> {
78 fn foo() {
79 Self { x: 1 };
80 }
81 }
82 "#,
83 expect![[r#"
84 49..79 '{ ... }': ()
85 59..72 'Self { x: 1 }': S<u32>
86 69..70 '1': u32
87 "#]],
88 );
89 }
90
91 #[test]
type_alias_in_struct_lit()92 fn type_alias_in_struct_lit() {
93 check_infer(
94 r#"
95 //- /main.rs
96 struct S<T> { x: T }
97
98 type SS = S<u32>;
99
100 fn foo() {
101 SS { x: 1 };
102 }
103 "#,
104 expect![[r#"
105 50..70 '{ ...1 }; }': ()
106 56..67 'SS { x: 1 }': S<u32>
107 64..65 '1': u32
108 "#]],
109 );
110 }
111
112 #[test]
infer_ranges()113 fn infer_ranges() {
114 check_types(
115 r#"
116 //- minicore: range
117 fn test() {
118 let a = ..;
119 let b = 1..;
120 let c = ..2u32;
121 let d = 1..2usize;
122 let e = ..=10;
123 let f = 'a'..='z';
124
125 let t = (a, b, c, d, e, f);
126 t;
127 } //^ (RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)
128 "#,
129 );
130 }
131
132 #[test]
infer_while_let()133 fn infer_while_let() {
134 check_types(
135 r#"
136 enum Option<T> { Some(T), None }
137
138 fn test() {
139 let foo: Option<f32> = None;
140 while let Option::Some(x) = foo {
141 x;
142 } //^ f32
143 }
144 "#,
145 );
146 }
147
148 #[test]
infer_basics()149 fn infer_basics() {
150 check_infer(
151 r#"
152 fn test(a: u32, b: isize, c: !, d: &str) {
153 a;
154 b;
155 c;
156 d;
157 1usize;
158 1isize;
159 "test";
160 1.0f32;
161 }
162 "#,
163 expect![[r#"
164 8..9 'a': u32
165 16..17 'b': isize
166 26..27 'c': !
167 32..33 'd': &str
168 41..120 '{ ...f32; }': ()
169 47..48 'a': u32
170 54..55 'b': isize
171 61..62 'c': !
172 68..69 'd': &str
173 75..81 '1usize': usize
174 87..93 '1isize': isize
175 99..105 '"test"': &str
176 111..117 '1.0f32': f32
177 "#]],
178 );
179 }
180
181 #[test]
infer_let()182 fn infer_let() {
183 check_infer(
184 r#"
185 fn test() {
186 let a = 1isize;
187 let b: usize = 1;
188 let c = b;
189 let d: u32;
190 let e;
191 let f: i32 = e;
192 }
193 "#,
194 expect![[r#"
195 10..117 '{ ...= e; }': ()
196 20..21 'a': isize
197 24..30 '1isize': isize
198 40..41 'b': usize
199 51..52 '1': usize
200 62..63 'c': usize
201 66..67 'b': usize
202 77..78 'd': u32
203 93..94 'e': i32
204 104..105 'f': i32
205 113..114 'e': i32
206 "#]],
207 );
208 }
209
210 #[test]
infer_paths()211 fn infer_paths() {
212 check_infer(
213 r#"
214 fn a() -> u32 { 1 }
215
216 mod b {
217 pub fn c() -> u32 { 1 }
218 }
219
220 fn test() {
221 a();
222 b::c();
223 }
224 "#,
225 expect![[r#"
226 14..19 '{ 1 }': u32
227 16..17 '1': u32
228 51..56 '{ 1 }': u32
229 53..54 '1': u32
230 70..94 '{ ...c(); }': ()
231 76..77 'a': fn a() -> u32
232 76..79 'a()': u32
233 85..89 'b::c': fn c() -> u32
234 85..91 'b::c()': u32
235 "#]],
236 );
237 }
238
239 #[test]
infer_path_type()240 fn infer_path_type() {
241 check_infer(
242 r#"
243 struct S;
244
245 impl S {
246 fn foo() -> i32 { 1 }
247 }
248
249 fn test() {
250 S::foo();
251 <S>::foo();
252 }
253 "#,
254 expect![[r#"
255 40..45 '{ 1 }': i32
256 42..43 '1': i32
257 59..92 '{ ...o(); }': ()
258 65..71 'S::foo': fn foo() -> i32
259 65..73 'S::foo()': i32
260 79..87 '<S>::foo': fn foo() -> i32
261 79..89 '<S>::foo()': i32
262 "#]],
263 );
264 }
265
266 #[test]
infer_struct()267 fn infer_struct() {
268 check_infer(
269 r#"
270 struct A {
271 b: B,
272 c: C,
273 }
274 struct B;
275 struct C(usize);
276
277 fn test() {
278 let c = C(1);
279 B;
280 let a: A = A { b: B, c: C(1) };
281 a.b;
282 a.c;
283 }
284 "#,
285 expect![[r#"
286 71..153 '{ ...a.c; }': ()
287 81..82 'c': C
288 85..86 'C': C(usize) -> C
289 85..89 'C(1)': C
290 87..88 '1': usize
291 95..96 'B': B
292 106..107 'a': A
293 113..132 'A { b:...C(1) }': A
294 120..121 'B': B
295 126..127 'C': C(usize) -> C
296 126..130 'C(1)': C
297 128..129 '1': usize
298 138..139 'a': A
299 138..141 'a.b': B
300 147..148 'a': A
301 147..150 'a.c': C
302 "#]],
303 );
304 }
305
306 #[test]
infer_enum()307 fn infer_enum() {
308 check_infer(
309 r#"
310 enum E {
311 V1 { field: u32 },
312 V2
313 }
314 fn test() {
315 E::V1 { field: 1 };
316 E::V2;
317 }
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]
infer_union()329 fn 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 104..107 'baz': fn baz(MyUnion)
356 104..110 'baz(u)': ()
357 108..109 'u': MyUnion
358 122..123 'u': MyUnion
359 126..146 'MyUnio... 0.0 }': MyUnion
360 141..144 '0.0': f32
361 152..170 'unsafe...(u); }': ()
362 161..164 'baz': fn baz(MyUnion)
363 161..167 'baz(u)': ()
364 165..166 'u': MyUnion
365 188..189 'u': MyUnion
366 200..249 '{ ...bar; }': ()
367 210..215 'inner': u32
368 218..219 'u': MyUnion
369 218..223 'u.foo': u32
370 233..238 'inner': f32
371 241..242 'u': MyUnion
372 241..246 'u.bar': f32
373 "#]],
374 );
375 }
376
377 #[test]
infer_refs()378 fn infer_refs() {
379 check_infer(
380 r#"
381 fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
382 a;
383 *a;
384 &a;
385 &mut a;
386 b;
387 *b;
388 &b;
389 c;
390 *c;
391 d;
392 *d;
393 }
394 "#,
395 expect![[r#"
396 8..9 'a': &u32
397 17..18 'b': &mut u32
398 30..31 'c': *const u32
399 45..46 'd': *mut u32
400 58..149 '{ ... *d; }': ()
401 64..65 'a': &u32
402 71..73 '*a': u32
403 72..73 'a': &u32
404 79..81 '&a': &&u32
405 80..81 'a': &u32
406 87..93 '&mut a': &mut &u32
407 92..93 'a': &u32
408 99..100 'b': &mut u32
409 106..108 '*b': u32
410 107..108 'b': &mut u32
411 114..116 '&b': &&mut u32
412 115..116 'b': &mut u32
413 122..123 'c': *const u32
414 129..131 '*c': u32
415 130..131 'c': *const u32
416 137..138 'd': *mut u32
417 144..146 '*d': u32
418 145..146 'd': *mut u32
419 "#]],
420 );
421 }
422
423 #[test]
infer_raw_ref()424 fn infer_raw_ref() {
425 check_infer(
426 r#"
427 fn test(a: i32) {
428 &raw mut a;
429 &raw const a;
430 }
431 "#,
432 expect![[r#"
433 8..9 'a': i32
434 16..53 '{ ...t a; }': ()
435 22..32 '&raw mut a': *mut i32
436 31..32 'a': i32
437 38..50 '&raw const a': *const i32
438 49..50 'a': i32
439 "#]],
440 );
441 }
442
443 #[test]
infer_literals()444 fn infer_literals() {
445 check_infer(
446 r##"
447 fn test() {
448 5i32;
449 5f32;
450 5f64;
451 "hello";
452 b"bytes";
453 'c';
454 b'b';
455 3.14;
456 5000;
457 false;
458 true;
459 r#"
460 //! doc
461 // non-doc
462 mod foo {}
463 "#;
464 br#"yolo"#;
465 let a = b"a\x20b\
466 c";
467 let b = br"g\
468 h";
469 let c = br#"x"\"yb"#;
470 }
471 "##,
472 expect![[r##"
473 18..478 '{ ... }': ()
474 32..36 '5i32': i32
475 50..54 '5f32': f32
476 68..72 '5f64': f64
477 86..93 '"hello"': &str
478 107..115 'b"bytes"': &[u8; 5]
479 129..132 ''c'': char
480 146..150 'b'b'': u8
481 164..168 '3.14': f64
482 182..186 '5000': i32
483 200..205 'false': bool
484 219..223 'true': bool
485 237..333 'r#" ... "#': &str
486 347..357 'br#"yolo"#': &[u8; 4]
487 375..376 'a': &[u8; 4]
488 379..403 'b"a\x2... c"': &[u8; 4]
489 421..422 'b': &[u8; 4]
490 425..433 'br"g\ h"': &[u8; 4]
491 451..452 'c': &[u8; 6]
492 455..467 'br#"x"\"yb"#': &[u8; 6]
493 "##]],
494 );
495 }
496
497 #[test]
infer_unary_op()498 fn infer_unary_op() {
499 check_infer(
500 r#"
501 enum SomeType {}
502
503 fn test(x: SomeType) {
504 let b = false;
505 let c = !b;
506 let a = 100;
507 let d: i128 = -a;
508 let e = -100;
509 let f = !!!true;
510 let g = !42;
511 let h = !10u32;
512 let j = !a;
513 -3.14;
514 !3;
515 -x;
516 !x;
517 -"hello";
518 !"hello";
519 }
520 "#,
521 expect![[r#"
522 26..27 'x': SomeType
523 39..271 '{ ...lo"; }': ()
524 49..50 'b': bool
525 53..58 'false': bool
526 68..69 'c': bool
527 72..74 '!b': bool
528 73..74 'b': bool
529 84..85 'a': i128
530 88..91 '100': i128
531 101..102 'd': i128
532 111..113 '-a': i128
533 112..113 'a': i128
534 123..124 'e': i32
535 127..131 '-100': i32
536 128..131 '100': i32
537 141..142 'f': bool
538 145..152 '!!!true': bool
539 146..152 '!!true': bool
540 147..152 '!true': bool
541 148..152 'true': bool
542 162..163 'g': i32
543 166..169 '!42': i32
544 167..169 '42': i32
545 179..180 'h': u32
546 183..189 '!10u32': u32
547 184..189 '10u32': u32
548 199..200 'j': i128
549 203..205 '!a': i128
550 204..205 'a': i128
551 211..216 '-3.14': f64
552 212..216 '3.14': f64
553 222..224 '!3': i32
554 223..224 '3': i32
555 230..232 '-x': {unknown}
556 231..232 'x': SomeType
557 238..240 '!x': {unknown}
558 239..240 'x': SomeType
559 246..254 '-"hello"': {unknown}
560 247..254 '"hello"': &str
561 260..268 '!"hello"': {unknown}
562 261..268 '"hello"': &str
563 "#]],
564 );
565 }
566
567 #[test]
infer_backwards()568 fn infer_backwards() {
569 check_infer(
570 r#"
571 fn takes_u32(x: u32) {}
572
573 struct S { i32_field: i32 }
574
575 fn test() -> &mut &f64 {
576 let a = unknown_function();
577 takes_u32(a);
578 let b = unknown_function();
579 S { i32_field: b };
580 let c = unknown_function();
581 &mut &c
582 }
583 "#,
584 expect![[r#"
585 13..14 'x': u32
586 21..23 '{}': ()
587 77..230 '{ ...t &c }': &mut &f64
588 87..88 'a': u32
589 91..107 'unknow...nction': {unknown}
590 91..109 'unknow...tion()': u32
591 115..124 'takes_u32': fn takes_u32(u32)
592 115..127 'takes_u32(a)': ()
593 125..126 'a': u32
594 137..138 'b': i32
595 141..157 'unknow...nction': {unknown}
596 141..159 'unknow...tion()': i32
597 165..183 'S { i3...d: b }': S
598 180..181 'b': i32
599 193..194 'c': f64
600 197..213 'unknow...nction': {unknown}
601 197..215 'unknow...tion()': f64
602 221..228 '&mut &c': &mut &f64
603 226..228 '&c': &f64
604 227..228 'c': f64
605 "#]],
606 );
607 }
608
609 #[test]
infer_self()610 fn infer_self() {
611 check_infer(
612 r#"
613 struct S;
614
615 impl S {
616 fn test(&self) {
617 self;
618 }
619 fn test2(self: &Self) {
620 self;
621 }
622 fn test3() -> Self {
623 S {}
624 }
625 fn test4() -> Self {
626 Self {}
627 }
628 }
629 "#,
630 expect![[r#"
631 33..37 'self': &S
632 39..60 '{ ... }': ()
633 49..53 'self': &S
634 74..78 'self': &S
635 87..108 '{ ... }': ()
636 97..101 'self': &S
637 132..152 '{ ... }': S
638 142..146 'S {}': S
639 176..199 '{ ... }': S
640 186..193 'Self {}': S
641 "#]],
642 );
643 }
644
645 #[test]
infer_self_as_path()646 fn infer_self_as_path() {
647 check_infer(
648 r#"
649 struct S1;
650 struct S2(isize);
651 enum E {
652 V1,
653 V2(u32),
654 }
655
656 impl S1 {
657 fn test() {
658 Self;
659 }
660 }
661 impl S2 {
662 fn test() {
663 Self(1);
664 }
665 }
666 impl E {
667 fn test() {
668 Self::V1;
669 Self::V2(1);
670 }
671 }
672 "#,
673 expect![[r#"
674 86..107 '{ ... }': ()
675 96..100 'Self': S1
676 134..158 '{ ... }': ()
677 144..148 'Self': S2(isize) -> S2
678 144..151 'Self(1)': S2
679 149..150 '1': isize
680 184..230 '{ ... }': ()
681 194..202 'Self::V1': E
682 212..220 'Self::V2': V2(u32) -> E
683 212..223 'Self::V2(1)': E
684 221..222 '1': u32
685 "#]],
686 );
687 }
688
689 #[test]
infer_binary_op()690 fn infer_binary_op() {
691 check_infer(
692 r#"
693 fn f(x: bool) -> i32 {
694 0i32
695 }
696
697 fn test() -> bool {
698 let x = a && b;
699 let y = true || false;
700 let z = x == y;
701 let t = x != y;
702 let minus_forty: isize = -40isize;
703 let h = minus_forty <= CONST_2;
704 let c = f(z || y) + 5;
705 let d = b;
706 let g = minus_forty ^= i;
707 let ten: usize = 10;
708 let ten_is_eleven = ten == some_num;
709
710 ten < 3
711 }
712 "#,
713 expect![[r#"
714 5..6 'x': bool
715 21..33 '{ 0i32 }': i32
716 27..31 '0i32': i32
717 53..369 '{ ... < 3 }': bool
718 63..64 'x': bool
719 67..68 'a': bool
720 67..73 'a && b': bool
721 72..73 'b': bool
722 83..84 'y': bool
723 87..91 'true': bool
724 87..100 'true || false': bool
725 95..100 'false': bool
726 110..111 'z': bool
727 114..115 'x': bool
728 114..120 'x == y': bool
729 119..120 'y': bool
730 130..131 't': bool
731 134..135 'x': bool
732 134..140 'x != y': bool
733 139..140 'y': bool
734 150..161 'minus_forty': isize
735 171..179 '-40isize': isize
736 172..179 '40isize': isize
737 189..190 'h': bool
738 193..204 'minus_forty': isize
739 193..215 'minus_...ONST_2': bool
740 208..215 'CONST_2': isize
741 225..226 'c': i32
742 229..230 'f': fn f(bool) -> i32
743 229..238 'f(z || y)': i32
744 229..242 'f(z || y) + 5': i32
745 231..232 'z': bool
746 231..237 'z || y': bool
747 236..237 'y': bool
748 241..242 '5': i32
749 252..253 'd': {unknown}
750 256..257 'b': {unknown}
751 267..268 'g': ()
752 271..282 'minus_forty': isize
753 271..287 'minus_...y ^= i': ()
754 286..287 'i': isize
755 297..300 'ten': usize
756 310..312 '10': usize
757 322..335 'ten_is_eleven': bool
758 338..341 'ten': usize
759 338..353 'ten == some_num': bool
760 345..353 'some_num': usize
761 360..363 'ten': usize
762 360..367 'ten < 3': bool
763 366..367 '3': usize
764 "#]],
765 );
766 }
767
768 #[test]
infer_shift_op()769 fn infer_shift_op() {
770 check_infer(
771 r#"
772 fn test() {
773 1u32 << 5u8;
774 1u32 >> 5u8;
775 }
776 "#,
777 expect![[r#"
778 10..47 '{ ...5u8; }': ()
779 16..20 '1u32': u32
780 16..27 '1u32 << 5u8': u32
781 24..27 '5u8': u8
782 33..37 '1u32': u32
783 33..44 '1u32 >> 5u8': u32
784 41..44 '5u8': u8
785 "#]],
786 );
787 }
788
789 #[test]
infer_field_autoderef()790 fn infer_field_autoderef() {
791 check_infer(
792 r#"
793 struct A {
794 b: B,
795 }
796 struct B;
797
798 fn test1(a: A) {
799 let a1 = a;
800 a1.b;
801 let a2 = &a;
802 a2.b;
803 let a3 = &mut a;
804 a3.b;
805 let a4 = &&&&&&&a;
806 a4.b;
807 let a5 = &mut &&mut &&mut a;
808 a5.b;
809 }
810
811 fn test2(a1: *const A, a2: *mut A) {
812 a1.b;
813 a2.b;
814 }
815 "#,
816 expect![[r#"
817 43..44 'a': A
818 49..212 '{ ...5.b; }': ()
819 59..61 'a1': A
820 64..65 'a': A
821 71..73 'a1': A
822 71..75 'a1.b': B
823 85..87 'a2': &A
824 90..92 '&a': &A
825 91..92 'a': A
826 98..100 'a2': &A
827 98..102 'a2.b': B
828 112..114 'a3': &mut A
829 117..123 '&mut a': &mut A
830 122..123 'a': A
831 129..131 'a3': &mut A
832 129..133 'a3.b': B
833 143..145 'a4': &&&&&&&A
834 148..156 '&&&&&&&a': &&&&&&&A
835 149..156 '&&&&&&a': &&&&&&A
836 150..156 '&&&&&a': &&&&&A
837 151..156 '&&&&a': &&&&A
838 152..156 '&&&a': &&&A
839 153..156 '&&a': &&A
840 154..156 '&a': &A
841 155..156 'a': A
842 162..164 'a4': &&&&&&&A
843 162..166 'a4.b': B
844 176..178 'a5': &mut &&mut &&mut A
845 181..199 '&mut &...&mut a': &mut &&mut &&mut A
846 186..199 '&&mut &&mut a': &&mut &&mut A
847 187..199 '&mut &&mut a': &mut &&mut A
848 192..199 '&&mut a': &&mut A
849 193..199 '&mut a': &mut A
850 198..199 'a': A
851 205..207 'a5': &mut &&mut &&mut A
852 205..209 'a5.b': B
853 223..225 'a1': *const A
854 237..239 'a2': *mut A
855 249..272 '{ ...2.b; }': ()
856 255..257 'a1': *const A
857 255..259 'a1.b': {unknown}
858 265..267 'a2': *mut A
859 265..269 'a2.b': {unknown}
860 "#]],
861 );
862 }
863
864 #[test]
infer_argument_autoderef()865 fn infer_argument_autoderef() {
866 check_infer(
867 r#"
868 //- minicore: deref
869 use core::ops::Deref;
870 struct A<T>(T);
871
872 impl<T> A<T> {
873 fn foo(&self) -> &T {
874 &self.0
875 }
876 }
877
878 struct B<T>(T);
879
880 impl<T> Deref for B<T> {
881 type Target = T;
882 fn deref(&self) -> &Self::Target {
883 &self.0
884 }
885 }
886
887 fn test() {
888 let t = A::foo(&&B(B(A(42))));
889 }
890 "#,
891 expect![[r#"
892 66..70 'self': &A<T>
893 78..101 '{ ... }': &T
894 88..95 '&self.0': &T
895 89..93 'self': &A<T>
896 89..95 'self.0': T
897 182..186 'self': &B<T>
898 205..228 '{ ... }': &T
899 215..222 '&self.0': &T
900 216..220 'self': &B<T>
901 216..222 'self.0': T
902 242..280 '{ ...))); }': ()
903 252..253 't': &i32
904 256..262 'A::foo': fn foo<i32>(&A<i32>) -> &i32
905 256..277 'A::foo...42))))': &i32
906 263..276 '&&B(B(A(42)))': &&B<B<A<i32>>>
907 264..276 '&B(B(A(42)))': &B<B<A<i32>>>
908 265..266 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
909 265..276 'B(B(A(42)))': B<B<A<i32>>>
910 267..268 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
911 267..275 'B(A(42))': B<A<i32>>
912 269..270 'A': A<i32>(i32) -> A<i32>
913 269..274 'A(42)': A<i32>
914 271..273 '42': i32
915 "#]],
916 );
917 }
918
919 #[test]
infer_method_argument_autoderef()920 fn infer_method_argument_autoderef() {
921 check_infer(
922 r#"
923 //- minicore: deref
924 use core::ops::Deref;
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 71..75 'self': &A<T>
948 77..78 'x': &A<T>
949 93..114 '{ ... }': &T
950 103..108 '&*x.0': &T
951 104..108 '*x.0': T
952 105..106 'x': &A<T>
953 105..108 'x.0': *mut T
954 195..199 'self': &B<T>
955 218..241 '{ ... }': &T
956 228..235 '&self.0': &T
957 229..233 'self': &B<T>
958 229..235 'self.0': T
959 253..254 'a': A<i32>
960 264..310 '{ ...))); }': ()
961 274..275 't': &i32
962 278..279 'A': A<i32>(*mut i32) -> A<i32>
963 278..292 'A(0 as *mut _)': A<i32>
964 278..307 'A(0 as...B(a)))': &i32
965 280..281 '0': i32
966 280..291 '0 as *mut _': *mut i32
967 297..306 '&&B(B(a))': &&B<B<A<i32>>>
968 298..306 '&B(B(a))': &B<B<A<i32>>>
969 299..300 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
970 299..306 'B(B(a))': B<B<A<i32>>>
971 301..302 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
972 301..305 'B(a)': B<A<i32>>
973 303..304 'a': A<i32>
974 "#]],
975 );
976 }
977
978 #[test]
infer_in_elseif()979 fn infer_in_elseif() {
980 check_infer(
981 r#"
982 struct Foo { field: i32 }
983 fn main(foo: Foo) {
984 if true {
985
986 } else if false {
987 foo.field
988 }
989 }
990 "#,
991 expect![[r#"
992 34..37 'foo': Foo
993 44..108 '{ ... } }': ()
994 50..106 'if tru... }': ()
995 53..57 'true': bool
996 58..66 '{ }': ()
997 72..106 'if fal... }': ()
998 75..80 'false': bool
999 81..106 '{ ... }': ()
1000 91..94 'foo': Foo
1001 91..100 'foo.field': i32
1002 "#]],
1003 )
1004 }
1005
1006 #[test]
infer_if_match_with_return()1007 fn infer_if_match_with_return() {
1008 check_infer(
1009 r#"
1010 fn foo() {
1011 let _x1 = if true {
1012 1
1013 } else {
1014 return;
1015 };
1016 let _x2 = if true {
1017 2
1018 } else {
1019 return
1020 };
1021 let _x3 = match true {
1022 true => 3,
1023 _ => {
1024 return;
1025 }
1026 };
1027 let _x4 = match true {
1028 true => 4,
1029 _ => return
1030 };
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]
infer_inherent_method()1071 fn 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 pub 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 '{}': i32
1096 106..110 'self': &A
1097 112..113 'x': u64
1098 127..129 '{}': i64
1099 147..148 'a': A
1100 153..201 '{ ...(1); }': ()
1101 159..160 'a': A
1102 159..167 'a.foo(1)': i32
1103 165..166 '1': u32
1104 173..184 '(&a).bar(1)': i64
1105 174..176 '&a': &A
1106 175..176 'a': A
1107 182..183 '1': u64
1108 190..191 'a': A
1109 190..198 'a.bar(1)': i64
1110 196..197 '1': u64
1111 "#]],
1112 );
1113 }
1114
1115 #[test]
infer_inherent_method_str()1116 fn infer_inherent_method_str() {
1117 check_infer(
1118 r#"
1119 #![rustc_coherence_is_core]
1120 #[lang = "str"]
1121 impl str {
1122 fn foo(&self) -> i32 {}
1123 }
1124
1125 fn test() {
1126 "foo".foo();
1127 }
1128 "#,
1129 expect![[r#"
1130 67..71 'self': &str
1131 80..82 '{}': i32
1132 96..116 '{ ...o(); }': ()
1133 102..107 '"foo"': &str
1134 102..113 '"foo".foo()': i32
1135 "#]],
1136 );
1137 }
1138
1139 #[test]
infer_tuple()1140 fn infer_tuple() {
1141 check_infer(
1142 r#"
1143 fn test(x: &str, y: isize) {
1144 let a: (u32, &str) = (1, "a");
1145 let b = (a, x);
1146 let c = (y, x);
1147 let d = (c, x);
1148 let e = (1, "e");
1149 let f = (e, "d");
1150 }
1151 "#,
1152 expect![[r#"
1153 8..9 'x': &str
1154 17..18 'y': isize
1155 27..169 '{ ...d"); }': ()
1156 37..38 'a': (u32, &str)
1157 54..62 '(1, "a")': (u32, &str)
1158 55..56 '1': u32
1159 58..61 '"a"': &str
1160 72..73 'b': ((u32, &str), &str)
1161 76..82 '(a, x)': ((u32, &str), &str)
1162 77..78 'a': (u32, &str)
1163 80..81 'x': &str
1164 92..93 'c': (isize, &str)
1165 96..102 '(y, x)': (isize, &str)
1166 97..98 'y': isize
1167 100..101 'x': &str
1168 112..113 'd': ((isize, &str), &str)
1169 116..122 '(c, x)': ((isize, &str), &str)
1170 117..118 'c': (isize, &str)
1171 120..121 'x': &str
1172 132..133 'e': (i32, &str)
1173 136..144 '(1, "e")': (i32, &str)
1174 137..138 '1': i32
1175 140..143 '"e"': &str
1176 154..155 'f': ((i32, &str), &str)
1177 158..166 '(e, "d")': ((i32, &str), &str)
1178 159..160 'e': (i32, &str)
1179 162..165 '"d"': &str
1180 "#]],
1181 );
1182 }
1183
1184 #[test]
infer_array()1185 fn infer_array() {
1186 check_infer(
1187 r#"
1188 fn test(x: &str, y: isize) {
1189 let a = [x];
1190 let b = [a, a];
1191 let c = [b, b];
1192
1193 let d = [y, 1, 2, 3];
1194 let d = [1, y, 2, 3];
1195 let e = [y];
1196 let f = [d, d];
1197 let g = [e, e];
1198
1199 let h = [1, 2];
1200 let i = ["a", "b"];
1201
1202 let b = [a, ["b"]];
1203 let x: [u8; 0] = [];
1204 let y: [u8; 2+2] = [1,2,3,4];
1205 }
1206 "#,
1207 expect![[r#"
1208 8..9 'x': &str
1209 17..18 'y': isize
1210 27..326 '{ ...,4]; }': ()
1211 37..38 'a': [&str; 1]
1212 41..44 '[x]': [&str; 1]
1213 42..43 'x': &str
1214 54..55 'b': [[&str; 1]; 2]
1215 58..64 '[a, a]': [[&str; 1]; 2]
1216 59..60 'a': [&str; 1]
1217 62..63 'a': [&str; 1]
1218 74..75 'c': [[[&str; 1]; 2]; 2]
1219 78..84 '[b, b]': [[[&str; 1]; 2]; 2]
1220 79..80 'b': [[&str; 1]; 2]
1221 82..83 'b': [[&str; 1]; 2]
1222 95..96 'd': [isize; 4]
1223 99..111 '[y, 1, 2, 3]': [isize; 4]
1224 100..101 'y': isize
1225 103..104 '1': isize
1226 106..107 '2': isize
1227 109..110 '3': isize
1228 121..122 'd': [isize; 4]
1229 125..137 '[1, y, 2, 3]': [isize; 4]
1230 126..127 '1': isize
1231 129..130 'y': isize
1232 132..133 '2': isize
1233 135..136 '3': isize
1234 147..148 'e': [isize; 1]
1235 151..154 '[y]': [isize; 1]
1236 152..153 'y': isize
1237 164..165 'f': [[isize; 4]; 2]
1238 168..174 '[d, d]': [[isize; 4]; 2]
1239 169..170 'd': [isize; 4]
1240 172..173 'd': [isize; 4]
1241 184..185 'g': [[isize; 1]; 2]
1242 188..194 '[e, e]': [[isize; 1]; 2]
1243 189..190 'e': [isize; 1]
1244 192..193 'e': [isize; 1]
1245 205..206 'h': [i32; 2]
1246 209..215 '[1, 2]': [i32; 2]
1247 210..211 '1': i32
1248 213..214 '2': i32
1249 225..226 'i': [&str; 2]
1250 229..239 '["a", "b"]': [&str; 2]
1251 230..233 '"a"': &str
1252 235..238 '"b"': &str
1253 250..251 'b': [[&str; 1]; 2]
1254 254..264 '[a, ["b"]]': [[&str; 1]; 2]
1255 255..256 'a': [&str; 1]
1256 258..263 '["b"]': [&str; 1]
1257 259..262 '"b"': &str
1258 274..275 'x': [u8; 0]
1259 287..289 '[]': [u8; 0]
1260 299..300 'y': [u8; 4]
1261 314..323 '[1,2,3,4]': [u8; 4]
1262 315..316 '1': u8
1263 317..318 '2': u8
1264 319..320 '3': u8
1265 321..322 '4': u8
1266 "#]],
1267 );
1268 }
1269
1270 #[test]
infer_struct_generics()1271 fn infer_struct_generics() {
1272 check_infer(
1273 r#"
1274 struct A<T> {
1275 x: T,
1276 }
1277
1278 fn test(a1: A<u32>, i: i32) {
1279 a1.x;
1280 let a2 = A { x: i };
1281 a2.x;
1282 let a3 = A::<i128> { x: 1 };
1283 a3.x;
1284 }
1285 "#,
1286 expect![[r#"
1287 35..37 'a1': A<u32>
1288 47..48 'i': i32
1289 55..146 '{ ...3.x; }': ()
1290 61..63 'a1': A<u32>
1291 61..65 'a1.x': u32
1292 75..77 'a2': A<i32>
1293 80..90 'A { x: i }': A<i32>
1294 87..88 'i': i32
1295 96..98 'a2': A<i32>
1296 96..100 'a2.x': i32
1297 110..112 'a3': A<i128>
1298 115..133 'A::<i1...x: 1 }': A<i128>
1299 130..131 '1': i128
1300 139..141 'a3': A<i128>
1301 139..143 'a3.x': i128
1302 "#]],
1303 );
1304 }
1305
1306 #[test]
infer_tuple_struct_generics()1307 fn infer_tuple_struct_generics() {
1308 check_infer(
1309 r#"
1310 struct A<T>(T);
1311 enum Option<T> { Some(T), None }
1312 use Option::*;
1313
1314 fn test() {
1315 A(42);
1316 A(42u128);
1317 Some("x");
1318 Option::Some("x");
1319 None;
1320 let x: Option<i64> = None;
1321 }
1322 "#,
1323 expect![[r#"
1324 75..183 '{ ...one; }': ()
1325 81..82 'A': A<i32>(i32) -> A<i32>
1326 81..86 'A(42)': A<i32>
1327 83..85 '42': i32
1328 92..93 'A': A<u128>(u128) -> A<u128>
1329 92..101 'A(42u128)': A<u128>
1330 94..100 '42u128': u128
1331 107..111 'Some': Some<&str>(&str) -> Option<&str>
1332 107..116 'Some("x")': Option<&str>
1333 112..115 '"x"': &str
1334 122..134 'Option::Some': Some<&str>(&str) -> Option<&str>
1335 122..139 'Option...e("x")': Option<&str>
1336 135..138 '"x"': &str
1337 145..149 'None': Option<{unknown}>
1338 159..160 'x': Option<i64>
1339 176..180 'None': Option<i64>
1340 "#]],
1341 );
1342 }
1343
1344 #[test]
infer_function_generics()1345 fn infer_function_generics() {
1346 check_infer(
1347 r#"
1348 fn id<T>(t: T) -> T { t }
1349
1350 fn test() {
1351 id(1u32);
1352 id::<i128>(1);
1353 let x: u64 = id(1);
1354 }
1355 "#,
1356 expect![[r#"
1357 9..10 't': T
1358 20..25 '{ t }': T
1359 22..23 't': T
1360 37..97 '{ ...(1); }': ()
1361 43..45 'id': fn id<u32>(u32) -> u32
1362 43..51 'id(1u32)': u32
1363 46..50 '1u32': u32
1364 57..67 'id::<i128>': fn id<i128>(i128) -> i128
1365 57..70 'id::<i128>(1)': i128
1366 68..69 '1': i128
1367 80..81 'x': u64
1368 89..91 'id': fn id<u64>(u64) -> u64
1369 89..94 'id(1)': u64
1370 92..93 '1': u64
1371 "#]],
1372 );
1373 }
1374
1375 #[test]
infer_impl_generics_basic()1376 fn infer_impl_generics_basic() {
1377 check_infer(
1378 r#"
1379 struct A<T1, T2> {
1380 x: T1,
1381 y: T2,
1382 }
1383 impl<Y, X> A<X, Y> {
1384 fn x(self) -> X {
1385 self.x
1386 }
1387 fn y(self) -> Y {
1388 self.y
1389 }
1390 fn z<T>(self, t: T) -> (X, Y, T) {
1391 (self.x, self.y, t)
1392 }
1393 }
1394
1395 fn test() -> i128 {
1396 let a = A { x: 1u64, y: 1i64 };
1397 a.x();
1398 a.y();
1399 a.z(1i128);
1400 a.z::<u128>(1);
1401 }
1402 "#,
1403 expect![[r#"
1404 73..77 'self': A<X, Y>
1405 84..106 '{ ... }': X
1406 94..98 'self': A<X, Y>
1407 94..100 'self.x': X
1408 116..120 'self': A<X, Y>
1409 127..149 '{ ... }': Y
1410 137..141 'self': A<X, Y>
1411 137..143 'self.y': Y
1412 162..166 'self': A<X, Y>
1413 168..169 't': T
1414 187..222 '{ ... }': (X, Y, T)
1415 197..216 '(self.....y, t)': (X, Y, T)
1416 198..202 'self': A<X, Y>
1417 198..204 'self.x': X
1418 206..210 'self': A<X, Y>
1419 206..212 'self.y': Y
1420 214..215 't': T
1421 244..341 '{ ...(1); }': i128
1422 254..255 'a': A<u64, i64>
1423 258..280 'A { x:...1i64 }': A<u64, i64>
1424 265..269 '1u64': u64
1425 274..278 '1i64': i64
1426 286..287 'a': A<u64, i64>
1427 286..291 'a.x()': u64
1428 297..298 'a': A<u64, i64>
1429 297..302 'a.y()': i64
1430 308..309 'a': A<u64, i64>
1431 308..318 'a.z(1i128)': (u64, i64, i128)
1432 312..317 '1i128': i128
1433 324..325 'a': A<u64, i64>
1434 324..338 'a.z::<u128>(1)': (u64, i64, u128)
1435 336..337 '1': u128
1436 "#]],
1437 );
1438 }
1439
1440 #[test]
infer_impl_generics_with_autoderef()1441 fn infer_impl_generics_with_autoderef() {
1442 check_infer(
1443 r#"
1444 enum Option<T> {
1445 Some(T),
1446 None,
1447 }
1448 impl<T> Option<T> {
1449 fn as_ref(&self) -> Option<&T> {}
1450 }
1451 fn test(o: Option<u32>) {
1452 (&o).as_ref();
1453 o.as_ref();
1454 }
1455 "#,
1456 expect![[r#"
1457 77..81 'self': &Option<T>
1458 97..99 '{}': Option<&T>
1459 110..111 'o': Option<u32>
1460 126..164 '{ ...f(); }': ()
1461 132..145 '(&o).as_ref()': Option<&u32>
1462 133..135 '&o': &Option<u32>
1463 134..135 'o': Option<u32>
1464 151..152 'o': Option<u32>
1465 151..161 'o.as_ref()': Option<&u32>
1466 "#]],
1467 );
1468 }
1469
1470 #[test]
infer_generic_chain()1471 fn infer_generic_chain() {
1472 check_infer(
1473 r#"
1474 struct A<T> {
1475 x: T,
1476 }
1477 impl<T2> A<T2> {
1478 fn x(self) -> T2 {
1479 self.x
1480 }
1481 }
1482 fn id<T>(t: T) -> T { t }
1483
1484 fn test() -> i128 {
1485 let x = 1;
1486 let y = id(x);
1487 let a = A { x: id(y) };
1488 let z = id(a.x);
1489 let b = A { x: z };
1490 b.x()
1491 }
1492 "#,
1493 expect![[r#"
1494 52..56 'self': A<T2>
1495 64..86 '{ ... }': T2
1496 74..78 'self': A<T2>
1497 74..80 'self.x': T2
1498 98..99 't': T
1499 109..114 '{ t }': T
1500 111..112 't': T
1501 134..254 '{ ....x() }': i128
1502 144..145 'x': i128
1503 148..149 '1': i128
1504 159..160 'y': i128
1505 163..165 'id': fn id<i128>(i128) -> i128
1506 163..168 'id(x)': i128
1507 166..167 'x': i128
1508 178..179 'a': A<i128>
1509 182..196 'A { x: id(y) }': A<i128>
1510 189..191 'id': fn id<i128>(i128) -> i128
1511 189..194 'id(y)': i128
1512 192..193 'y': i128
1513 206..207 'z': i128
1514 210..212 'id': fn id<i128>(i128) -> i128
1515 210..217 'id(a.x)': i128
1516 213..214 'a': A<i128>
1517 213..216 'a.x': i128
1518 227..228 'b': A<i128>
1519 231..241 'A { x: z }': A<i128>
1520 238..239 'z': i128
1521 247..248 'b': A<i128>
1522 247..252 'b.x()': i128
1523 "#]],
1524 );
1525 }
1526
1527 #[test]
infer_associated_const()1528 fn infer_associated_const() {
1529 check_infer(
1530 r#"
1531 struct Struct;
1532
1533 impl Struct {
1534 const FOO: u32 = 1;
1535 }
1536
1537 enum Enum {}
1538
1539 impl Enum {
1540 const BAR: u32 = 2;
1541 }
1542
1543 trait Trait {
1544 const ID: u32;
1545 }
1546
1547 struct TraitTest;
1548
1549 impl Trait for TraitTest {
1550 const ID: u32 = 5;
1551 }
1552
1553 fn test() {
1554 let x = Struct::FOO;
1555 let y = Enum::BAR;
1556 let z = TraitTest::ID;
1557 }
1558 "#,
1559 expect![[r#"
1560 51..52 '1': u32
1561 104..105 '2': u32
1562 212..213 '5': u32
1563 228..306 '{ ...:ID; }': ()
1564 238..239 'x': u32
1565 242..253 'Struct::FOO': u32
1566 263..264 'y': u32
1567 267..276 'Enum::BAR': u32
1568 286..287 'z': u32
1569 290..303 'TraitTest::ID': u32
1570 "#]],
1571 );
1572 }
1573
1574 #[test]
infer_type_alias()1575 fn infer_type_alias() {
1576 check_infer(
1577 r#"
1578 struct A<X, Y> { x: X, y: Y }
1579 type Foo = A<u32, i128>;
1580 type Bar<T> = A<T, u128>;
1581 type Baz<U, V> = A<V, U>;
1582 fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) {
1583 x.x;
1584 x.y;
1585 y.x;
1586 y.y;
1587 z.x;
1588 z.y;
1589 }
1590 mod m {
1591 pub enum Enum {
1592 Foo(u8),
1593 }
1594 pub type Alias = Enum;
1595 }
1596 fn f() {
1597 let e = m::Alias::Foo(0);
1598 let m::Alias::Foo(x) = &e;
1599 }
1600 "#,
1601 expect![[r#"
1602 115..116 'x': A<u32, i128>
1603 123..124 'y': A<&str, u128>
1604 137..138 'z': A<u8, i8>
1605 153..210 '{ ...z.y; }': ()
1606 159..160 'x': A<u32, i128>
1607 159..162 'x.x': u32
1608 168..169 'x': A<u32, i128>
1609 168..171 'x.y': i128
1610 177..178 'y': A<&str, u128>
1611 177..180 'y.x': &str
1612 186..187 'y': A<&str, u128>
1613 186..189 'y.y': u128
1614 195..196 'z': A<u8, i8>
1615 195..198 'z.x': u8
1616 204..205 'z': A<u8, i8>
1617 204..207 'z.y': i8
1618 298..362 '{ ... &e; }': ()
1619 308..309 'e': Enum
1620 312..325 'm::Alias::Foo': Foo(u8) -> Enum
1621 312..328 'm::Ali...Foo(0)': Enum
1622 326..327 '0': u8
1623 338..354 'm::Ali...Foo(x)': Enum
1624 352..353 'x': &u8
1625 357..359 '&e': &Enum
1626 358..359 'e': Enum
1627 "#]],
1628 )
1629 }
1630
1631 #[test]
recursive_type_alias()1632 fn recursive_type_alias() {
1633 check_infer(
1634 r#"
1635 struct A<X> {}
1636 type Foo = Foo;
1637 type Bar = A<Bar>;
1638 fn test(x: Foo) {}
1639 "#,
1640 expect![[r#"
1641 58..59 'x': {unknown}
1642 66..68 '{}': ()
1643 "#]],
1644 )
1645 }
1646
1647 #[test]
infer_type_param()1648 fn infer_type_param() {
1649 check_infer(
1650 r#"
1651 fn id<T>(x: T) -> T {
1652 x
1653 }
1654
1655 fn clone<T>(x: &T) -> T {
1656 *x
1657 }
1658
1659 fn test() {
1660 let y = 10u32;
1661 id(y);
1662 let x: bool = clone(z);
1663 id::<i128>(1);
1664 }
1665 "#,
1666 expect![[r#"
1667 9..10 'x': T
1668 20..29 '{ x }': T
1669 26..27 'x': T
1670 43..44 'x': &T
1671 55..65 '{ *x }': T
1672 61..63 '*x': T
1673 62..63 'x': &T
1674 77..157 '{ ...(1); }': ()
1675 87..88 'y': u32
1676 91..96 '10u32': u32
1677 102..104 'id': fn id<u32>(u32) -> u32
1678 102..107 'id(y)': u32
1679 105..106 'y': u32
1680 117..118 'x': bool
1681 127..132 'clone': fn clone<bool>(&bool) -> bool
1682 127..135 'clone(z)': bool
1683 133..134 'z': &bool
1684 141..151 'id::<i128>': fn id<i128>(i128) -> i128
1685 141..154 'id::<i128>(1)': i128
1686 152..153 '1': i128
1687 "#]],
1688 );
1689 }
1690
1691 #[test]
infer_const()1692 fn infer_const() {
1693 check_infer(
1694 r#"
1695 struct Foo;
1696 impl Foo { const ASSOC_CONST: u32 = 0; }
1697 const GLOBAL_CONST: u32 = 101;
1698 fn test() {
1699 const LOCAL_CONST: u32 = 99;
1700 let x = LOCAL_CONST;
1701 let z = GLOBAL_CONST;
1702 let id = Foo::ASSOC_CONST;
1703 }
1704 "#,
1705 expect![[r#"
1706 48..49 '0': u32
1707 79..82 '101': u32
1708 94..212 '{ ...NST; }': ()
1709 137..138 'x': u32
1710 141..152 'LOCAL_CONST': u32
1711 162..163 'z': u32
1712 166..178 'GLOBAL_CONST': u32
1713 188..190 'id': u32
1714 193..209 'Foo::A..._CONST': u32
1715 125..127 '99': u32
1716 "#]],
1717 );
1718 }
1719
1720 #[test]
infer_static()1721 fn infer_static() {
1722 check_infer(
1723 r#"
1724 static GLOBAL_STATIC: u32 = 101;
1725 static mut GLOBAL_STATIC_MUT: u32 = 101;
1726 fn test() {
1727 static LOCAL_STATIC: u32 = 99;
1728 static mut LOCAL_STATIC_MUT: u32 = 99;
1729 let x = LOCAL_STATIC;
1730 let y = LOCAL_STATIC_MUT;
1731 let z = GLOBAL_STATIC;
1732 let w = GLOBAL_STATIC_MUT;
1733 }
1734 "#,
1735 expect![[r#"
1736 28..31 '101': u32
1737 69..72 '101': u32
1738 84..279 '{ ...MUT; }': ()
1739 172..173 'x': u32
1740 176..188 'LOCAL_STATIC': u32
1741 198..199 'y': u32
1742 202..218 'LOCAL_...IC_MUT': u32
1743 228..229 'z': u32
1744 232..245 'GLOBAL_STATIC': u32
1745 255..256 'w': u32
1746 259..276 'GLOBAL...IC_MUT': u32
1747 117..119 '99': u32
1748 160..162 '99': u32
1749 "#]],
1750 );
1751 }
1752
1753 #[test]
infer_enum_variant()1754 fn infer_enum_variant() {
1755 check_infer(
1756 r#"
1757 enum Foo {
1758 A = 15,
1759 B = Foo::A as isize + 1
1760 }
1761 "#,
1762 expect![[r#"
1763 19..21 '15': isize
1764 31..37 'Foo::A': Foo
1765 31..46 'Foo::A as isize': isize
1766 31..50 'Foo::A...ze + 1': isize
1767 49..50 '1': isize
1768 "#]],
1769 );
1770 check_infer(
1771 r#"
1772 #[repr(u32)]
1773 enum Foo {
1774 A = 15,
1775 B = Foo::A as u32 + 1
1776 }
1777 "#,
1778 expect![[r#"
1779 32..34 '15': u32
1780 44..50 'Foo::A': Foo
1781 44..57 'Foo::A as u32': u32
1782 44..61 'Foo::A...32 + 1': u32
1783 60..61 '1': u32
1784 "#]],
1785 );
1786 }
1787
1788 #[test]
shadowing_primitive()1789 fn shadowing_primitive() {
1790 check_types(
1791 r#"
1792 struct i32;
1793 struct Foo;
1794
1795 impl i32 { fn foo(&self) -> Foo { Foo } }
1796
1797 fn main() {
1798 let x: i32 = i32;
1799 x.foo();
1800 //^^^^^^^ Foo
1801 }"#,
1802 );
1803 }
1804
1805 #[test]
const_eval_array_repeat_expr()1806 fn const_eval_array_repeat_expr() {
1807 check_types(
1808 r#"
1809 fn main() {
1810 const X: usize = 6 - 1;
1811 let t = [(); X + 2];
1812 //^ [(); 7]
1813 }"#,
1814 );
1815 check_types(
1816 r#"
1817 trait Foo {
1818 fn x(self);
1819 }
1820
1821 impl Foo for u8 {
1822 fn x(self) {
1823 let t = [0; 4 + 2];
1824 //^ [i32; 6]
1825 }
1826 }
1827 "#,
1828 );
1829 }
1830
1831 #[test]
const_eval_in_function_signature()1832 fn const_eval_in_function_signature() {
1833 check_types(
1834 r#"
1835 const fn foo() -> usize {
1836 5
1837 }
1838
1839 fn f() -> [u8; foo()] {
1840 loop {}
1841 }
1842
1843 fn main() {
1844 let t = f();
1845 //^ [u8; 5]
1846 }"#,
1847 );
1848 check_types(
1849 r#"
1850 //- minicore: default, builtin_impls
1851 fn f() -> [u8; Default::default()] {
1852 loop {}
1853 }
1854
1855 fn main() {
1856 let t = f();
1857 //^ [u8; 0]
1858 }
1859 "#,
1860 );
1861 }
1862
1863 #[test]
shadowing_primitive_with_inner_items()1864 fn shadowing_primitive_with_inner_items() {
1865 check_types(
1866 r#"
1867 struct i32;
1868 struct Foo;
1869
1870 impl i32 { fn foo(&self) -> Foo { Foo } }
1871
1872 fn main() {
1873 fn inner() {}
1874 let x: i32 = i32;
1875 x.foo();
1876 //^^^^^^^ Foo
1877 }"#,
1878 );
1879 }
1880
1881 #[test]
not_shadowing_primitive_by_module()1882 fn not_shadowing_primitive_by_module() {
1883 check_types(
1884 r#"
1885 //- /str.rs
1886 fn foo() {}
1887
1888 //- /main.rs
1889 mod str;
1890 fn foo() -> &'static str { "" }
1891
1892 fn main() {
1893 foo();
1894 //^^^^^ &str
1895 }"#,
1896 );
1897 }
1898
1899 #[test]
not_shadowing_module_by_primitive()1900 fn not_shadowing_module_by_primitive() {
1901 check_types(
1902 r#"
1903 //- /str.rs
1904 pub fn foo() -> u32 {0}
1905
1906 //- /main.rs
1907 mod str;
1908 fn foo() -> &'static str { "" }
1909
1910 fn main() {
1911 str::foo();
1912 //^^^^^^^^^^ u32
1913 }"#,
1914 );
1915 }
1916
1917 // This test is actually testing the shadowing behavior within hir_def. It
1918 // lives here because the testing infrastructure in hir_def isn't currently
1919 // capable of asserting the necessary conditions.
1920 #[test]
should_be_shadowing_imports()1921 fn should_be_shadowing_imports() {
1922 check_types(
1923 r#"
1924 mod a {
1925 pub fn foo() -> i8 {0}
1926 pub struct foo { a: i8 }
1927 }
1928 mod b { pub fn foo () -> u8 {0} }
1929 mod c { pub struct foo { a: u8 } }
1930 mod d {
1931 pub use super::a::*;
1932 pub use super::c::foo;
1933 pub use super::b::foo;
1934 }
1935
1936 fn main() {
1937 d::foo();
1938 //^^^^^^^^ u8
1939 d::foo{a:0};
1940 //^^^^^^^^^^^ foo
1941 }"#,
1942 );
1943 }
1944
1945 #[test]
closure_return()1946 fn closure_return() {
1947 check_infer(
1948 r#"
1949 fn foo() -> u32 {
1950 let x = || -> usize { return 1; };
1951 }
1952 "#,
1953 expect![[r#"
1954 16..58 '{ ...; }; }': u32
1955 26..27 'x': impl Fn() -> usize
1956 30..55 '|| -> ...n 1; }': impl Fn() -> usize
1957 42..55 '{ return 1; }': usize
1958 44..52 'return 1': !
1959 51..52 '1': usize
1960 "#]],
1961 );
1962 }
1963
1964 #[test]
closure_return_unit()1965 fn closure_return_unit() {
1966 check_infer(
1967 r#"
1968 fn foo() -> u32 {
1969 let x = || { return; };
1970 }
1971 "#,
1972 expect![[r#"
1973 16..47 '{ ...; }; }': u32
1974 26..27 'x': impl Fn()
1975 30..44 '|| { return; }': impl Fn()
1976 33..44 '{ return; }': ()
1977 35..41 'return': !
1978 "#]],
1979 );
1980 }
1981
1982 #[test]
closure_return_inferred()1983 fn closure_return_inferred() {
1984 check_infer(
1985 r#"
1986 fn foo() -> u32 {
1987 let x = || { "test" };
1988 }
1989 "#,
1990 expect![[r#"
1991 16..46 '{ ..." }; }': u32
1992 26..27 'x': impl Fn() -> &str
1993 30..43 '|| { "test" }': impl Fn() -> &str
1994 33..43 '{ "test" }': &str
1995 35..41 '"test"': &str
1996 "#]],
1997 );
1998 }
1999
2000 #[test]
generator_types_inferred()2001 fn generator_types_inferred() {
2002 check_infer(
2003 r#"
2004 //- minicore: generator, deref
2005 use core::ops::{Generator, GeneratorState};
2006 use core::pin::Pin;
2007
2008 fn f(v: i64) {}
2009 fn test() {
2010 let mut g = |r| {
2011 let a = yield 0;
2012 let a = yield 1;
2013 let a = yield 2;
2014 "return value"
2015 };
2016
2017 match Pin::new(&mut g).resume(0usize) {
2018 GeneratorState::Yielded(y) => { f(y); }
2019 GeneratorState::Complete(r) => {}
2020 }
2021 }
2022 "#,
2023 expect![[r#"
2024 70..71 'v': i64
2025 78..80 '{}': ()
2026 91..362 '{ ... } }': ()
2027 101..106 'mut g': |usize| yields i64 -> &str
2028 109..218 '|r| { ... }': |usize| yields i64 -> &str
2029 110..111 'r': usize
2030 113..218 '{ ... }': &str
2031 127..128 'a': usize
2032 131..138 'yield 0': usize
2033 137..138 '0': i64
2034 152..153 'a': usize
2035 156..163 'yield 1': usize
2036 162..163 '1': i64
2037 177..178 'a': usize
2038 181..188 'yield 2': usize
2039 187..188 '2': i64
2040 198..212 '"return value"': &str
2041 225..360 'match ... }': ()
2042 231..239 'Pin::new': fn new<&mut |usize| yields i64 -> &str>(&mut |usize| yields i64 -> &str) -> Pin<&mut |usize| yields i64 -> &str>
2043 231..247 'Pin::n...mut g)': Pin<&mut |usize| yields i64 -> &str>
2044 231..262 'Pin::n...usize)': GeneratorState<i64, &str>
2045 240..246 '&mut g': &mut |usize| yields i64 -> &str
2046 245..246 'g': |usize| yields i64 -> &str
2047 255..261 '0usize': usize
2048 273..299 'Genera...ded(y)': GeneratorState<i64, &str>
2049 297..298 'y': i64
2050 303..312 '{ f(y); }': ()
2051 305..306 'f': fn f(i64)
2052 305..309 'f(y)': ()
2053 307..308 'y': i64
2054 321..348 'Genera...ete(r)': GeneratorState<i64, &str>
2055 346..347 'r': &str
2056 352..354 '{}': ()
2057 "#]],
2058 );
2059 }
2060
2061 #[test]
generator_resume_yield_return_unit()2062 fn generator_resume_yield_return_unit() {
2063 check_no_mismatches(
2064 r#"
2065 //- minicore: generator, deref
2066 use core::ops::{Generator, GeneratorState};
2067 use core::pin::Pin;
2068 fn test() {
2069 let mut g = || {
2070 let () = yield;
2071 };
2072
2073 match Pin::new(&mut g).resume(()) {
2074 GeneratorState::Yielded(()) => {}
2075 GeneratorState::Complete(()) => {}
2076 }
2077 }
2078 "#,
2079 );
2080 }
2081
2082 #[test]
tuple_pattern_nested_match_ergonomics()2083 fn tuple_pattern_nested_match_ergonomics() {
2084 check_no_mismatches(
2085 r#"
2086 fn f(x: (&i32, &i32)) -> i32 {
2087 match x {
2088 (3, 4) => 5,
2089 _ => 12,
2090 }
2091 }
2092 "#,
2093 );
2094 check_types(
2095 r#"
2096 fn f(x: (&&&&i32, &&&i32)) {
2097 let f = match x {
2098 t @ (3, 4) => t,
2099 _ => loop {},
2100 };
2101 f;
2102 //^ (&&&&i32, &&&i32)
2103 }
2104 "#,
2105 );
2106 check_types(
2107 r#"
2108 fn f() {
2109 let x = &&&(&&&2, &&&&&3);
2110 let (y, z) = x;
2111 //^ &&&&i32
2112 let t @ (y, z) = x;
2113 t;
2114 //^ &&&(&&&i32, &&&&&i32)
2115 }
2116 "#,
2117 );
2118 check_types(
2119 r#"
2120 fn f() {
2121 let x = &&&(&&&2, &&&&&3);
2122 let (y, z) = x;
2123 //^ &&&&i32
2124 let t @ (y, z) = x;
2125 t;
2126 //^ &&&(&&&i32, &&&&&i32)
2127 }
2128 "#,
2129 );
2130 }
2131
2132 #[test]
fn_pointer_return()2133 fn fn_pointer_return() {
2134 check_infer(
2135 r#"
2136 struct Vtable {
2137 method: fn(),
2138 }
2139
2140 fn main() {
2141 let vtable = Vtable { method: || {} };
2142 let m = vtable.method;
2143 }
2144 "#,
2145 expect![[r#"
2146 47..120 '{ ...hod; }': ()
2147 57..63 'vtable': Vtable
2148 66..90 'Vtable...| {} }': Vtable
2149 83..88 '|| {}': impl Fn()
2150 86..88 '{}': ()
2151 100..101 'm': fn()
2152 104..110 'vtable': Vtable
2153 104..117 'vtable.method': fn()
2154 "#]],
2155 );
2156 }
2157
2158 #[test]
block_modifiers_smoke_test()2159 fn block_modifiers_smoke_test() {
2160 check_infer(
2161 r#"
2162 //- minicore: future, try
2163 async fn main() {
2164 let x = unsafe { 92 };
2165 let y = async { async { () }.await };
2166 let z: core::ops::ControlFlow<(), _> = try { () };
2167 let w = const { 92 };
2168 let t = 'a: { 92 };
2169 }
2170 "#,
2171 expect![[r#"
2172 16..193 '{ ...2 }; }': ()
2173 26..27 'x': i32
2174 30..43 'unsafe { 92 }': i32
2175 39..41 '92': i32
2176 53..54 'y': impl Future<Output = ()>
2177 57..85 'async ...wait }': impl Future<Output = ()>
2178 65..77 'async { () }': impl Future<Output = ()>
2179 65..83 'async ....await': ()
2180 73..75 '()': ()
2181 95..96 'z': ControlFlow<(), ()>
2182 130..140 'try { () }': ControlFlow<(), ()>
2183 136..138 '()': ()
2184 150..151 'w': i32
2185 154..166 'const { 92 }': i32
2186 154..166 'const { 92 }': i32
2187 162..164 '92': i32
2188 176..177 't': i32
2189 180..190 ''a: { 92 }': i32
2190 186..188 '92': i32
2191 "#]],
2192 )
2193 }
2194
2195 #[test]
async_fn_and_try_operator()2196 fn async_fn_and_try_operator() {
2197 check_no_mismatches(
2198 r#"
2199 //- minicore: future, result, fn, try, from
2200 async fn foo() -> Result<(), ()> {
2201 Ok(())
2202 }
2203
2204 async fn bar() -> Result<(), ()> {
2205 let x = foo().await?;
2206 Ok(x)
2207 }
2208 "#,
2209 )
2210 }
2211
2212 #[test]
async_block_early_return()2213 fn async_block_early_return() {
2214 check_infer(
2215 r#"
2216 //- minicore: future, result, fn
2217 fn test<I, E, F: FnMut() -> Fut, Fut: core::future::Future<Output = Result<I, E>>>(f: F) {}
2218
2219 fn main() {
2220 async {
2221 return Err(());
2222 Ok(())
2223 };
2224 test(|| async {
2225 return Err(());
2226 Ok(())
2227 });
2228 }
2229 "#,
2230 expect![[r#"
2231 83..84 'f': F
2232 89..91 '{}': ()
2233 103..231 '{ ... }); }': ()
2234 109..161 'async ... }': impl Future<Output = Result<(), ()>>
2235 125..139 'return Err(())': !
2236 132..135 'Err': Err<(), ()>(()) -> Result<(), ()>
2237 132..139 'Err(())': Result<(), ()>
2238 136..138 '()': ()
2239 149..151 'Ok': Ok<(), ()>(()) -> Result<(), ()>
2240 149..155 'Ok(())': Result<(), ()>
2241 152..154 '()': ()
2242 167..171 'test': fn test<(), (), impl Fn() -> impl Future<Output = Result<(), ()>>, impl Future<Output = Result<(), ()>>>(impl Fn() -> impl Future<Output = Result<(), ()>>)
2243 167..228 'test(|... })': ()
2244 172..227 '|| asy... }': impl Fn() -> impl Future<Output = Result<(), ()>>
2245 175..227 'async ... }': impl Future<Output = Result<(), ()>>
2246 191..205 'return Err(())': !
2247 198..201 'Err': Err<(), ()>(()) -> Result<(), ()>
2248 198..205 'Err(())': Result<(), ()>
2249 202..204 '()': ()
2250 215..217 'Ok': Ok<(), ()>(()) -> Result<(), ()>
2251 215..221 'Ok(())': Result<(), ()>
2252 218..220 '()': ()
2253 "#]],
2254 )
2255 }
2256
2257 #[test]
infer_generic_from_later_assignment()2258 fn infer_generic_from_later_assignment() {
2259 check_infer(
2260 r#"
2261 enum Option<T> { Some(T), None }
2262 use Option::*;
2263
2264 fn test() {
2265 let mut end = None;
2266 loop {
2267 end = Some(true);
2268 }
2269 }
2270 "#,
2271 expect![[r#"
2272 59..129 '{ ... } }': ()
2273 69..76 'mut end': Option<bool>
2274 79..83 'None': Option<bool>
2275 89..127 'loop {... }': !
2276 94..127 '{ ... }': ()
2277 104..107 'end': Option<bool>
2278 104..120 'end = ...(true)': ()
2279 110..114 'Some': Some<bool>(bool) -> Option<bool>
2280 110..120 'Some(true)': Option<bool>
2281 115..119 'true': bool
2282 "#]],
2283 );
2284 }
2285
2286 #[test]
infer_loop_break_with_val()2287 fn infer_loop_break_with_val() {
2288 check_infer(
2289 r#"
2290 enum Option<T> { Some(T), None }
2291 use Option::*;
2292
2293 fn test() {
2294 let x = loop {
2295 if false {
2296 break None;
2297 }
2298
2299 break Some(true);
2300 };
2301 }
2302 "#,
2303 expect![[r#"
2304 59..168 '{ ... }; }': ()
2305 69..70 'x': Option<bool>
2306 73..165 'loop {... }': Option<bool>
2307 78..165 '{ ... }': ()
2308 88..132 'if fal... }': ()
2309 91..96 'false': bool
2310 97..132 '{ ... }': ()
2311 111..121 'break None': !
2312 117..121 'None': Option<bool>
2313 142..158 'break ...(true)': !
2314 148..152 'Some': Some<bool>(bool) -> Option<bool>
2315 148..158 'Some(true)': Option<bool>
2316 153..157 'true': bool
2317 "#]],
2318 );
2319 }
2320
2321 #[test]
infer_loop_break_without_val()2322 fn infer_loop_break_without_val() {
2323 check_infer(
2324 r#"
2325 enum Option<T> { Some(T), None }
2326 use Option::*;
2327
2328 fn test() {
2329 let x = loop {
2330 if false {
2331 break;
2332 }
2333 };
2334 }
2335 "#,
2336 expect![[r#"
2337 59..136 '{ ... }; }': ()
2338 69..70 'x': ()
2339 73..133 'loop {... }': ()
2340 78..133 '{ ... }': ()
2341 88..127 'if fal... }': ()
2342 91..96 'false': bool
2343 97..127 '{ ... }': ()
2344 111..116 'break': !
2345 "#]],
2346 );
2347 }
2348
2349 #[test]
infer_labelled_break_with_val()2350 fn infer_labelled_break_with_val() {
2351 check_infer(
2352 r#"
2353 fn foo() {
2354 let _x = || 'outer: loop {
2355 let inner = 'inner: loop {
2356 let i = Default::default();
2357 if (break 'outer i) {
2358 loop { break 'inner 5i8; };
2359 } else if true {
2360 break 'inner 6;
2361 }
2362 break 7;
2363 };
2364 break inner < 8;
2365 };
2366 }
2367 "#,
2368 expect![[r#"
2369 9..335 '{ ... }; }': ()
2370 19..21 '_x': impl Fn() -> bool
2371 24..332 '|| 'ou... }': impl Fn() -> bool
2372 27..332 ''outer... }': bool
2373 40..332 '{ ... }': ()
2374 54..59 'inner': i8
2375 62..300 ''inner... }': i8
2376 75..300 '{ ... }': ()
2377 93..94 'i': bool
2378 97..113 'Defaul...efault': {unknown}
2379 97..115 'Defaul...ault()': bool
2380 129..269 'if (br... }': ()
2381 133..147 'break 'outer i': !
2382 146..147 'i': bool
2383 149..208 '{ ... }': ()
2384 167..193 'loop {...5i8; }': !
2385 172..193 '{ brea...5i8; }': ()
2386 174..190 'break ...er 5i8': !
2387 187..190 '5i8': i8
2388 214..269 'if tru... }': ()
2389 217..221 'true': bool
2390 222..269 '{ ... }': ()
2391 240..254 'break 'inner 6': !
2392 253..254 '6': i8
2393 282..289 'break 7': !
2394 288..289 '7': i8
2395 310..325 'break inner < 8': !
2396 316..321 'inner': i8
2397 316..325 'inner < 8': bool
2398 324..325 '8': i8
2399 "#]],
2400 );
2401 }
2402
2403 #[test]
infer_labelled_block_break_with_val()2404 fn infer_labelled_block_break_with_val() {
2405 check_infer(
2406 r#"
2407 fn default<T>() -> T { loop {} }
2408 fn foo() {
2409 let _x = 'outer: {
2410 let inner = 'inner: {
2411 let i = default();
2412 if (break 'outer i) {
2413 break 'inner 5i8;
2414 } else if true {
2415 break 'inner 6;
2416 }
2417 break 'inner 'innermost: { 0 };
2418 42
2419 };
2420 break 'outer inner < 8;
2421 };
2422 }
2423 "#,
2424 expect![[r#"
2425 21..32 '{ loop {} }': T
2426 23..30 'loop {}': !
2427 28..30 '{}': ()
2428 42..381 '{ ... }; }': ()
2429 52..54 '_x': bool
2430 57..378 ''outer... }': bool
2431 79..84 'inner': i8
2432 87..339 ''inner... }': i8
2433 113..114 'i': bool
2434 117..124 'default': fn default<bool>() -> bool
2435 117..126 'default()': bool
2436 140..270 'if (br... }': ()
2437 144..158 'break 'outer i': !
2438 157..158 'i': bool
2439 160..209 '{ ... }': ()
2440 178..194 'break ...er 5i8': !
2441 191..194 '5i8': i8
2442 215..270 'if tru... }': ()
2443 218..222 'true': bool
2444 223..270 '{ ... }': ()
2445 241..255 'break 'inner 6': !
2446 254..255 '6': i8
2447 283..313 'break ... { 0 }': !
2448 296..313 ''inner... { 0 }': i8
2449 310..311 '0': i8
2450 327..329 '42': i8
2451 349..371 'break ...er < 8': !
2452 362..367 'inner': i8
2453 362..371 'inner < 8': bool
2454 370..371 '8': i8
2455 "#]],
2456 );
2457 }
2458
2459 #[test]
generic_default()2460 fn generic_default() {
2461 check_infer(
2462 r#"
2463 struct Thing<T = ()> { t: T }
2464 enum OtherThing<T = ()> {
2465 One { t: T },
2466 Two(T),
2467 }
2468
2469 fn test(t1: Thing, t2: OtherThing, t3: Thing<i32>, t4: OtherThing<i32>) {
2470 t1.t;
2471 t3.t;
2472 match t2 {
2473 OtherThing::One { t } => { t; },
2474 OtherThing::Two(t) => { t; },
2475 }
2476 match t4 {
2477 OtherThing::One { t } => { t; },
2478 OtherThing::Two(t) => { t; },
2479 }
2480 }
2481 "#,
2482 expect![[r#"
2483 97..99 't1': Thing<()>
2484 108..110 't2': OtherThing<()>
2485 124..126 't3': Thing<i32>
2486 140..142 't4': OtherThing<i32>
2487 161..384 '{ ... } }': ()
2488 167..169 't1': Thing<()>
2489 167..171 't1.t': ()
2490 177..179 't3': Thing<i32>
2491 177..181 't3.t': i32
2492 187..282 'match ... }': ()
2493 193..195 't2': OtherThing<()>
2494 206..227 'OtherT... { t }': OtherThing<()>
2495 224..225 't': ()
2496 231..237 '{ t; }': ()
2497 233..234 't': ()
2498 247..265 'OtherT...Two(t)': OtherThing<()>
2499 263..264 't': ()
2500 269..275 '{ t; }': ()
2501 271..272 't': ()
2502 287..382 'match ... }': ()
2503 293..295 't4': OtherThing<i32>
2504 306..327 'OtherT... { t }': OtherThing<i32>
2505 324..325 't': i32
2506 331..337 '{ t; }': ()
2507 333..334 't': i32
2508 347..365 'OtherT...Two(t)': OtherThing<i32>
2509 363..364 't': i32
2510 369..375 '{ t; }': ()
2511 371..372 't': i32
2512 "#]],
2513 );
2514 }
2515
2516 #[test]
generic_default_in_struct_literal()2517 fn generic_default_in_struct_literal() {
2518 check_infer(
2519 r#"
2520 struct Thing<T = ()> { t: T }
2521 enum OtherThing<T = ()> {
2522 One { t: T },
2523 Two(T),
2524 }
2525
2526 fn test() {
2527 let x = Thing { t: loop {} };
2528 let y = Thing { t: () };
2529 let z = Thing { t: 1i32 };
2530 if let Thing { t } = z {
2531 t;
2532 }
2533
2534 let a = OtherThing::One { t: 1i32 };
2535 let b = OtherThing::Two(1i32);
2536 }
2537 "#,
2538 expect![[r#"
2539 99..319 '{ ...32); }': ()
2540 109..110 'x': Thing<!>
2541 113..133 'Thing ...p {} }': Thing<!>
2542 124..131 'loop {}': !
2543 129..131 '{}': ()
2544 143..144 'y': Thing<()>
2545 147..162 'Thing { t: () }': Thing<()>
2546 158..160 '()': ()
2547 172..173 'z': Thing<i32>
2548 176..193 'Thing ...1i32 }': Thing<i32>
2549 187..191 '1i32': i32
2550 199..240 'if let... }': ()
2551 202..221 'let Th... } = z': bool
2552 206..217 'Thing { t }': Thing<i32>
2553 214..215 't': i32
2554 220..221 'z': Thing<i32>
2555 222..240 '{ ... }': ()
2556 232..233 't': i32
2557 250..251 'a': OtherThing<i32>
2558 254..281 'OtherT...1i32 }': OtherThing<i32>
2559 275..279 '1i32': i32
2560 291..292 'b': OtherThing<i32>
2561 295..310 'OtherThing::Two': Two<i32>(i32) -> OtherThing<i32>
2562 295..316 'OtherT...(1i32)': OtherThing<i32>
2563 311..315 '1i32': i32
2564 "#]],
2565 );
2566 }
2567
2568 #[test]
generic_default_depending_on_other_type_arg()2569 fn generic_default_depending_on_other_type_arg() {
2570 // FIXME: the {unknown} is a bug
2571 check_infer(
2572 r#"
2573 struct Thing<T = u128, F = fn() -> T> { t: T }
2574
2575 fn test(t1: Thing<u32>, t2: Thing) {
2576 t1;
2577 t2;
2578 Thing::<_> { t: 1u32 };
2579 }
2580 "#,
2581 expect![[r#"
2582 56..58 't1': Thing<u32, fn() -> u32>
2583 72..74 't2': Thing<u128, fn() -> u128>
2584 83..130 '{ ...2 }; }': ()
2585 89..91 't1': Thing<u32, fn() -> u32>
2586 97..99 't2': Thing<u128, fn() -> u128>
2587 105..127 'Thing:...1u32 }': Thing<u32, fn() -> {unknown}>
2588 121..125 '1u32': u32
2589 "#]],
2590 );
2591 }
2592
2593 #[test]
generic_default_depending_on_other_type_arg_forward()2594 fn generic_default_depending_on_other_type_arg_forward() {
2595 // the {unknown} here is intentional, as defaults are not allowed to
2596 // refer to type parameters coming later
2597 check_infer(
2598 r#"
2599 struct Thing<F = fn() -> T, T = u128> { t: T }
2600
2601 fn test(t1: Thing) {
2602 t1;
2603 }
2604 "#,
2605 expect![[r#"
2606 56..58 't1': Thing<fn() -> {unknown}, u128>
2607 67..78 '{ t1; }': ()
2608 73..75 't1': Thing<fn() -> {unknown}, u128>
2609 "#]],
2610 );
2611 }
2612
2613 #[test]
infer_operator_overload()2614 fn infer_operator_overload() {
2615 check_types(
2616 r#"
2617 //- minicore: add
2618 struct V2([f32; 2]);
2619
2620 impl core::ops::Add<V2> for V2 {
2621 type Output = V2;
2622 }
2623
2624 fn test() {
2625 let va = V2([0.0, 1.0]);
2626 let vb = V2([0.0, 1.0]);
2627
2628 let r = va + vb;
2629 // ^^^^^^^ V2
2630 }
2631
2632 "#,
2633 );
2634 }
2635
2636 #[test]
infer_const_params()2637 fn infer_const_params() {
2638 check_infer(
2639 r#"
2640 fn foo<const FOO: usize>() {
2641 let bar = FOO;
2642 }
2643 "#,
2644 expect![[r#"
2645 27..49 '{ ...FOO; }': ()
2646 37..40 'bar': usize
2647 43..46 'FOO': usize
2648 "#]],
2649 );
2650 }
2651
2652 #[test]
infer_inner_type()2653 fn infer_inner_type() {
2654 check_infer(
2655 r#"
2656 fn foo() {
2657 struct S { field: u32 }
2658 let s = S { field: 0 };
2659 let f = s.field;
2660 }
2661 "#,
2662 expect![[r#"
2663 9..89 '{ ...eld; }': ()
2664 47..48 's': S
2665 51..65 'S { field: 0 }': S
2666 62..63 '0': u32
2667 75..76 'f': u32
2668 79..80 's': S
2669 79..86 's.field': u32
2670 "#]],
2671 );
2672 }
2673
2674 #[test]
infer_nested_inner_type()2675 fn infer_nested_inner_type() {
2676 check_infer(
2677 r#"
2678 fn foo() {
2679 {
2680 let s = S { field: 0 };
2681 let f = s.field;
2682 }
2683 struct S { field: u32 }
2684 }
2685 "#,
2686 expect![[r#"
2687 9..109 '{ ...32 } }': ()
2688 15..79 '{ ... }': ()
2689 29..30 's': S
2690 33..47 'S { field: 0 }': S
2691 44..45 '0': u32
2692 61..62 'f': u32
2693 65..66 's': S
2694 65..72 's.field': u32
2695 "#]],
2696 );
2697 }
2698
2699 #[test]
inner_use_enum_rename()2700 fn inner_use_enum_rename() {
2701 check_infer(
2702 r#"
2703 enum Request {
2704 Info
2705 }
2706
2707 fn f() {
2708 use Request as R;
2709
2710 let r = R::Info;
2711 match r {
2712 R::Info => {}
2713 }
2714 }
2715 "#,
2716 expect![[r#"
2717 34..123 '{ ... } }': ()
2718 67..68 'r': Request
2719 71..78 'R::Info': Request
2720 84..121 'match ... }': ()
2721 90..91 'r': Request
2722 102..109 'R::Info': Request
2723 113..115 '{}': ()
2724 "#]],
2725 )
2726 }
2727
2728 #[test]
box_into_vec()2729 fn box_into_vec() {
2730 check_infer(
2731 r#"
2732 #[lang = "sized"]
2733 pub trait Sized {}
2734
2735 #[lang = "unsize"]
2736 pub trait Unsize<T: ?Sized> {}
2737
2738 #[lang = "coerce_unsized"]
2739 pub trait CoerceUnsized<T> {}
2740
2741 pub unsafe trait Allocator {}
2742
2743 pub struct Global;
2744 unsafe impl Allocator for Global {}
2745
2746 #[lang = "owned_box"]
2747 #[fundamental]
2748 pub struct Box<T: ?Sized, A: Allocator = Global>;
2749
2750 impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
2751
2752 pub struct Vec<T, A: Allocator = Global> {}
2753
2754 #[lang = "slice"]
2755 impl<T> [T] {}
2756
2757 #[lang = "slice_alloc"]
2758 impl<T> [T] {
2759 #[rustc_allow_incoherent_impl]
2760 pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
2761 unimplemented!()
2762 }
2763 }
2764
2765 fn test() {
2766 let vec = <[_]>::into_vec(box [1i32]);
2767 let v: Vec<Box<dyn B>> = <[_]> :: into_vec(box [box Astruct]);
2768 }
2769
2770 trait B{}
2771 struct Astruct;
2772 impl B for Astruct {}
2773 "#,
2774 expect![[r#"
2775 604..608 'self': Box<[T], A>
2776 637..669 '{ ... }': Vec<T, A>
2777 683..796 '{ ...t]); }': ()
2778 693..696 'vec': Vec<i32, Global>
2779 699..714 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global>
2780 699..726 '<[_]>:...1i32])': Vec<i32, Global>
2781 715..725 'box [1i32]': Box<[i32; 1], Global>
2782 719..725 '[1i32]': [i32; 1]
2783 720..724 '1i32': i32
2784 736..737 'v': Vec<Box<dyn B, Global>, Global>
2785 757..774 '<[_]> ...to_vec': fn into_vec<Box<dyn B, Global>, Global>(Box<[Box<dyn B, Global>], Global>) -> Vec<Box<dyn B, Global>, Global>
2786 757..793 '<[_]> ...ruct])': Vec<Box<dyn B, Global>, Global>
2787 775..792 'box [b...truct]': Box<[Box<dyn B, Global>; 1], Global>
2788 779..792 '[box Astruct]': [Box<dyn B, Global>; 1]
2789 780..791 'box Astruct': Box<Astruct, Global>
2790 784..791 'Astruct': Astruct
2791 "#]],
2792 )
2793 }
2794
2795 #[test]
capture_kinds_simple()2796 fn capture_kinds_simple() {
2797 check_types(
2798 r#"
2799 struct S;
2800
2801 impl S {
2802 fn read(&self) -> &S { self }
2803 fn write(&mut self) -> &mut S { self }
2804 fn consume(self) -> S { self }
2805 }
2806
2807 fn f() {
2808 let x = S;
2809 let c1 = || x.read();
2810 //^^ impl Fn() -> &S
2811 let c2 = || x.write();
2812 //^^ impl FnMut() -> &mut S
2813 let c3 = || x.consume();
2814 //^^ impl FnOnce() -> S
2815 let c3 = || x.consume().consume().consume();
2816 //^^ impl FnOnce() -> S
2817 let c3 = || x.consume().write().read();
2818 //^^ impl FnOnce() -> &S
2819 let x = &mut x;
2820 let c1 = || x.write();
2821 //^^ impl FnMut() -> &mut S
2822 let x = S;
2823 let c1 = || { let ref t = x; t };
2824 //^^ impl Fn() -> &S
2825 let c2 = || { let ref mut t = x; t };
2826 //^^ impl FnMut() -> &mut S
2827 let c3 = || { let t = x; t };
2828 //^^ impl FnOnce() -> S
2829 }
2830 "#,
2831 )
2832 }
2833
2834 #[test]
capture_kinds_closure()2835 fn capture_kinds_closure() {
2836 check_types(
2837 r#"
2838 //- minicore: copy, fn
2839 fn f() {
2840 let mut x = 2;
2841 x = 5;
2842 let mut c1 = || { x = 3; x };
2843 //^^^^^^ impl FnMut() -> i32
2844 let mut c2 = || { c1() };
2845 //^^^^^^ impl FnMut() -> i32
2846 let mut c1 = || { x };
2847 //^^^^^^ impl Fn() -> i32
2848 let mut c2 = || { c1() };
2849 //^^^^^^ impl Fn() -> i32
2850 struct X;
2851 let x = X;
2852 let mut c1 = || { x };
2853 //^^^^^^ impl FnOnce() -> X
2854 let mut c2 = || { c1() };
2855 //^^^^^^ impl FnOnce() -> X
2856 }
2857 "#,
2858 );
2859 }
2860
2861 #[test]
capture_kinds_overloaded_deref()2862 fn capture_kinds_overloaded_deref() {
2863 check_types(
2864 r#"
2865 //- minicore: fn, deref_mut
2866 use core::ops::{Deref, DerefMut};
2867
2868 struct Foo;
2869 impl Deref for Foo {
2870 type Target = (i32, u8);
2871 fn deref(&self) -> &(i32, u8) {
2872 &(5, 2)
2873 }
2874 }
2875 impl DerefMut for Foo {
2876 fn deref_mut(&mut self) -> &mut (i32, u8) {
2877 &mut (5, 2)
2878 }
2879 }
2880 fn test() {
2881 let mut x = Foo;
2882 let c1 = || *x;
2883 //^^ impl Fn() -> (i32, u8)
2884 let c2 = || { *x = (2, 5); };
2885 //^^ impl FnMut()
2886 let c3 = || { x.1 };
2887 //^^ impl Fn() -> u8
2888 let c4 = || { x.1 = 6; };
2889 //^^ impl FnMut()
2890 }
2891 "#,
2892 );
2893 }
2894
2895 #[test]
capture_kinds_with_copy_types()2896 fn capture_kinds_with_copy_types() {
2897 check_types(
2898 r#"
2899 //- minicore: copy, clone, derive
2900 #[derive(Clone, Copy)]
2901 struct Copy;
2902 struct NotCopy;
2903 #[derive(Clone, Copy)]
2904 struct Generic<T>(T);
2905
2906 trait Tr {
2907 type Assoc;
2908 }
2909
2910 impl Tr for Copy {
2911 type Assoc = NotCopy;
2912 }
2913
2914 #[derive(Clone, Copy)]
2915 struct AssocGeneric<T: Tr>(T::Assoc);
2916
2917 fn f() {
2918 let a = Copy;
2919 let b = NotCopy;
2920 let c = Generic(Copy);
2921 let d = Generic(NotCopy);
2922 let e: AssocGeneric<Copy> = AssocGeneric(NotCopy);
2923 let c1 = || a;
2924 //^^ impl Fn() -> Copy
2925 let c2 = || b;
2926 //^^ impl FnOnce() -> NotCopy
2927 let c3 = || c;
2928 //^^ impl Fn() -> Generic<Copy>
2929 let c3 = || d;
2930 //^^ impl FnOnce() -> Generic<NotCopy>
2931 let c3 = || e;
2932 //^^ impl FnOnce() -> AssocGeneric<Copy>
2933 }
2934 "#,
2935 )
2936 }
2937
2938 #[test]
derive_macro_should_work_for_associated_type()2939 fn derive_macro_should_work_for_associated_type() {
2940 check_types(
2941 r#"
2942 //- minicore: copy, clone, derive
2943 #[derive(Clone)]
2944 struct X;
2945 #[derive(Clone)]
2946 struct Y;
2947
2948 trait Tr {
2949 type Assoc;
2950 }
2951
2952 impl Tr for X {
2953 type Assoc = Y;
2954 }
2955
2956 #[derive(Clone)]
2957 struct AssocGeneric<T: Tr>(T::Assoc);
2958
2959 fn f() {
2960 let e: AssocGeneric<X> = AssocGeneric(Y);
2961 let e_clone = e.clone();
2962 //^^^^^^^ AssocGeneric<X>
2963 }
2964 "#,
2965 )
2966 }
2967
2968 #[test]
cfgd_out_assoc_items()2969 fn cfgd_out_assoc_items() {
2970 check_types(
2971 r#"
2972 struct S;
2973
2974 impl S {
2975 #[cfg(FALSE)]
2976 const C: S = S;
2977 }
2978
2979 fn f() {
2980 S::C;
2981 //^^^^ {unknown}
2982 }
2983 "#,
2984 )
2985 }
2986
2987 #[test]
infer_ref_to_raw_cast()2988 fn infer_ref_to_raw_cast() {
2989 check_types(
2990 r#"
2991 struct S;
2992
2993 fn f() {
2994 let s = &mut S;
2995 let s = s as *mut _;
2996 //^ *mut S
2997 }
2998 "#,
2999 );
3000 }
3001
3002 #[test]
infer_missing_type()3003 fn infer_missing_type() {
3004 check_types(
3005 r#"
3006 struct S;
3007
3008 fn f() {
3009 let s: = S;
3010 //^ S
3011 }
3012 "#,
3013 );
3014 }
3015
3016 #[test]
infer_type_alias_variant()3017 fn infer_type_alias_variant() {
3018 check_infer(
3019 r#"
3020 type Qux = Foo;
3021 enum Foo {
3022 Bar(i32),
3023 Baz { baz: f32 }
3024 }
3025
3026 fn f() {
3027 match Foo::Bar(3) {
3028 Qux::Bar(bar) => (),
3029 Qux::Baz { baz } => (),
3030 }
3031 }
3032 "#,
3033 expect![[r#"
3034 72..166 '{ ... } }': ()
3035 78..164 'match ... }': ()
3036 84..92 'Foo::Bar': Bar(i32) -> Foo
3037 84..95 'Foo::Bar(3)': Foo
3038 93..94 '3': i32
3039 106..119 'Qux::Bar(bar)': Foo
3040 115..118 'bar': i32
3041 123..125 '()': ()
3042 135..151 'Qux::B... baz }': Foo
3043 146..149 'baz': f32
3044 155..157 '()': ()
3045 "#]],
3046 )
3047 }
3048
3049 #[test]
infer_boxed_self_receiver()3050 fn infer_boxed_self_receiver() {
3051 check_infer(
3052 r#"
3053 //- minicore: deref
3054 use core::ops::Deref;
3055
3056 struct Box<T>(T);
3057
3058 impl<T> Deref for Box<T> {
3059 type Target = T;
3060 fn deref(&self) -> &Self::Target;
3061 }
3062
3063 struct Foo<T>(T);
3064
3065 impl<T> Foo<T> {
3066 fn get_inner<'a>(self: &'a Box<Self>) -> &'a T {}
3067
3068 fn get_self<'a>(self: &'a Box<Self>) -> &'a Self {}
3069
3070 fn into_inner(self: Box<Self>) -> Self {}
3071 }
3072
3073 fn main() {
3074 let boxed = Box(Foo(0_i32));
3075
3076 let bad1 = boxed.get_inner();
3077 let good1 = Foo::get_inner(&boxed);
3078
3079 let bad2 = boxed.get_self();
3080 let good2 = Foo::get_self(&boxed);
3081
3082 let inner = boxed.into_inner();
3083 }
3084 "#,
3085 expect![[r#"
3086 104..108 'self': &Box<T>
3087 188..192 'self': &Box<Foo<T>>
3088 218..220 '{}': &T
3089 242..246 'self': &Box<Foo<T>>
3090 275..277 '{}': &Foo<T>
3091 297..301 'self': Box<Foo<T>>
3092 322..324 '{}': Foo<T>
3093 338..559 '{ ...r(); }': ()
3094 348..353 'boxed': Box<Foo<i32>>
3095 356..359 'Box': Box<Foo<i32>>(Foo<i32>) -> Box<Foo<i32>>
3096 356..371 'Box(Foo(0_i32))': Box<Foo<i32>>
3097 360..363 'Foo': Foo<i32>(i32) -> Foo<i32>
3098 360..370 'Foo(0_i32)': Foo<i32>
3099 364..369 '0_i32': i32
3100 382..386 'bad1': &i32
3101 389..394 'boxed': Box<Foo<i32>>
3102 389..406 'boxed....nner()': &i32
3103 416..421 'good1': &i32
3104 424..438 'Foo::get_inner': fn get_inner<i32>(&Box<Foo<i32>>) -> &i32
3105 424..446 'Foo::g...boxed)': &i32
3106 439..445 '&boxed': &Box<Foo<i32>>
3107 440..445 'boxed': Box<Foo<i32>>
3108 457..461 'bad2': &Foo<i32>
3109 464..469 'boxed': Box<Foo<i32>>
3110 464..480 'boxed....self()': &Foo<i32>
3111 490..495 'good2': &Foo<i32>
3112 498..511 'Foo::get_self': fn get_self<i32>(&Box<Foo<i32>>) -> &Foo<i32>
3113 498..519 'Foo::g...boxed)': &Foo<i32>
3114 512..518 '&boxed': &Box<Foo<i32>>
3115 513..518 'boxed': Box<Foo<i32>>
3116 530..535 'inner': Foo<i32>
3117 538..543 'boxed': Box<Foo<i32>>
3118 538..556 'boxed....nner()': Foo<i32>
3119 "#]],
3120 );
3121 }
3122
3123 #[test]
prelude_2015()3124 fn prelude_2015() {
3125 check_types(
3126 r#"
3127 //- /main.rs edition:2015 crate:main deps:core
3128 fn f() {
3129 Rust;
3130 //^^^^ Rust
3131 }
3132
3133 //- /core.rs crate:core
3134 pub mod prelude {
3135 pub mod rust_2015 {
3136 pub struct Rust;
3137 }
3138 }
3139 "#,
3140 );
3141 }
3142
3143 #[test]
legacy_const_generics()3144 fn legacy_const_generics() {
3145 check_no_mismatches(
3146 r#"
3147 #[rustc_legacy_const_generics(1, 3)]
3148 fn mixed<const N1: &'static str, const N2: bool>(
3149 a: u8,
3150 b: i8,
3151 ) {}
3152
3153 fn f() {
3154 mixed(0, "", -1, true);
3155 mixed::<"", true>(0, -1);
3156 }
3157 "#,
3158 );
3159 }
3160
3161 #[test]
destructuring_assignment_slice()3162 fn destructuring_assignment_slice() {
3163 check_types(
3164 r#"
3165 fn main() {
3166 let a;
3167 //^usize
3168 [a,] = [0usize];
3169
3170 let a;
3171 //^usize
3172 [a, ..] = [0usize; 5];
3173
3174 let a;
3175 //^usize
3176 [.., a] = [0usize; 5];
3177
3178 let a;
3179 //^usize
3180 [.., a, _] = [0usize; 5];
3181
3182 let a;
3183 //^usize
3184 [_, a, ..] = [0usize; 5];
3185
3186 let a: &mut i64 = &mut 0;
3187 [*a, ..] = [1, 2, 3];
3188
3189 let a: usize;
3190 let b;
3191 //^usize
3192 [a, _, b] = [3, 4, 5];
3193 //^usize
3194
3195 let a;
3196 //^i64
3197 let b;
3198 //^i64
3199 [[a, ..], .., [.., b]] = [[1, 2], [3i64, 4], [5, 6], [7, 8]];
3200 }
3201 "#,
3202 );
3203 }
3204
3205 #[test]
destructuring_assignment_tuple()3206 fn destructuring_assignment_tuple() {
3207 check_types(
3208 r#"
3209 fn main() {
3210 let a;
3211 //^char
3212 let b;
3213 //^i64
3214 (a, b) = ('c', 0i64);
3215
3216 let a;
3217 //^char
3218 (a, ..) = ('c', 0i64);
3219
3220 let a;
3221 //^i64
3222 (.., a) = ('c', 0i64);
3223
3224 let a;
3225 //^char
3226 let b;
3227 //^i64
3228 (a, .., b) = ('c', 0i64);
3229
3230 let a;
3231 //^char
3232 let b;
3233 //^bool
3234 (a, .., b) = ('c', 0i64, true);
3235
3236 let a;
3237 //^i64
3238 let b;
3239 //^bool
3240 (_, a, .., b) = ('c', 0i64, true);
3241
3242 let a;
3243 //^i64
3244 let b;
3245 //^usize
3246 (_, a, .., b) = ('c', 0i64, true, 0usize);
3247
3248 let mut a = 1;
3249 //^^^^^i64
3250 let mut b: i64 = 0;
3251 (a, b) = (b, a);
3252 }
3253 "#,
3254 );
3255 }
3256
3257 #[test]
destructuring_assignment_tuple_struct()3258 fn destructuring_assignment_tuple_struct() {
3259 check_types(
3260 r#"
3261 struct S2(char, i64);
3262 struct S3(char, i64, bool);
3263 struct S4(char, i64, bool usize);
3264 fn main() {
3265 let a;
3266 //^char
3267 let b;
3268 //^i64
3269 S2(a, b) = S2('c', 0i64);
3270
3271 let a;
3272 //^char
3273 let b;
3274 //^i64
3275 S2(a, .., b) = S2('c', 0i64);
3276
3277 let a;
3278 //^char
3279 let b;
3280 //^bool
3281 S3(a, .., b) = S3('c', 0i64, true);
3282
3283 let a;
3284 //^i64
3285 let b;
3286 //^bool
3287 S3(_, a, .., b) = S3('c', 0i64, true);
3288
3289 let a;
3290 //^i64
3291 let b;
3292 //^usize
3293 S4(_, a, .., b) = S4('c', 0i64, true, 0usize);
3294
3295 struct Swap(i64, i64);
3296
3297 let mut a = 1;
3298 //^^^^^i64
3299 let mut b = 0;
3300 //^^^^^i64
3301 Swap(a, b) = Swap(b, a);
3302 }
3303 "#,
3304 );
3305 }
3306
3307 #[test]
destructuring_assignment_struct()3308 fn destructuring_assignment_struct() {
3309 check_types(
3310 r#"
3311 struct S {
3312 a: usize,
3313 b: char,
3314 }
3315 struct T {
3316 s: S,
3317 t: i64,
3318 }
3319
3320 fn main() {
3321 let a;
3322 //^usize
3323 let c;
3324 //^char
3325 S { a, b: c } = S { a: 3, b: 'b' };
3326
3327 let a;
3328 //^char
3329 S { b: a, .. } = S { a: 3, b: 'b' };
3330
3331 let a;
3332 //^char
3333 S { b: a, _ } = S { a: 3, b: 'b' };
3334
3335 let a;
3336 //^usize
3337 let c;
3338 //^char
3339 let t;
3340 //^i64
3341 T { s: S { a, b: c }, t } = T { s: S { a: 3, b: 'b' }, t: 0 };
3342 }
3343 "#,
3344 );
3345 }
3346
3347 #[test]
destructuring_assignment_nested()3348 fn destructuring_assignment_nested() {
3349 check_types(
3350 r#"
3351 struct S {
3352 a: TS,
3353 b: [char; 3],
3354 }
3355 struct TS(usize, i64);
3356
3357 fn main() {
3358 let a;
3359 //^i32
3360 let b;
3361 //^bool
3362 ([.., a], .., b, _) = ([0, 1, 2], true, 'c');
3363
3364 let a;
3365 //^i32
3366 let b;
3367 //^i32
3368 [(.., a, _), .., (b, ..)] = [(1, 2); 5];
3369
3370 let a;
3371 //^usize
3372 let b;
3373 //^char
3374 S { a: TS(a, ..), b: [_, b, ..] } = S { a: TS(0, 0), b: ['a'; 3] };
3375 }
3376 "#,
3377 );
3378 }
3379
3380 #[test]
destructuring_assignment_unit_struct()3381 fn destructuring_assignment_unit_struct() {
3382 // taken from rustc; see https://github.com/rust-lang/rust/pull/95380
3383 check_no_mismatches(
3384 r#"
3385 struct S;
3386 enum E { V, }
3387 type A = E;
3388
3389 fn main() {
3390 let mut a;
3391
3392 (S, a) = (S, ());
3393
3394 (E::V, a) = (E::V, ());
3395
3396 (<E>::V, a) = (E::V, ());
3397 (A::V, a) = (E::V, ());
3398 }
3399
3400 impl S {
3401 fn check() {
3402 let a;
3403 (Self, a) = (S, ());
3404 }
3405 }
3406
3407 impl E {
3408 fn check() {
3409 let a;
3410 (Self::V, a) = (E::V, ());
3411 }
3412 }
3413 "#,
3414 );
3415 }
3416
3417 #[test]
destructuring_assignment_no_default_binding_mode()3418 fn destructuring_assignment_no_default_binding_mode() {
3419 check(
3420 r#"
3421 struct S { a: usize }
3422 struct TS(usize);
3423 fn main() {
3424 let x;
3425 [x,] = &[1,];
3426 //^^^^expected &[i32; 1], got [{unknown}; _]
3427
3428 // FIXME we only want the outermost error, but this matches the current
3429 // behavior of slice patterns
3430 let x;
3431 [(x,),] = &[(1,),];
3432 // ^^^^expected {unknown}, got ({unknown},)
3433 //^^^^^^^expected &[(i32,); 1], got [{unknown}; _]
3434
3435 let x;
3436 ((x,),) = &((1,),);
3437 //^^^^^^^expected &((i32,),), got (({unknown},),)
3438
3439 let x;
3440 (x,) = &(1,);
3441 //^^^^expected &(i32,), got ({unknown},)
3442
3443 let x;
3444 (S { a: x },) = &(S { a: 42 },);
3445 //^^^^^^^^^^^^^expected &(S,), got (S,)
3446
3447 let x;
3448 S { a: x } = &S { a: 42 };
3449 //^^^^^^^^^^expected &S, got S
3450
3451 let x;
3452 TS(x) = &TS(42);
3453 //^^^^^expected &TS, got TS
3454 }
3455 "#,
3456 );
3457 }
3458
3459 #[test]
destructuring_assignment_type_mismatch_on_identifier()3460 fn destructuring_assignment_type_mismatch_on_identifier() {
3461 check(
3462 r#"
3463 struct S { v: i64 }
3464 struct TS(i64);
3465 fn main() {
3466 let mut a: usize = 0;
3467 (a,) = (0i64,);
3468 //^expected i64, got usize
3469
3470 let mut a: usize = 0;
3471 [a,] = [0i64,];
3472 //^expected i64, got usize
3473
3474 let mut a: usize = 0;
3475 S { v: a } = S { v: 0 };
3476 //^expected i64, got usize
3477
3478 let mut a: usize = 0;
3479 TS(a) = TS(0);
3480 //^expected i64, got usize
3481 }
3482 "#,
3483 );
3484 }
3485
3486 #[test]
nested_break()3487 fn nested_break() {
3488 check_no_mismatches(
3489 r#"
3490 fn func() {
3491 let int = loop {
3492 break 0;
3493 break (break 0);
3494 };
3495 }
3496 "#,
3497 );
3498 }
3499
3500 #[test]
pointee_trait()3501 fn pointee_trait() {
3502 check_types(
3503 r#"
3504 //- minicore: pointee
3505 use core::ptr::Pointee;
3506 fn func() {
3507 let x: <u8 as Pointee>::Metadata;
3508 //^ ()
3509 let x: <[u8] as Pointee>::Metadata;
3510 //^ usize
3511 }
3512 "#,
3513 );
3514 }
3515
3516 // FIXME
3517 #[test]
castable_to()3518 fn castable_to() {
3519 check_infer(
3520 r#"
3521 //- minicore: sized
3522 #[lang = "owned_box"]
3523 pub struct Box<T: ?Sized> {
3524 inner: *mut T,
3525 }
3526 impl<T> Box<T> {
3527 fn new(t: T) -> Self { loop {} }
3528 }
3529
3530 fn func() {
3531 let x = Box::new([]) as Box<[i32; 0]>;
3532 }
3533 "#,
3534 expect![[r#"
3535 99..100 't': T
3536 113..124 '{ loop {} }': Box<T>
3537 115..122 'loop {}': !
3538 120..122 '{}': ()
3539 138..184 '{ ...0]>; }': ()
3540 148..149 'x': Box<[i32; 0]>
3541 152..160 'Box::new': fn new<[{unknown}; 0]>([{unknown}; 0]) -> Box<[{unknown}; 0]>
3542 152..164 'Box::new([])': Box<[{unknown}; 0]>
3543 152..181 'Box::n...2; 0]>': Box<[i32; 0]>
3544 161..163 '[]': [{unknown}; 0]
3545 "#]],
3546 );
3547 }
3548
3549 #[test]
castable_to1()3550 fn castable_to1() {
3551 check_infer(
3552 r#"
3553 struct Ark<T>(T);
3554 impl<T> Ark<T> {
3555 fn foo(&self) -> *const T {
3556 &self.0
3557 }
3558 }
3559 fn f<T>(t: Ark<T>) {
3560 Ark::foo(&t) as *const ();
3561 }
3562 "#,
3563 expect![[r#"
3564 47..51 'self': &Ark<T>
3565 65..88 '{ ... }': *const T
3566 75..82 '&self.0': &T
3567 76..80 'self': &Ark<T>
3568 76..82 'self.0': T
3569 99..100 't': Ark<T>
3570 110..144 '{ ... (); }': ()
3571 116..124 'Ark::foo': fn foo<T>(&Ark<T>) -> *const T
3572 116..128 'Ark::foo(&t)': *const T
3573 116..141 'Ark::f...nst ()': *const ()
3574 125..127 '&t': &Ark<T>
3575 126..127 't': Ark<T>
3576 "#]],
3577 );
3578 }
3579
3580 #[test]
const_dependent_on_local()3581 fn const_dependent_on_local() {
3582 check_types(
3583 r#"
3584 fn main() {
3585 let s = 5;
3586 let t = [2; s];
3587 //^ [i32; _]
3588 }
3589 "#,
3590 );
3591 }
3592
3593 #[test]
issue_14275()3594 fn issue_14275() {
3595 check_types(
3596 r#"
3597 struct Foo<const T: bool>;
3598 fn main() {
3599 const B: bool = false;
3600 let foo = Foo::<B>;
3601 //^^^ Foo<false>
3602 }
3603 "#,
3604 );
3605 check_types(
3606 r#"
3607 struct Foo<const T: bool>;
3608 impl Foo<true> {
3609 fn foo(self) -> u8 { 2 }
3610 }
3611 impl Foo<false> {
3612 fn foo(self) -> u16 { 5 }
3613 }
3614 fn main() {
3615 const B: bool = false;
3616 let foo: Foo<B> = Foo;
3617 let x = foo.foo();
3618 //^ u16
3619 }
3620 "#,
3621 );
3622 }
3623
3624 #[test]
cstring_literals()3625 fn cstring_literals() {
3626 check_types(
3627 r#"
3628 #[lang = "CStr"]
3629 pub struct CStr;
3630
3631 fn main() {
3632 c"ello";
3633 //^^^^^^^ &CStr
3634 }
3635 "#,
3636 );
3637 }
3638