]> git.proxmox.com Git - rustc.git/blob - src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs
New upstream version 1.76.0+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / hir-ty / src / tests / macros.rs
1 use expect_test::expect;
2 use test_utils::{bench, bench_fixture, skip_slow_tests};
3
4 use crate::tests::check_infer_with_mismatches;
5
6 use super::{check_infer, check_types};
7
8 #[test]
9 fn cfg_impl_def() {
10 check_types(
11 r#"
12 //- /main.rs crate:main deps:foo cfg:test
13 use foo::S as T;
14 struct S;
15
16 #[cfg(test)]
17 impl S {
18 fn foo1(&self) -> i32 { 0 }
19 }
20
21 #[cfg(not(test))]
22 impl S {
23 fn foo2(&self) -> i32 { 0 }
24 }
25
26 fn test() {
27 let t = (S.foo1(), S.foo2(), T.foo3(), T.foo4());
28 t;
29 } //^ (i32, {unknown}, i32, {unknown})
30
31 //- /foo.rs crate:foo
32 pub struct S;
33
34 #[cfg(not(test))]
35 impl S {
36 pub fn foo3(&self) -> i32 { 0 }
37 }
38
39 #[cfg(test)]
40 impl S {
41 pub fn foo4(&self) -> i32 { 0 }
42 }
43 "#,
44 );
45 }
46
47 #[test]
48 fn infer_macros_expanded() {
49 check_infer(
50 r#"
51 struct Foo(Vec<i32>);
52
53 macro_rules! foo {
54 ($($item:expr),*) => {
55 {
56 Foo(vec![$($item,)*])
57 }
58 };
59 }
60
61 fn main() {
62 let x = foo!(1,2);
63 }
64 "#,
65 expect![[r#"
66 !0..17 '{Foo(v...,2,])}': Foo
67 !1..4 'Foo': Foo({unknown}) -> Foo
68 !1..16 'Foo(vec![1,2,])': Foo
69 !5..15 'vec![1,2,]': {unknown}
70 155..181 '{ ...,2); }': ()
71 165..166 'x': Foo
72 "#]],
73 );
74 }
75
76 #[test]
77 fn infer_legacy_textual_scoped_macros_expanded() {
78 check_infer(
79 r#"
80 struct Foo(Vec<i32>);
81
82 #[macro_use]
83 mod m {
84 macro_rules! foo {
85 ($($item:expr),*) => {
86 {
87 Foo(vec![$($item,)*])
88 }
89 };
90 }
91 }
92
93 fn main() {
94 let x = foo!(1,2);
95 let y = crate::foo!(1,2);
96 }
97 "#,
98 expect![[r#"
99 !0..17 '{Foo(v...,2,])}': Foo
100 !1..4 'Foo': Foo({unknown}) -> Foo
101 !1..16 'Foo(vec![1,2,])': Foo
102 !5..15 'vec![1,2,]': {unknown}
103 194..250 '{ ...,2); }': ()
104 204..205 'x': Foo
105 227..228 'y': {unknown}
106 231..247 'crate:...!(1,2)': {unknown}
107 "#]],
108 );
109 }
110
111 #[test]
112 fn infer_path_qualified_macros_expanded() {
113 check_infer(
114 r#"
115 #[macro_export]
116 macro_rules! foo {
117 () => { 42i32 }
118 }
119
120 mod m {
121 pub use super::foo as bar;
122 }
123
124 fn main() {
125 let x = crate::foo!();
126 let y = m::bar!();
127 }
128 "#,
129 expect![[r#"
130 !0..5 '42i32': i32
131 !0..5 '42i32': i32
132 110..163 '{ ...!(); }': ()
133 120..121 'x': i32
134 147..148 'y': i32
135 "#]],
136 );
137 }
138
139 #[test]
140 fn expr_macro_def_expanded_in_various_places() {
141 check_infer(
142 r#"
143 //- minicore: iterator
144 macro spam() {
145 1isize
146 }
147
148 fn spam() {
149 spam!();
150 (spam!());
151 spam!().spam(spam!());
152 for _ in spam!() {}
153 || spam!();
154 while spam!() {}
155 break spam!();
156 return spam!();
157 match spam!() {
158 _ if spam!() => spam!(),
159 }
160 spam!()(spam!());
161 Spam { spam: spam!() };
162 spam!()[spam!()];
163 await spam!();
164 spam!() as usize;
165 &spam!();
166 -spam!();
167 spam!()..spam!();
168 spam!() + spam!();
169 }
170 "#,
171 expect![[r#"
172 !0..6 '1isize': isize
173 !0..6 '1isize': isize
174 !0..6 '1isize': isize
175 !0..6 '1isize': isize
176 !0..6 '1isize': isize
177 !0..6 '1isize': isize
178 !0..6 '1isize': isize
179 !0..6 '1isize': isize
180 !0..6 '1isize': isize
181 !0..6 '1isize': isize
182 !0..6 '1isize': isize
183 !0..6 '1isize': isize
184 !0..6 '1isize': isize
185 !0..6 '1isize': isize
186 !0..6 '1isize': isize
187 !0..6 '1isize': isize
188 !0..6 '1isize': isize
189 !0..6 '1isize': isize
190 !0..6 '1isize': isize
191 !0..6 '1isize': isize
192 !0..6 '1isize': isize
193 !0..6 '1isize': isize
194 !0..6 '1isize': isize
195 !0..6 '1isize': isize
196 !0..6 '1isize': isize
197 39..442 '{ ...!(); }': ()
198 73..94 'spam!(...am!())': {unknown}
199 100..119 'for _ ...!() {}': fn into_iter<isize>(isize) -> <isize as IntoIterator>::IntoIter
200 100..119 'for _ ...!() {}': IntoIterator::IntoIter<isize>
201 100..119 'for _ ...!() {}': !
202 100..119 'for _ ...!() {}': IntoIterator::IntoIter<isize>
203 100..119 'for _ ...!() {}': &mut IntoIterator::IntoIter<isize>
204 100..119 'for _ ...!() {}': fn next<IntoIterator::IntoIter<isize>>(&mut IntoIterator::IntoIter<isize>) -> Option<<IntoIterator::IntoIter<isize> as Iterator>::Item>
205 100..119 'for _ ...!() {}': Option<IntoIterator::Item<isize>>
206 100..119 'for _ ...!() {}': ()
207 100..119 'for _ ...!() {}': ()
208 100..119 'for _ ...!() {}': ()
209 104..105 '_': IntoIterator::Item<isize>
210 117..119 '{}': ()
211 124..134 '|| spam!()': impl Fn() -> isize
212 140..156 'while ...!() {}': !
213 140..156 'while ...!() {}': ()
214 140..156 'while ...!() {}': ()
215 154..156 '{}': ()
216 161..174 'break spam!()': !
217 180..194 'return spam!()': !
218 200..254 'match ... }': isize
219 224..225 '_': isize
220 259..275 'spam!(...am!())': {unknown}
221 281..303 'Spam {...m!() }': {unknown}
222 309..325 'spam!(...am!()]': {unknown}
223 350..366 'spam!(... usize': usize
224 372..380 '&spam!()': &isize
225 386..394 '-spam!()': isize
226 400..416 'spam!(...pam!()': {unknown}
227 422..439 'spam!(...pam!()': isize
228 "#]],
229 );
230 }
231
232 #[test]
233 fn expr_macro_rules_expanded_in_various_places() {
234 check_infer(
235 r#"
236 //- minicore: iterator
237 macro_rules! spam {
238 () => (1isize);
239 }
240
241 fn spam() {
242 spam!();
243 (spam!());
244 spam!().spam(spam!());
245 for _ in spam!() {}
246 || spam!();
247 while spam!() {}
248 break spam!();
249 return spam!();
250 match spam!() {
251 _ if spam!() => spam!(),
252 }
253 spam!()(spam!());
254 Spam { spam: spam!() };
255 spam!()[spam!()];
256 await spam!();
257 spam!() as usize;
258 &spam!();
259 -spam!();
260 spam!()..spam!();
261 spam!() + spam!();
262 }
263 "#,
264 expect![[r#"
265 !0..6 '1isize': isize
266 !0..6 '1isize': isize
267 !0..6 '1isize': isize
268 !0..6 '1isize': isize
269 !0..6 '1isize': isize
270 !0..6 '1isize': isize
271 !0..6 '1isize': isize
272 !0..6 '1isize': isize
273 !0..6 '1isize': isize
274 !0..6 '1isize': isize
275 !0..6 '1isize': isize
276 !0..6 '1isize': isize
277 !0..6 '1isize': isize
278 !0..6 '1isize': isize
279 !0..6 '1isize': isize
280 !0..6 '1isize': isize
281 !0..6 '1isize': isize
282 !0..6 '1isize': isize
283 !0..6 '1isize': isize
284 !0..6 '1isize': isize
285 !0..6 '1isize': isize
286 !0..6 '1isize': isize
287 !0..6 '1isize': isize
288 !0..6 '1isize': isize
289 !0..6 '1isize': isize
290 53..456 '{ ...!(); }': ()
291 87..108 'spam!(...am!())': {unknown}
292 114..133 'for _ ...!() {}': fn into_iter<isize>(isize) -> <isize as IntoIterator>::IntoIter
293 114..133 'for _ ...!() {}': IntoIterator::IntoIter<isize>
294 114..133 'for _ ...!() {}': !
295 114..133 'for _ ...!() {}': IntoIterator::IntoIter<isize>
296 114..133 'for _ ...!() {}': &mut IntoIterator::IntoIter<isize>
297 114..133 'for _ ...!() {}': fn next<IntoIterator::IntoIter<isize>>(&mut IntoIterator::IntoIter<isize>) -> Option<<IntoIterator::IntoIter<isize> as Iterator>::Item>
298 114..133 'for _ ...!() {}': Option<IntoIterator::Item<isize>>
299 114..133 'for _ ...!() {}': ()
300 114..133 'for _ ...!() {}': ()
301 114..133 'for _ ...!() {}': ()
302 118..119 '_': IntoIterator::Item<isize>
303 131..133 '{}': ()
304 138..148 '|| spam!()': impl Fn() -> isize
305 154..170 'while ...!() {}': !
306 154..170 'while ...!() {}': ()
307 154..170 'while ...!() {}': ()
308 168..170 '{}': ()
309 175..188 'break spam!()': !
310 194..208 'return spam!()': !
311 214..268 'match ... }': isize
312 238..239 '_': isize
313 273..289 'spam!(...am!())': {unknown}
314 295..317 'Spam {...m!() }': {unknown}
315 323..339 'spam!(...am!()]': {unknown}
316 364..380 'spam!(... usize': usize
317 386..394 '&spam!()': &isize
318 400..408 '-spam!()': isize
319 414..430 'spam!(...pam!()': {unknown}
320 436..453 'spam!(...pam!()': isize
321 "#]],
322 );
323 }
324
325 #[test]
326 fn expr_macro_expanded_in_stmts() {
327 check_infer(
328 r#"
329 macro_rules! id { ($($es:tt)*) => { $($es)* } }
330 fn foo() {
331 id! { let a = (); }
332 }
333 "#,
334 expect![[r#"
335 !3..4 'a': ()
336 !5..7 '()': ()
337 57..84 '{ ...); } }': ()
338 "#]],
339 );
340 }
341
342 #[test]
343 fn recursive_macro_expanded_in_stmts() {
344 check_infer(
345 r#"
346 macro_rules! ng {
347 ([$($tts:tt)*]) => {
348 $($tts)*;
349 };
350 ([$($tts:tt)*] $head:tt $($rest:tt)*) => {
351 ng! {
352 [$($tts)* $head] $($rest)*
353 }
354 };
355 }
356 fn foo() {
357 ng!([] let a = 3);
358 let b = a;
359 }
360 "#,
361 expect![[r#"
362 !3..4 'a': i32
363 !5..6 '3': i32
364 196..237 '{ ...= a; }': ()
365 229..230 'b': i32
366 233..234 'a': i32
367 "#]],
368 );
369 }
370
371 #[test]
372 fn recursive_inner_item_macro_rules() {
373 check_infer(
374 r#"
375 macro_rules! mac {
376 () => { mac!($)};
377 ($x:tt) => { macro_rules! blub { () => { 1 }; } };
378 }
379 fn foo() {
380 mac!();
381 let a = blub!();
382 }
383 "#,
384 expect![[r#"
385 !0..1 '1': i32
386 107..143 '{ ...!(); }': ()
387 129..130 'a': i32
388 "#]],
389 );
390 }
391
392 #[test]
393 fn infer_macro_defining_block_with_items() {
394 check_infer(
395 r#"
396 macro_rules! foo {
397 () => {{
398 fn bar() -> usize { 0 }
399 bar()
400 }};
401 }
402 fn main() {
403 let _a = foo!();
404 }
405 "#,
406 expect![[r#"
407 !15..18 '{0}': usize
408 !16..17 '0': usize
409 !0..24 '{fnbar...bar()}': usize
410 !18..21 'bar': fn bar() -> usize
411 !18..23 'bar()': usize
412 98..122 '{ ...!(); }': ()
413 108..110 '_a': usize
414 "#]],
415 );
416 }
417
418 #[test]
419 fn infer_type_value_macro_having_same_name() {
420 check_infer(
421 r#"
422 #[macro_export]
423 macro_rules! foo {
424 () => {
425 mod foo {
426 pub use super::foo;
427 }
428 };
429 ($x:tt) => {
430 $x
431 };
432 }
433
434 foo!();
435
436 fn foo() {
437 let foo = foo::foo!(42i32);
438 }
439 "#,
440 expect![[r#"
441 !0..5 '42i32': i32
442 170..205 '{ ...32); }': ()
443 180..183 'foo': i32
444 "#]],
445 );
446 }
447
448 #[test]
449 fn processes_impls_generated_by_macros() {
450 check_types(
451 r#"
452 macro_rules! m {
453 ($ident:ident) => (impl Trait for $ident {})
454 }
455 trait Trait { fn foo(self) -> u128 { 0 } }
456 struct S;
457 m!(S);
458 fn test() { S.foo(); }
459 //^^^^^^^ u128
460 "#,
461 );
462 }
463
464 #[test]
465 fn infer_assoc_items_generated_by_macros() {
466 check_types(
467 r#"
468 macro_rules! m {
469 () => (fn foo(&self) -> u128 {0})
470 }
471 struct S;
472 impl S {
473 m!();
474 }
475
476 fn test() { S.foo(); }
477 //^^^^^^^ u128
478 "#,
479 );
480 }
481
482 #[test]
483 fn infer_assoc_items_generated_by_macros_chain() {
484 check_types(
485 r#"
486 macro_rules! m_inner {
487 () => {fn foo(&self) -> u128 {0}}
488 }
489 macro_rules! m {
490 () => {m_inner!();}
491 }
492
493 struct S;
494 impl S {
495 m!();
496 }
497
498 fn test() { S.foo(); }
499 //^^^^^^^ u128
500 "#,
501 );
502 }
503
504 #[test]
505 fn infer_macro_with_dollar_crate_is_correct_in_expr() {
506 check_types(
507 r#"
508 //- /main.rs crate:main deps:foo
509 fn test() {
510 let x = (foo::foo!(1), foo::foo!(2));
511 x;
512 } //^ (i32, usize)
513
514 //- /lib.rs crate:foo
515 #[macro_export]
516 macro_rules! foo {
517 (1) => { $crate::bar!() };
518 (2) => { 1 + $crate::baz() };
519 }
520
521 #[macro_export]
522 macro_rules! bar {
523 () => { 42 }
524 }
525
526 pub fn baz() -> usize { 31usize }
527 "#,
528 );
529 }
530
531 #[test]
532 fn infer_macro_with_dollar_crate_is_correct_in_trait_associate_type() {
533 check_types(
534 r#"
535 //- /main.rs crate:main deps:foo
536 use foo::Trait;
537
538 fn test() {
539 let msg = foo::Message(foo::MessageRef);
540 let r = msg.deref();
541 r;
542 //^ &MessageRef
543 }
544
545 //- /lib.rs crate:foo
546 pub struct MessageRef;
547 pub struct Message(MessageRef);
548
549 pub trait Trait {
550 type Target;
551 fn deref(&self) -> &Self::Target;
552 }
553
554 #[macro_export]
555 macro_rules! expand {
556 () => {
557 impl Trait for Message {
558 type Target = $crate::MessageRef;
559 fn deref(&self) -> &Self::Target {
560 &self.0
561 }
562 }
563 }
564 }
565
566 expand!();
567 "#,
568 );
569 }
570
571 #[test]
572 fn infer_macro_with_dollar_crate_in_def_site() {
573 check_types(
574 r#"
575 //- /main.rs crate:main deps:foo
576 use foo::expand;
577
578 macro_rules! list {
579 ($($tt:tt)*) => { $($tt)* }
580 }
581
582 fn test() {
583 let r = expand!();
584 r;
585 //^ u128
586 }
587
588 //- /lib.rs crate:foo
589 #[macro_export]
590 macro_rules! expand {
591 () => { list!($crate::m!()) };
592 }
593
594 #[macro_export]
595 macro_rules! m {
596 () => { 0u128 };
597 }
598 "#,
599 );
600 }
601
602 #[test]
603 fn infer_type_value_non_legacy_macro_use_as() {
604 check_infer(
605 r#"
606 mod m {
607 macro_rules! _foo {
608 ($x:ident) => { type $x = u64; }
609 }
610 pub(crate) use _foo as foo;
611 }
612
613 m::foo!(foo);
614 use foo as bar;
615 fn f() -> bar { 0 }
616 fn main() {
617 let _a = f();
618 }
619 "#,
620 expect![[r#"
621 158..163 '{ 0 }': u64
622 160..161 '0': u64
623 174..196 '{ ...f(); }': ()
624 184..186 '_a': u64
625 190..191 'f': fn f() -> u64
626 190..193 'f()': u64
627 "#]],
628 );
629 }
630
631 #[test]
632 fn infer_local_macro() {
633 check_infer(
634 r#"
635 fn main() {
636 macro_rules! foo {
637 () => { 1usize }
638 }
639 let _a = foo!();
640 }
641 "#,
642 expect![[r#"
643 !0..6 '1usize': usize
644 10..89 '{ ...!(); }': ()
645 74..76 '_a': usize
646 "#]],
647 );
648 }
649
650 #[test]
651 fn infer_local_inner_macros() {
652 check_types(
653 r#"
654 //- /main.rs crate:main deps:foo
655 fn test() {
656 let x = foo::foo!(1);
657 x;
658 } //^ i32
659
660 //- /lib.rs crate:foo
661 #[macro_export(local_inner_macros)]
662 macro_rules! foo {
663 (1) => { bar!() };
664 }
665
666 #[macro_export]
667 macro_rules! bar {
668 () => { 42 }
669 }
670
671 "#,
672 );
673 }
674
675 #[test]
676 fn infer_builtin_macros_line() {
677 check_infer(
678 r#"
679 #[rustc_builtin_macro]
680 macro_rules! line {() => {}}
681
682 fn main() {
683 let x = line!();
684 }
685 "#,
686 expect![[r#"
687 !0..4 '0u32': u32
688 63..87 '{ ...!(); }': ()
689 73..74 'x': u32
690 "#]],
691 );
692 }
693
694 #[test]
695 fn infer_builtin_macros_file() {
696 check_infer(
697 r#"
698 #[rustc_builtin_macro]
699 macro_rules! file {() => {}}
700
701 fn main() {
702 let x = file!();
703 }
704 "#,
705 expect![[r#"
706 !0..2 '""': &str
707 63..87 '{ ...!(); }': ()
708 73..74 'x': &str
709 "#]],
710 );
711 }
712
713 #[test]
714 fn infer_builtin_macros_column() {
715 check_infer(
716 r#"
717 #[rustc_builtin_macro]
718 macro_rules! column {() => {}}
719
720 fn main() {
721 let x = column!();
722 }
723 "#,
724 expect![[r#"
725 !0..4 '0u32': u32
726 65..91 '{ ...!(); }': ()
727 75..76 'x': u32
728 "#]],
729 );
730 }
731
732 #[test]
733 fn infer_builtin_macros_concat() {
734 check_infer(
735 r#"
736 #[rustc_builtin_macro]
737 macro_rules! concat {() => {}}
738
739 fn main() {
740 let x = concat!("hello", concat!("world", "!"));
741 }
742 "#,
743 expect![[r#"
744 !0..13 '"helloworld!"': &str
745 65..121 '{ ...")); }': ()
746 75..76 'x': &str
747 "#]],
748 );
749 }
750
751 #[test]
752 fn infer_builtin_macros_include() {
753 check_types(
754 r#"
755 //- /main.rs
756 #[rustc_builtin_macro]
757 macro_rules! include {() => {}}
758
759 include!("foo.rs");
760
761 fn main() {
762 bar();
763 } //^^^^^ u32
764
765 //- /foo.rs
766 fn bar() -> u32 {0}
767 "#,
768 );
769 }
770
771 #[test]
772 fn infer_builtin_macros_include_expression() {
773 check_types(
774 r#"
775 //- /main.rs
776 #[rustc_builtin_macro]
777 macro_rules! include {() => {}}
778 fn main() {
779 let i = include!("bla.rs");
780 i;
781 //^ i32
782 }
783 //- /bla.rs
784 0
785 "#,
786 )
787 }
788
789 #[test]
790 fn infer_builtin_macros_include_child_mod() {
791 check_types(
792 r#"
793 //- /main.rs
794 #[rustc_builtin_macro]
795 macro_rules! include {() => {}}
796
797 include!("f/foo.rs");
798
799 fn main() {
800 bar::bar();
801 } //^^^^^^^^^^ u32
802
803 //- /f/foo.rs
804 pub mod bar;
805
806 //- /f/bar.rs
807 pub fn bar() -> u32 {0}
808 "#,
809 );
810 }
811
812 #[test]
813 fn infer_builtin_macros_include_str() {
814 check_types(
815 r#"
816 //- /main.rs
817 #[rustc_builtin_macro]
818 macro_rules! include_str {() => {}}
819
820 fn main() {
821 let a = include_str!("foo.rs");
822 a;
823 } //^ &str
824
825 //- /foo.rs
826 hello
827 "#,
828 );
829 }
830
831 #[test]
832 fn infer_builtin_macros_include_str_with_lazy_nested() {
833 check_types(
834 r#"
835 //- /main.rs
836 #[rustc_builtin_macro]
837 macro_rules! concat {() => {}}
838 #[rustc_builtin_macro]
839 macro_rules! include_str {() => {}}
840
841 macro_rules! m {
842 ($x:expr) => {
843 concat!("foo", $x)
844 };
845 }
846
847 fn main() {
848 let a = include_str!(m!(".rs"));
849 a;
850 } //^ &str
851
852 //- /foo.rs
853 hello
854 "#,
855 );
856 }
857
858 #[test]
859 fn benchmark_include_macro() {
860 if skip_slow_tests() {
861 return;
862 }
863 let data = bench_fixture::big_struct();
864 let fixture = r#"
865 //- /main.rs
866 #[rustc_builtin_macro]
867 macro_rules! include {() => {}}
868
869 include!("foo.rs");
870
871 fn main() {
872 RegisterBlock { };
873 //^^^^^^^^^^^^^^^^^ RegisterBlock
874 }
875 "#;
876 let fixture = format!("{fixture}\n//- /foo.rs\n{data}");
877
878 {
879 let _b = bench("include macro");
880 check_types(&fixture);
881 }
882 }
883
884 #[test]
885 fn infer_builtin_macros_include_concat() {
886 check_types(
887 r#"
888 //- /main.rs
889 #[rustc_builtin_macro]
890 macro_rules! include {() => {}}
891
892 #[rustc_builtin_macro]
893 macro_rules! concat {() => {}}
894
895 include!(concat!("f", "oo.rs"));
896
897 fn main() {
898 bar();
899 } //^^^^^ u32
900
901 //- /foo.rs
902 fn bar() -> u32 {0}
903 "#,
904 );
905 }
906
907 #[test]
908 fn infer_builtin_macros_include_concat_with_bad_env_should_failed() {
909 check_types(
910 r#"
911 //- /main.rs
912 #[rustc_builtin_macro]
913 macro_rules! include {() => {}}
914
915 #[rustc_builtin_macro]
916 macro_rules! concat {() => {}}
917
918 #[rustc_builtin_macro]
919 macro_rules! env {() => {}}
920
921 include!(concat!(env!("OUT_DIR"), "/foo.rs"));
922
923 fn main() {
924 bar();
925 } //^^^^^ {unknown}
926
927 //- /foo.rs
928 fn bar() -> u32 {0}
929 "#,
930 );
931 }
932
933 #[test]
934 fn infer_builtin_macros_include_itself_should_failed() {
935 check_types(
936 r#"
937 #[rustc_builtin_macro]
938 macro_rules! include {() => {}}
939
940 include!("main.rs");
941
942 fn main() {
943 0;
944 } //^ i32
945 "#,
946 );
947 }
948
949 #[test]
950 fn infer_builtin_macros_concat_with_lazy() {
951 check_infer(
952 r#"
953 macro_rules! hello {() => {"hello"}}
954
955 #[rustc_builtin_macro]
956 macro_rules! concat {() => {}}
957
958 fn main() {
959 let x = concat!(hello!(), concat!("world", "!"));
960 }
961 "#,
962 expect![[r#"
963 !0..13 '"helloworld!"': &str
964 103..160 '{ ...")); }': ()
965 113..114 'x': &str
966 "#]],
967 );
968 }
969
970 #[test]
971 fn infer_builtin_macros_env() {
972 check_types(
973 r#"
974 //- /main.rs env:foo=bar
975 #[rustc_builtin_macro]
976 macro_rules! env {() => {}}
977
978 fn main() {
979 let x = env!("foo");
980 //^ &str
981 }
982 "#,
983 );
984 }
985
986 #[test]
987 fn infer_builtin_macros_option_env() {
988 check_types(
989 r#"
990 //- minicore: option
991 //- /main.rs env:foo=bar
992 #[rustc_builtin_macro]
993 macro_rules! option_env {() => {}}
994
995 fn main() {
996 let x = option_env!("foo");
997 //^ Option<&str>
998 }
999 "#,
1000 );
1001 }
1002
1003 #[test]
1004 fn infer_derive_clone_simple() {
1005 check_types(
1006 r#"
1007 //- minicore: derive, clone
1008 #[derive(Clone)]
1009 struct S;
1010 fn test() {
1011 S.clone();
1012 } //^^^^^^^^^ S
1013 "#,
1014 );
1015 }
1016
1017 #[test]
1018 fn infer_derive_clone_with_params() {
1019 check_types(
1020 r#"
1021 //- minicore: clone, derive
1022 #[derive(Clone)]
1023 struct S;
1024 #[derive(Clone)]
1025 struct Wrapper<T>(T);
1026 struct NonClone;
1027 fn test() {
1028 let x = (Wrapper(S).clone(), Wrapper(NonClone).clone());
1029 x;
1030 //^ (Wrapper<S>, {unknown})
1031 }
1032 "#,
1033 );
1034 }
1035
1036 #[test]
1037 fn infer_custom_derive_simple() {
1038 // FIXME: this test current now do nothing
1039 check_types(
1040 r#"
1041 //- minicore: derive
1042 use foo::Foo;
1043
1044 #[derive(Foo)]
1045 struct S{}
1046
1047 fn test() {
1048 S{};
1049 } //^^^ S
1050 "#,
1051 );
1052 }
1053
1054 #[test]
1055 fn macro_in_arm() {
1056 check_infer(
1057 r#"
1058 macro_rules! unit {
1059 () => { () };
1060 }
1061
1062 fn main() {
1063 let x = match () {
1064 unit!() => 92u32,
1065 };
1066 }
1067 "#,
1068 expect![[r#"
1069 !0..2 '()': ()
1070 51..110 '{ ... }; }': ()
1071 61..62 'x': u32
1072 65..107 'match ... }': u32
1073 71..73 '()': ()
1074 95..100 '92u32': u32
1075 "#]],
1076 );
1077 }
1078
1079 #[test]
1080 fn macro_in_type_alias_position() {
1081 check_infer(
1082 r#"
1083 macro_rules! U32 {
1084 () => { u32 };
1085 }
1086
1087 trait Foo {
1088 type Ty;
1089 }
1090
1091 impl<T> Foo for T {
1092 type Ty = U32!();
1093 }
1094
1095 type TayTo = U32!();
1096
1097 fn testy() {
1098 let a: <() as Foo>::Ty;
1099 let b: TayTo;
1100 }
1101 "#,
1102 expect![[r#"
1103 147..196 '{ ...yTo; }': ()
1104 157..158 'a': u32
1105 185..186 'b': u32
1106 "#]],
1107 );
1108 }
1109
1110 #[test]
1111 fn nested_macro_in_type_alias_position() {
1112 check_infer(
1113 r#"
1114 macro_rules! U32Inner2 {
1115 () => { u32 };
1116 }
1117
1118 macro_rules! U32Inner1 {
1119 () => { U32Inner2!() };
1120 }
1121
1122 macro_rules! U32 {
1123 () => { U32Inner1!() };
1124 }
1125
1126 trait Foo {
1127 type Ty;
1128 }
1129
1130 impl<T> Foo for T {
1131 type Ty = U32!();
1132 }
1133
1134 type TayTo = U32!();
1135
1136 fn testy() {
1137 let a: <() as Foo>::Ty;
1138 let b: TayTo;
1139 }
1140 "#,
1141 expect![[r#"
1142 259..308 '{ ...yTo; }': ()
1143 269..270 'a': u32
1144 297..298 'b': u32
1145 "#]],
1146 );
1147 }
1148
1149 #[test]
1150 fn macros_in_type_alias_position_generics() {
1151 check_infer(
1152 r#"
1153 struct Foo<A, B>(A, B);
1154
1155 macro_rules! U32 {
1156 () => { u32 };
1157 }
1158
1159 macro_rules! Bar {
1160 () => { Foo<U32!(), U32!()> };
1161 }
1162
1163 trait Moo {
1164 type Ty;
1165 }
1166
1167 impl<T> Moo for T {
1168 type Ty = Bar!();
1169 }
1170
1171 type TayTo = Bar!();
1172
1173 fn main() {
1174 let a: <() as Moo>::Ty;
1175 let b: TayTo;
1176 }
1177 "#,
1178 expect![[r#"
1179 228..277 '{ ...yTo; }': ()
1180 238..239 'a': Foo<u32, u32>
1181 266..267 'b': Foo<u32, u32>
1182 "#]],
1183 );
1184 }
1185
1186 #[test]
1187 fn macros_in_type_position() {
1188 check_infer(
1189 r#"
1190 struct Foo<A, B>(A, B);
1191
1192 macro_rules! U32 {
1193 () => { u32 };
1194 }
1195
1196 macro_rules! Bar {
1197 () => { Foo<U32!(), U32!()> };
1198 }
1199
1200 fn main() {
1201 let a: Bar!();
1202 }
1203 "#,
1204 expect![[r#"
1205 133..155 '{ ...!(); }': ()
1206 143..144 'a': Foo<u32, u32>
1207 "#]],
1208 );
1209 }
1210
1211 #[test]
1212 fn macros_in_type_generics() {
1213 check_infer(
1214 r#"
1215 struct Foo<A, B>(A, B);
1216
1217 macro_rules! U32 {
1218 () => { u32 };
1219 }
1220
1221 macro_rules! Bar {
1222 () => { Foo<U32!(), U32!()> };
1223 }
1224
1225 trait Moo {
1226 type Ty;
1227 }
1228
1229 impl<T> Moo for T {
1230 type Ty = Foo<Bar!(), Bar!()>;
1231 }
1232
1233 type TayTo = Foo<Bar!(), U32!()>;
1234
1235 fn main() {
1236 let a: <() as Moo>::Ty;
1237 let b: TayTo;
1238 }
1239 "#,
1240 expect![[r#"
1241 254..303 '{ ...yTo; }': ()
1242 264..265 'a': Foo<Foo<u32, u32>, Foo<u32, u32>>
1243 292..293 'b': Foo<Foo<u32, u32>, u32>
1244 "#]],
1245 );
1246 }
1247
1248 #[test]
1249 fn infinitely_recursive_macro_type() {
1250 check_infer(
1251 r#"
1252 struct Bar<T, X>(T, X);
1253
1254 macro_rules! Foo {
1255 () => { Foo!() }
1256 }
1257
1258 macro_rules! U32 {
1259 () => { u32 }
1260 }
1261
1262 type A = Foo!();
1263 type B = Bar<Foo!(), U32!()>;
1264
1265 fn main() {
1266 let a: A;
1267 let b: B;
1268 }
1269 "#,
1270 expect![[r#"
1271 166..197 '{ ...: B; }': ()
1272 176..177 'a': {unknown}
1273 190..191 'b': Bar<{unknown}, u32>
1274 "#]],
1275 );
1276 }
1277
1278 #[test]
1279 fn cfg_tails() {
1280 check_infer_with_mismatches(
1281 r#"
1282 //- /lib.rs crate:foo cfg:feature=foo
1283 struct S {}
1284
1285 impl S {
1286 fn new2(bar: u32) -> Self {
1287 #[cfg(feature = "foo")]
1288 { Self { } }
1289 #[cfg(not(feature = "foo"))]
1290 { Self { } }
1291 }
1292 }
1293 "#,
1294 expect![[r#"
1295 34..37 'bar': u32
1296 52..170 '{ ... }': S
1297 62..106 '#[cfg(... { } }': S
1298 96..104 'Self { }': S
1299 "#]],
1300 );
1301 }
1302
1303 #[test]
1304 fn infer_in_unexpandable_attr_proc_macro_1() {
1305 check_types(
1306 r#"
1307 //- /main.rs crate:main deps:mac
1308 #[mac::attr_macro]
1309 fn foo() {
1310 let xxx = 1;
1311 //^^^ i32
1312 }
1313
1314 //- /mac.rs crate:mac
1315 #![crate_type="proc-macro"]
1316 #[proc_macro_attribute]
1317 pub fn attr_macro() {}
1318 "#,
1319 );
1320 }
1321
1322 #[test]
1323 fn infer_in_unexpandable_attr_proc_macro_in_impl() {
1324 check_types(
1325 r#"
1326 //- /main.rs crate:main deps:mac
1327 struct Foo;
1328 impl Foo {
1329 #[mac::attr_macro]
1330 fn foo() {
1331 let xxx = 1;
1332 //^^^ i32
1333 }
1334 }
1335
1336 //- /mac.rs crate:mac
1337 #![crate_type="proc-macro"]
1338 #[proc_macro_attribute]
1339 pub fn attr_macro() {}
1340 "#,
1341 );
1342 }
1343
1344 #[test]
1345 fn infer_in_unexpandable_attr_proc_macro_in_trait() {
1346 check_types(
1347 r#"
1348 //- /main.rs crate:main deps:mac
1349 trait Foo {
1350 #[mac::attr_macro]
1351 fn foo() {
1352 let xxx = 1;
1353 //^^^ i32
1354 }
1355 }
1356
1357 //- /mac.rs crate:mac
1358 #![crate_type="proc-macro"]
1359 #[proc_macro_attribute]
1360 pub fn attr_macro() {}
1361 "#,
1362 );
1363 }