]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/macros.rs
Merge #9453
[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 pub 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 { 0 } }
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 pub mod prelude {
986     pub mod rust_2018 {
987         #[rustc_builtin_macro]
988         pub macro Clone {}
989         pub use crate::clone::Clone;
990     }
991 }
992
993 pub mod clone {
994     pub trait Clone {
995         fn clone(&self) -> Self;
996     }
997 }
998 "#,
999     );
1000 }
1001
1002 #[test]
1003 fn infer_derive_clone_in_core() {
1004     check_types(
1005         r#"
1006 //- /lib.rs crate:core
1007 #[prelude_import]
1008 use prelude::rust_2018::*;
1009
1010 pub mod prelude {
1011     pub mod rust_2018 {
1012         #[rustc_builtin_macro]
1013         pub macro Clone {}
1014         pub use crate::clone::Clone;
1015     }
1016 }
1017
1018 pub mod clone {
1019     pub trait Clone {
1020         fn clone(&self) -> Self;
1021     }
1022 }
1023
1024 #[derive(Clone)]
1025 pub struct S;
1026
1027 //- /main.rs crate:main deps:core
1028 use core::S;
1029 fn test() {
1030     S.clone();
1031 } //^^^^^^^^^ S
1032 "#,
1033     );
1034 }
1035
1036 #[test]
1037 fn infer_derive_clone_with_params() {
1038     check_types(
1039         r#"
1040 //- /main.rs crate:main deps:core
1041 #[derive(Clone)]
1042 struct S;
1043 #[derive(Clone)]
1044 struct Wrapper<T>(T);
1045 struct NonClone;
1046 fn test() {
1047     let x = (Wrapper(S).clone(), Wrapper(NonClone).clone());
1048     x;
1049   //^ (Wrapper<S>, {unknown})
1050 }
1051
1052 //- /lib.rs crate:core
1053 pub mod prelude {
1054     pub mod rust_2018 {
1055         #[rustc_builtin_macro]
1056         pub macro Clone {}
1057         pub use crate::clone::Clone;
1058     }
1059 }
1060
1061 pub mod clone {
1062     pub trait Clone {
1063         fn clone(&self) -> Self;
1064     }
1065 }
1066 "#,
1067     );
1068 }
1069
1070 #[test]
1071 fn infer_custom_derive_simple() {
1072     // FIXME: this test current now do nothing
1073     check_types(
1074         r#"
1075 //- /main.rs crate:main
1076 use foo::Foo;
1077
1078 #[derive(Foo)]
1079 struct S{}
1080
1081 fn test() {
1082     S{};
1083 } //^^^ S
1084 "#,
1085     );
1086 }
1087
1088 #[test]
1089 fn macro_in_arm() {
1090     check_infer(
1091         r#"
1092         macro_rules! unit {
1093             () => { () };
1094         }
1095
1096         fn main() {
1097             let x = match () {
1098                 unit!() => 92u32,
1099             };
1100         }
1101         "#,
1102         expect![[r#"
1103             !0..2 '()': ()
1104             51..110 '{     ...  }; }': ()
1105             61..62 'x': u32
1106             65..107 'match ...     }': u32
1107             71..73 '()': ()
1108             95..100 '92u32': u32
1109         "#]],
1110     );
1111 }
1112
1113 #[test]
1114 fn macro_in_type_alias_position() {
1115     check_infer(
1116         r#"
1117         macro_rules! U32 {
1118             () => { u32 };
1119         }
1120
1121         trait Foo {
1122             type Ty;
1123         }
1124
1125         impl<T> Foo for T {
1126             type Ty = U32!();
1127         }
1128
1129         type TayTo = U32!();
1130
1131         fn testy() {
1132             let a: <() as Foo>::Ty;
1133             let b: TayTo;
1134         }
1135         "#,
1136         expect![[r#"
1137             147..196 '{     ...yTo; }': ()
1138             157..158 'a': u32
1139             185..186 'b': u32
1140         "#]],
1141     );
1142 }
1143
1144 #[test]
1145 fn nested_macro_in_type_alias_position() {
1146     check_infer(
1147         r#"
1148         macro_rules! U32Inner2 {
1149             () => { u32 };
1150         }
1151
1152         macro_rules! U32Inner1 {
1153             () => { U32Inner2!() };
1154         }
1155
1156         macro_rules! U32 {
1157             () => { U32Inner1!() };
1158         }
1159
1160         trait Foo {
1161             type Ty;
1162         }
1163
1164         impl<T> Foo for T {
1165             type Ty = U32!();
1166         }
1167
1168         type TayTo = U32!();
1169
1170         fn testy() {
1171             let a: <() as Foo>::Ty;
1172             let b: TayTo;
1173         }
1174         "#,
1175         expect![[r#"
1176             259..308 '{     ...yTo; }': ()
1177             269..270 'a': u32
1178             297..298 'b': u32
1179         "#]],
1180     );
1181 }
1182
1183 #[test]
1184 fn macros_in_type_alias_position_generics() {
1185     check_infer(
1186         r#"
1187         struct Foo<A, B>(A, B);
1188
1189         macro_rules! U32 {
1190             () => { u32 };
1191         }
1192
1193         macro_rules! Bar {
1194             () => { Foo<U32!(), U32!()> };
1195         }
1196
1197         trait Moo {
1198             type Ty;
1199         }
1200
1201         impl<T> Moo for T {
1202             type Ty = Bar!();
1203         }
1204
1205         type TayTo = Bar!();
1206
1207         fn main() {
1208             let a: <() as Moo>::Ty;
1209             let b: TayTo;
1210         }
1211         "#,
1212         expect![[r#"
1213             228..277 '{     ...yTo; }': ()
1214             238..239 'a': Foo<u32, u32>
1215             266..267 'b': Foo<u32, u32>
1216         "#]],
1217     );
1218 }
1219
1220 #[test]
1221 fn macros_in_type_position() {
1222     check_infer(
1223         r#"
1224         struct Foo<A, B>(A, B);
1225
1226         macro_rules! U32 {
1227             () => { u32 };
1228         }
1229
1230         macro_rules! Bar {
1231             () => { Foo<U32!(), U32!()> };
1232         }
1233
1234         fn main() {
1235             let a: Bar!();
1236         }
1237         "#,
1238         expect![[r#"
1239             133..155 '{     ...!(); }': ()
1240             143..144 'a': Foo<u32, u32>
1241         "#]],
1242     );
1243 }
1244
1245 #[test]
1246 fn macros_in_type_generics() {
1247     check_infer(
1248         r#"
1249         struct Foo<A, B>(A, B);
1250
1251         macro_rules! U32 {
1252             () => { u32 };
1253         }
1254
1255         macro_rules! Bar {
1256             () => { Foo<U32!(), U32!()> };
1257         }
1258
1259         trait Moo {
1260             type Ty;
1261         }
1262
1263         impl<T> Moo for T {
1264             type Ty = Foo<Bar!(), Bar!()>;
1265         }
1266
1267         type TayTo = Foo<Bar!(), U32!()>;
1268
1269         fn main() {
1270             let a: <() as Moo>::Ty;
1271             let b: TayTo;
1272         }
1273         "#,
1274         expect![[r#"
1275             254..303 '{     ...yTo; }': ()
1276             264..265 'a': Foo<Foo<u32, u32>, Foo<u32, u32>>
1277             292..293 'b': Foo<Foo<u32, u32>, u32>
1278         "#]],
1279     );
1280 }
1281
1282 #[test]
1283 fn infinitely_recursive_macro_type() {
1284     check_infer(
1285         r#"
1286         struct Bar<T, X>(T, X);
1287
1288         macro_rules! Foo {
1289             () => { Foo!() }
1290         }
1291
1292         macro_rules! U32 {
1293             () => { u32 }
1294         }
1295
1296         type A = Foo!();
1297         type B = Bar<Foo!(), U32!()>;
1298
1299         fn main() {
1300             let a: A;
1301             let b: B;
1302         }
1303         "#,
1304         expect![[r#"
1305             166..197 '{     ...: B; }': ()
1306             176..177 'a': {unknown}
1307             190..191 'b': Bar<{unknown}, u32>
1308         "#]],
1309     );
1310 }