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