]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/macros.rs
Merge #8583
[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_child_mod() {
756     check_types(
757         r#"
758 //- /main.rs
759 #[rustc_builtin_macro]
760 macro_rules! include {() => {}}
761
762 include!("f/foo.rs");
763
764 fn main() {
765     bar::bar();
766 }          //^ u32
767
768 //- /f/foo.rs
769 pub mod bar;
770
771 //- /f/bar.rs
772 pub fn bar() -> u32 {0}
773 "#,
774     );
775 }
776
777 #[test]
778 fn infer_builtin_macros_include_str() {
779     check_types(
780         r#"
781 //- /main.rs
782 #[rustc_builtin_macro]
783 macro_rules! include_str {() => {}}
784
785 fn main() {
786     let a = include_str!("foo.rs");
787     a;
788 } //^ &str
789
790 //- /foo.rs
791 hello
792 "#,
793     );
794 }
795
796 #[test]
797 fn infer_builtin_macros_include_str_with_lazy_nested() {
798     check_types(
799         r#"
800 //- /main.rs
801 #[rustc_builtin_macro]
802 macro_rules! concat {() => {}}
803 #[rustc_builtin_macro]
804 macro_rules! include_str {() => {}}
805
806 macro_rules! m {
807     ($x:expr) => {
808         concat!("foo", $x)
809     };
810 }
811
812 fn main() {
813     let a = include_str!(m!(".rs"));
814     a;
815 } //^ &str
816
817 //- /foo.rs
818 hello
819 "#,
820     );
821 }
822
823 #[test]
824 fn benchmark_include_macro() {
825     if skip_slow_tests() {
826         return;
827     }
828     let data = bench_fixture::big_struct();
829     let fixture = r#"
830 //- /main.rs
831 #[rustc_builtin_macro]
832 macro_rules! include {() => {}}
833
834 include!("foo.rs");
835
836 fn main() {
837     RegisterBlock { };
838                   //^ RegisterBlock
839 }
840     "#;
841     let fixture = format!("{}\n//- /foo.rs\n{}", fixture, data);
842
843     {
844         let _b = bench("include macro");
845         check_types(&fixture);
846     }
847 }
848
849 #[test]
850 fn infer_builtin_macros_include_concat() {
851     check_types(
852         r#"
853 //- /main.rs
854 #[rustc_builtin_macro]
855 macro_rules! include {() => {}}
856
857 #[rustc_builtin_macro]
858 macro_rules! concat {() => {}}
859
860 include!(concat!("f", "oo.rs"));
861
862 fn main() {
863     bar();
864 }     //^ u32
865
866 //- /foo.rs
867 fn bar() -> u32 {0}
868 "#,
869     );
870 }
871
872 #[test]
873 fn infer_builtin_macros_include_concat_with_bad_env_should_failed() {
874     check_types(
875         r#"
876 //- /main.rs
877 #[rustc_builtin_macro]
878 macro_rules! include {() => {}}
879
880 #[rustc_builtin_macro]
881 macro_rules! concat {() => {}}
882
883 #[rustc_builtin_macro]
884 macro_rules! env {() => {}}
885
886 include!(concat!(env!("OUT_DIR"), "/foo.rs"));
887
888 fn main() {
889     bar();
890 }     //^ {unknown}
891
892 //- /foo.rs
893 fn bar() -> u32 {0}
894 "#,
895     );
896 }
897
898 #[test]
899 fn infer_builtin_macros_include_itself_should_failed() {
900     check_types(
901         r#"
902 #[rustc_builtin_macro]
903 macro_rules! include {() => {}}
904
905 include!("main.rs");
906
907 fn main() {
908             0
909 } //^ i32
910 "#,
911     );
912 }
913
914 #[test]
915 fn infer_builtin_macros_concat_with_lazy() {
916     check_infer(
917         r#"
918         macro_rules! hello {() => {"hello"}}
919
920         #[rustc_builtin_macro]
921         macro_rules! concat {() => {}}
922
923         fn main() {
924             let x = concat!(hello!(), concat!("world", "!"));
925         }
926         "#,
927         expect![[r#"
928             !0..13 '"helloworld!"': &str
929             103..160 '{     ...")); }': ()
930             113..114 'x': &str
931         "#]],
932     );
933 }
934
935 #[test]
936 fn infer_builtin_macros_env() {
937     check_infer(
938         r#"
939         //- /main.rs env:foo=bar
940         #[rustc_builtin_macro]
941         macro_rules! env {() => {}}
942
943         fn main() {
944             let x = env!("foo");
945         }
946         "#,
947         expect![[r#"
948             !0..22 '"__RA_...TED__"': &str
949             62..90 '{     ...o"); }': ()
950             72..73 'x': &str
951         "#]],
952     );
953 }
954
955 #[test]
956 fn infer_derive_clone_simple() {
957     check_types(
958         r#"
959 //- /main.rs crate:main deps:core
960 #[derive(Clone)]
961 struct S;
962 fn test() {
963     S.clone();
964 }         //^ S
965
966 //- /lib.rs crate:core
967 #[prelude_import]
968 use clone::*;
969 mod clone {
970     trait Clone {
971         fn clone(&self) -> Self;
972     }
973     #[rustc_builtin_macro]
974     macro Clone {}
975 }
976 "#,
977     );
978 }
979
980 #[test]
981 fn infer_derive_clone_in_core() {
982     check_types(
983         r#"
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 #[derive(Clone)]
995 pub struct S;
996
997 //- /main.rs crate:main deps:core
998 use core::S;
999 fn test() {
1000     S.clone();
1001 }         //^ S
1002 "#,
1003     );
1004 }
1005
1006 #[test]
1007 fn infer_derive_clone_with_params() {
1008     check_types(
1009         r#"
1010 //- /main.rs crate:main deps:core
1011 #[derive(Clone)]
1012 struct S;
1013 #[derive(Clone)]
1014 struct Wrapper<T>(T);
1015 struct NonClone;
1016 fn test() {
1017     (Wrapper(S).clone(), Wrapper(NonClone).clone());
1018   //^ (Wrapper<S>, {unknown})
1019 }
1020
1021 //- /lib.rs crate:core
1022 #[prelude_import]
1023 use clone::*;
1024 mod clone {
1025     trait Clone {
1026         fn clone(&self) -> Self;
1027     }
1028     #[rustc_builtin_macro]
1029     macro Clone {}
1030 }
1031 "#,
1032     );
1033 }
1034
1035 #[test]
1036 fn infer_custom_derive_simple() {
1037     // FIXME: this test current now do nothing
1038     check_types(
1039         r#"
1040 //- /main.rs crate:main
1041 use foo::Foo;
1042
1043 #[derive(Foo)]
1044 struct S{}
1045
1046 fn test() {
1047     S{};
1048 }   //^ S
1049 "#,
1050     );
1051 }
1052
1053 #[test]
1054 fn macro_in_arm() {
1055     check_infer(
1056         r#"
1057         macro_rules! unit {
1058             () => { () };
1059         }
1060
1061         fn main() {
1062             let x = match () {
1063                 unit!() => 92u32,
1064             };
1065         }
1066         "#,
1067         expect![[r#"
1068             !0..2 '()': ()
1069             51..110 '{     ...  }; }': ()
1070             61..62 'x': u32
1071             65..107 'match ...     }': u32
1072             71..73 '()': ()
1073             95..100 '92u32': u32
1074         "#]],
1075     );
1076 }
1077
1078 #[test]
1079 fn macro_in_type_alias_position() {
1080     check_infer(
1081         r#"
1082         macro_rules! U32 {
1083             () => { u32 };
1084         }
1085
1086         trait Foo {
1087             type Ty;
1088         }
1089
1090         impl<T> Foo for T {
1091             type Ty = U32!();
1092         }
1093
1094         type TayTo = U32!();
1095
1096         fn testy() {
1097             let a: <() as Foo>::Ty;
1098             let b: TayTo;
1099         }
1100         "#,
1101         expect![[r#"
1102             147..196 '{     ...yTo; }': ()
1103             157..158 'a': u32
1104             185..186 'b': u32
1105         "#]],
1106     );
1107 }
1108
1109 #[test]
1110 fn nested_macro_in_type_alias_position() {
1111     check_infer(
1112         r#"
1113         macro_rules! U32Inner2 {
1114             () => { u32 };
1115         }
1116
1117         macro_rules! U32Inner1 {
1118             () => { U32Inner2!() };
1119         }
1120
1121         macro_rules! U32 {
1122             () => { U32Inner1!() };
1123         }
1124
1125         trait Foo {
1126             type Ty;
1127         }
1128
1129         impl<T> Foo for T {
1130             type Ty = U32!();
1131         }
1132
1133         type TayTo = U32!();
1134
1135         fn testy() {
1136             let a: <() as Foo>::Ty;
1137             let b: TayTo;
1138         }
1139         "#,
1140         expect![[r#"
1141             259..308 '{     ...yTo; }': ()
1142             269..270 'a': u32
1143             297..298 'b': u32
1144         "#]],
1145     );
1146 }
1147
1148 #[test]
1149 fn macros_in_type_alias_position_generics() {
1150     check_infer(
1151         r#"
1152         struct Foo<A, B>(A, B);
1153
1154         macro_rules! U32 {
1155             () => { u32 };
1156         }
1157
1158         macro_rules! Bar {
1159             () => { Foo<U32!(), U32!()> };
1160         }
1161
1162         trait Moo {
1163             type Ty;
1164         }
1165
1166         impl<T> Moo for T {
1167             type Ty = Bar!();
1168         }
1169
1170         type TayTo = Bar!();
1171
1172         fn main() {
1173             let a: <() as Moo>::Ty;
1174             let b: TayTo;
1175         }
1176         "#,
1177         expect![[r#"
1178             228..277 '{     ...yTo; }': ()
1179             238..239 'a': Foo<u32, u32>
1180             266..267 'b': Foo<u32, u32>
1181         "#]],
1182     );
1183 }
1184
1185 #[test]
1186 fn macros_in_type_position() {
1187     check_infer(
1188         r#"
1189         struct Foo<A, B>(A, B);
1190
1191         macro_rules! U32 {
1192             () => { u32 };
1193         }
1194
1195         macro_rules! Bar {
1196             () => { Foo<U32!(), U32!()> };
1197         }
1198
1199         fn main() {
1200             let a: Bar!();
1201         }
1202         "#,
1203         expect![[r#"
1204             133..155 '{     ...!(); }': ()
1205             143..144 'a': Foo<u32, u32>
1206         "#]],
1207     );
1208 }
1209
1210 #[test]
1211 fn macros_in_type_generics() {
1212     check_infer(
1213         r#"
1214         struct Foo<A, B>(A, B);
1215
1216         macro_rules! U32 {
1217             () => { u32 };
1218         }
1219
1220         macro_rules! Bar {
1221             () => { Foo<U32!(), U32!()> };
1222         }
1223
1224         trait Moo {
1225             type Ty;
1226         }
1227
1228         impl<T> Moo for T {
1229             type Ty = Foo<Bar!(), Bar!()>;
1230         }
1231
1232         type TayTo = Foo<Bar!(), U32!()>;
1233
1234         fn main() {
1235             let a: <() as Moo>::Ty;
1236             let b: TayTo;
1237         }
1238         "#,
1239         expect![[r#"
1240             254..303 '{     ...yTo; }': ()
1241             264..265 'a': Foo<Foo<u32, u32>, Foo<u32, u32>>
1242             292..293 'b': Foo<Foo<u32, u32>, u32>
1243         "#]],
1244     );
1245 }
1246
1247 #[test]
1248 fn infinitely_recursive_macro_type() {
1249     check_infer(
1250         r#"
1251         struct Bar<T, X>(T, X);
1252
1253         macro_rules! Foo {
1254             () => { Foo!() }
1255         }
1256
1257         macro_rules! U32 {
1258             () => { u32 }
1259         }
1260
1261         type A = Foo!();
1262         type B = Bar<Foo!(), U32!()>;
1263
1264         fn main() {
1265             let a: A;
1266             let b: B;
1267         }
1268         "#,
1269         expect![[r#"
1270             166..197 '{     ...: B; }': ()
1271             176..177 'a': {unknown}
1272             190..191 'b': Bar<{unknown}, u32>
1273         "#]],
1274     );
1275 }