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