]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/macros.rs
Update tests
[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             39..442 '{     ...!(); }': ()
194             73..94 'spam!(...am!())': {unknown}
195             100..119 'for _ ...!() {}': ()
196             104..105 '_': {unknown}
197             117..119 '{}': ()
198             124..134 '|| spam!()': || -> isize
199             140..156 'while ...!() {}': ()
200             146..153 'spam!()': bool
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             53..456 '{     ...!(); }': ()
275             87..108 'spam!(...am!())': {unknown}
276             114..133 'for _ ...!() {}': ()
277             118..119 '_': {unknown}
278             131..133 '{}': ()
279             138..148 '|| spam!()': || -> isize
280             154..170 'while ...!() {}': ()
281             160..167 'spam!()': bool
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 //- minicore: derive, clone
978 #[derive(Clone)]
979 struct S;
980 fn test() {
981     S.clone();
982 } //^^^^^^^^^ S
983 "#,
984     );
985 }
986
987 #[test]
988 fn infer_derive_clone_with_params() {
989     check_types(
990         r#"
991 //- minicore: clone, derive
992 #[derive(Clone)]
993 struct S;
994 #[derive(Clone)]
995 struct Wrapper<T>(T);
996 struct NonClone;
997 fn test() {
998     let x = (Wrapper(S).clone(), Wrapper(NonClone).clone());
999     x;
1000   //^ (Wrapper<S>, {unknown})
1001 }
1002 "#,
1003     );
1004 }
1005
1006 #[test]
1007 fn infer_custom_derive_simple() {
1008     // FIXME: this test current now do nothing
1009     check_types(
1010         r#"
1011 //- minicore: derive
1012 use foo::Foo;
1013
1014 #[derive(Foo)]
1015 struct S{}
1016
1017 fn test() {
1018     S{};
1019 } //^^^ S
1020 "#,
1021     );
1022 }
1023
1024 #[test]
1025 fn macro_in_arm() {
1026     check_infer(
1027         r#"
1028         macro_rules! unit {
1029             () => { () };
1030         }
1031
1032         fn main() {
1033             let x = match () {
1034                 unit!() => 92u32,
1035             };
1036         }
1037         "#,
1038         expect![[r#"
1039             !0..2 '()': ()
1040             51..110 '{     ...  }; }': ()
1041             61..62 'x': u32
1042             65..107 'match ...     }': u32
1043             71..73 '()': ()
1044             95..100 '92u32': u32
1045         "#]],
1046     );
1047 }
1048
1049 #[test]
1050 fn macro_in_type_alias_position() {
1051     check_infer(
1052         r#"
1053         macro_rules! U32 {
1054             () => { u32 };
1055         }
1056
1057         trait Foo {
1058             type Ty;
1059         }
1060
1061         impl<T> Foo for T {
1062             type Ty = U32!();
1063         }
1064
1065         type TayTo = U32!();
1066
1067         fn testy() {
1068             let a: <() as Foo>::Ty;
1069             let b: TayTo;
1070         }
1071         "#,
1072         expect![[r#"
1073             147..196 '{     ...yTo; }': ()
1074             157..158 'a': u32
1075             185..186 'b': u32
1076         "#]],
1077     );
1078 }
1079
1080 #[test]
1081 fn nested_macro_in_type_alias_position() {
1082     check_infer(
1083         r#"
1084         macro_rules! U32Inner2 {
1085             () => { u32 };
1086         }
1087
1088         macro_rules! U32Inner1 {
1089             () => { U32Inner2!() };
1090         }
1091
1092         macro_rules! U32 {
1093             () => { U32Inner1!() };
1094         }
1095
1096         trait Foo {
1097             type Ty;
1098         }
1099
1100         impl<T> Foo for T {
1101             type Ty = U32!();
1102         }
1103
1104         type TayTo = U32!();
1105
1106         fn testy() {
1107             let a: <() as Foo>::Ty;
1108             let b: TayTo;
1109         }
1110         "#,
1111         expect![[r#"
1112             259..308 '{     ...yTo; }': ()
1113             269..270 'a': u32
1114             297..298 'b': u32
1115         "#]],
1116     );
1117 }
1118
1119 #[test]
1120 fn macros_in_type_alias_position_generics() {
1121     check_infer(
1122         r#"
1123         struct Foo<A, B>(A, B);
1124
1125         macro_rules! U32 {
1126             () => { u32 };
1127         }
1128
1129         macro_rules! Bar {
1130             () => { Foo<U32!(), U32!()> };
1131         }
1132
1133         trait Moo {
1134             type Ty;
1135         }
1136
1137         impl<T> Moo for T {
1138             type Ty = Bar!();
1139         }
1140
1141         type TayTo = Bar!();
1142
1143         fn main() {
1144             let a: <() as Moo>::Ty;
1145             let b: TayTo;
1146         }
1147         "#,
1148         expect![[r#"
1149             228..277 '{     ...yTo; }': ()
1150             238..239 'a': Foo<u32, u32>
1151             266..267 'b': Foo<u32, u32>
1152         "#]],
1153     );
1154 }
1155
1156 #[test]
1157 fn macros_in_type_position() {
1158     check_infer(
1159         r#"
1160         struct Foo<A, B>(A, B);
1161
1162         macro_rules! U32 {
1163             () => { u32 };
1164         }
1165
1166         macro_rules! Bar {
1167             () => { Foo<U32!(), U32!()> };
1168         }
1169
1170         fn main() {
1171             let a: Bar!();
1172         }
1173         "#,
1174         expect![[r#"
1175             133..155 '{     ...!(); }': ()
1176             143..144 'a': Foo<u32, u32>
1177         "#]],
1178     );
1179 }
1180
1181 #[test]
1182 fn macros_in_type_generics() {
1183     check_infer(
1184         r#"
1185         struct Foo<A, B>(A, B);
1186
1187         macro_rules! U32 {
1188             () => { u32 };
1189         }
1190
1191         macro_rules! Bar {
1192             () => { Foo<U32!(), U32!()> };
1193         }
1194
1195         trait Moo {
1196             type Ty;
1197         }
1198
1199         impl<T> Moo for T {
1200             type Ty = Foo<Bar!(), Bar!()>;
1201         }
1202
1203         type TayTo = Foo<Bar!(), U32!()>;
1204
1205         fn main() {
1206             let a: <() as Moo>::Ty;
1207             let b: TayTo;
1208         }
1209         "#,
1210         expect![[r#"
1211             254..303 '{     ...yTo; }': ()
1212             264..265 'a': Foo<Foo<u32, u32>, Foo<u32, u32>>
1213             292..293 'b': Foo<Foo<u32, u32>, u32>
1214         "#]],
1215     );
1216 }
1217
1218 #[test]
1219 fn infinitely_recursive_macro_type() {
1220     check_infer(
1221         r#"
1222         struct Bar<T, X>(T, X);
1223
1224         macro_rules! Foo {
1225             () => { Foo!() }
1226         }
1227
1228         macro_rules! U32 {
1229             () => { u32 }
1230         }
1231
1232         type A = Foo!();
1233         type B = Bar<Foo!(), U32!()>;
1234
1235         fn main() {
1236             let a: A;
1237             let b: B;
1238         }
1239         "#,
1240         expect![[r#"
1241             166..197 '{     ...: B; }': ()
1242             176..177 'a': {unknown}
1243             190..191 'b': Bar<{unknown}, u32>
1244         "#]],
1245     );
1246 }