]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/macros.rs
Basic Support Macro 2.0
[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_type_value_macro_having_same_name() {
377     check_infer(
378         r#"
379         #[macro_export]
380         macro_rules! foo {
381             () => {
382                 mod foo {
383                     pub use super::foo;
384                 }
385             };
386             ($x:tt) => {
387                 $x
388             };
389         }
390
391         foo!();
392
393         fn foo() {
394             let foo = foo::foo!(42i32);
395         }
396         "#,
397         expect![[r#"
398             !0..5 '42i32': i32
399             170..205 '{     ...32); }': ()
400             180..183 'foo': i32
401         "#]],
402     );
403 }
404
405 #[test]
406 fn processes_impls_generated_by_macros() {
407     check_types(
408         r#"
409 macro_rules! m {
410     ($ident:ident) => (impl Trait for $ident {})
411 }
412 trait Trait { fn foo(self) -> u128 {} }
413 struct S;
414 m!(S);
415 fn test() { S.foo(); }
416                 //^ u128
417 "#,
418     );
419 }
420
421 #[test]
422 fn infer_assoc_items_generated_by_macros() {
423     check_types(
424         r#"
425 macro_rules! m {
426     () => (fn foo(&self) -> u128 {0})
427 }
428 struct S;
429 impl S {
430     m!();
431 }
432
433 fn test() { S.foo(); }
434                 //^ u128
435 "#,
436     );
437 }
438
439 #[test]
440 fn infer_assoc_items_generated_by_macros_chain() {
441     check_types(
442         r#"
443 macro_rules! m_inner {
444     () => {fn foo(&self) -> u128 {0}}
445 }
446 macro_rules! m {
447     () => {m_inner!();}
448 }
449
450 struct S;
451 impl S {
452     m!();
453 }
454
455 fn test() { S.foo(); }
456                 //^ u128
457 "#,
458     );
459 }
460
461 #[test]
462 fn infer_macro_with_dollar_crate_is_correct_in_expr() {
463     check_types(
464         r#"
465 //- /main.rs crate:main deps:foo
466 fn test() {
467     let x = (foo::foo!(1), foo::foo!(2));
468     x;
469 } //^ (i32, usize)
470
471 //- /lib.rs crate:foo
472 #[macro_export]
473 macro_rules! foo {
474     (1) => { $crate::bar!() };
475     (2) => { 1 + $crate::baz() };
476 }
477
478 #[macro_export]
479 macro_rules! bar {
480     () => { 42 }
481 }
482
483 pub fn baz() -> usize { 31usize }
484 "#,
485     );
486 }
487
488 #[test]
489 fn infer_macro_with_dollar_crate_is_correct_in_trait_associate_type() {
490     check_types(
491         r#"
492 //- /main.rs crate:main deps:foo
493 use foo::Trait;
494
495 fn test() {
496     let msg = foo::Message(foo::MessageRef);
497     let r = msg.deref();
498     r;
499   //^ &MessageRef
500 }
501
502 //- /lib.rs crate:foo
503 pub struct MessageRef;
504 pub struct Message(MessageRef);
505
506 pub trait Trait {
507     type Target;
508     fn deref(&self) -> &Self::Target;
509 }
510
511 #[macro_export]
512 macro_rules! expand {
513     () => {
514         impl Trait for Message {
515             type Target = $crate::MessageRef;
516             fn deref(&self) ->  &Self::Target {
517                 &self.0
518             }
519         }
520     }
521 }
522
523 expand!();
524 "#,
525     );
526 }
527
528 #[test]
529 fn infer_macro_with_dollar_crate_in_def_site() {
530     check_types(
531         r#"
532 //- /main.rs crate:main deps:foo
533 use foo::expand;
534
535 macro_rules! list {
536     ($($tt:tt)*) => { $($tt)* }
537 }
538
539 fn test() {
540     let r = expand!();
541     r;
542   //^ u128
543 }
544
545 //- /lib.rs crate:foo
546 #[macro_export]
547 macro_rules! expand {
548     () => { list!($crate::m!()) };
549 }
550
551 #[macro_export]
552 macro_rules! m {
553     () => { 0u128 };
554 }
555 "#,
556     );
557 }
558
559 #[test]
560 fn infer_type_value_non_legacy_macro_use_as() {
561     check_infer(
562         r#"
563         mod m {
564             macro_rules! _foo {
565                 ($x:ident) => { type $x = u64; }
566             }
567             pub(crate) use _foo as foo;
568         }
569
570         m::foo!(foo);
571         use foo as bar;
572         fn f() -> bar { 0 }
573         fn main() {
574             let _a  = f();
575         }
576         "#,
577         expect![[r#"
578             158..163 '{ 0 }': u64
579             160..161 '0': u64
580             174..196 '{     ...f(); }': ()
581             184..186 '_a': u64
582             190..191 'f': fn f() -> u64
583             190..193 'f()': u64
584         "#]],
585     );
586 }
587
588 #[test]
589 fn infer_local_macro() {
590     check_infer(
591         r#"
592         fn main() {
593             macro_rules! foo {
594                 () => { 1usize }
595             }
596             let _a  = foo!();
597         }
598         "#,
599         expect![[r#"
600             !0..6 '1usize': usize
601             10..89 '{     ...!(); }': ()
602             74..76 '_a': usize
603         "#]],
604     );
605 }
606
607 #[test]
608 fn infer_local_inner_macros() {
609     check_types(
610         r#"
611 //- /main.rs crate:main deps:foo
612 fn test() {
613     let x = foo::foo!(1);
614     x;
615 } //^ i32
616
617 //- /lib.rs crate:foo
618 #[macro_export(local_inner_macros)]
619 macro_rules! foo {
620     (1) => { bar!() };
621 }
622
623 #[macro_export]
624 macro_rules! bar {
625     () => { 42 }
626 }
627
628 "#,
629     );
630 }
631
632 #[test]
633 fn infer_builtin_macros_line() {
634     check_infer(
635         r#"
636         #[rustc_builtin_macro]
637         macro_rules! line {() => {}}
638
639         fn main() {
640             let x = line!();
641         }
642         "#,
643         expect![[r#"
644             !0..1 '0': i32
645             63..87 '{     ...!(); }': ()
646             73..74 'x': i32
647         "#]],
648     );
649 }
650
651 #[test]
652 fn infer_builtin_macros_file() {
653     check_infer(
654         r#"
655         #[rustc_builtin_macro]
656         macro_rules! file {() => {}}
657
658         fn main() {
659             let x = file!();
660         }
661         "#,
662         expect![[r#"
663             !0..2 '""': &str
664             63..87 '{     ...!(); }': ()
665             73..74 'x': &str
666         "#]],
667     );
668 }
669
670 #[test]
671 fn infer_builtin_macros_column() {
672     check_infer(
673         r#"
674         #[rustc_builtin_macro]
675         macro_rules! column {() => {}}
676
677         fn main() {
678             let x = column!();
679         }
680         "#,
681         expect![[r#"
682             !0..1 '0': i32
683             65..91 '{     ...!(); }': ()
684             75..76 'x': i32
685         "#]],
686     );
687 }
688
689 #[test]
690 fn infer_builtin_macros_concat() {
691     check_infer(
692         r#"
693         #[rustc_builtin_macro]
694         macro_rules! concat {() => {}}
695
696         fn main() {
697             let x = concat!("hello", concat!("world", "!"));
698         }
699         "#,
700         expect![[r#"
701             !0..13 '"helloworld!"': &str
702             65..121 '{     ...")); }': ()
703             75..76 'x': &str
704         "#]],
705     );
706 }
707
708 #[test]
709 fn infer_builtin_macros_include() {
710     check_types(
711         r#"
712 //- /main.rs
713 #[rustc_builtin_macro]
714 macro_rules! include {() => {}}
715
716 include!("foo.rs");
717
718 fn main() {
719     bar();
720 }     //^ u32
721
722 //- /foo.rs
723 fn bar() -> u32 {0}
724 "#,
725     );
726 }
727
728 #[test]
729 fn infer_builtin_macros_include_child_mod() {
730     check_types(
731         r#"
732 //- /main.rs
733 #[rustc_builtin_macro]
734 macro_rules! include {() => {}}
735
736 include!("f/foo.rs");
737
738 fn main() {
739     bar::bar();
740 }          //^ u32
741
742 //- /f/foo.rs
743 pub mod bar;
744
745 //- /f/bar.rs
746 pub fn bar() -> u32 {0}
747 "#,
748     );
749 }
750
751 #[test]
752 fn infer_builtin_macros_include_str() {
753     check_types(
754         r#"
755 //- /main.rs
756 #[rustc_builtin_macro]
757 macro_rules! include_str {() => {}}
758
759 fn main() {
760     let a = include_str!("foo.rs");
761     a;
762 } //^ &str
763
764 //- /foo.rs
765 hello
766 "#,
767     );
768 }
769
770 #[test]
771 fn infer_builtin_macros_include_str_with_lazy_nested() {
772     check_types(
773         r#"
774 //- /main.rs
775 #[rustc_builtin_macro]
776 macro_rules! concat {() => {}}
777 #[rustc_builtin_macro]
778 macro_rules! include_str {() => {}}
779
780 macro_rules! m {
781     ($x:expr) => {
782         concat!("foo", $x)
783     };
784 }
785
786 fn main() {
787     let a = include_str!(m!(".rs"));
788     a;
789 } //^ &str
790
791 //- /foo.rs
792 hello
793 "#,
794     );
795 }
796
797 #[test]
798 fn benchmark_include_macro() {
799     if skip_slow_tests() {
800         return;
801     }
802     let data = bench_fixture::big_struct();
803     let fixture = r#"
804 //- /main.rs
805 #[rustc_builtin_macro]
806 macro_rules! include {() => {}}
807
808 include!("foo.rs");
809
810 fn main() {
811     RegisterBlock { };
812                   //^ RegisterBlock
813 }
814     "#;
815     let fixture = format!("{}\n//- /foo.rs\n{}", fixture, data);
816
817     {
818         let _b = bench("include macro");
819         check_types(&fixture);
820     }
821 }
822
823 #[test]
824 fn infer_builtin_macros_include_concat() {
825     check_types(
826         r#"
827 //- /main.rs
828 #[rustc_builtin_macro]
829 macro_rules! include {() => {}}
830
831 #[rustc_builtin_macro]
832 macro_rules! concat {() => {}}
833
834 include!(concat!("f", "oo.rs"));
835
836 fn main() {
837     bar();
838 }     //^ u32
839
840 //- /foo.rs
841 fn bar() -> u32 {0}
842 "#,
843     );
844 }
845
846 #[test]
847 fn infer_builtin_macros_include_concat_with_bad_env_should_failed() {
848     check_types(
849         r#"
850 //- /main.rs
851 #[rustc_builtin_macro]
852 macro_rules! include {() => {}}
853
854 #[rustc_builtin_macro]
855 macro_rules! concat {() => {}}
856
857 #[rustc_builtin_macro]
858 macro_rules! env {() => {}}
859
860 include!(concat!(env!("OUT_DIR"), "/foo.rs"));
861
862 fn main() {
863     bar();
864 }     //^ {unknown}
865
866 //- /foo.rs
867 fn bar() -> u32 {0}
868 "#,
869     );
870 }
871
872 #[test]
873 fn infer_builtin_macros_include_itself_should_failed() {
874     check_types(
875         r#"
876 #[rustc_builtin_macro]
877 macro_rules! include {() => {}}
878
879 include!("main.rs");
880
881 fn main() {
882             0
883 } //^ i32
884 "#,
885     );
886 }
887
888 #[test]
889 fn infer_builtin_macros_concat_with_lazy() {
890     check_infer(
891         r#"
892         macro_rules! hello {() => {"hello"}}
893
894         #[rustc_builtin_macro]
895         macro_rules! concat {() => {}}
896
897         fn main() {
898             let x = concat!(hello!(), concat!("world", "!"));
899         }
900         "#,
901         expect![[r#"
902             !0..13 '"helloworld!"': &str
903             103..160 '{     ...")); }': ()
904             113..114 'x': &str
905         "#]],
906     );
907 }
908
909 #[test]
910 fn infer_builtin_macros_env() {
911     check_infer(
912         r#"
913         //- /main.rs env:foo=bar
914         #[rustc_builtin_macro]
915         macro_rules! env {() => {}}
916
917         fn main() {
918             let x = env!("foo");
919         }
920         "#,
921         expect![[r#"
922             !0..22 '"__RA_...TED__"': &str
923             62..90 '{     ...o"); }': ()
924             72..73 'x': &str
925         "#]],
926     );
927 }
928
929 #[test]
930 fn infer_derive_clone_simple() {
931     check_types(
932         r#"
933 //- /main.rs crate:main deps:core
934 #[derive(Clone)]
935 struct S;
936 fn test() {
937     S.clone();
938 }         //^ S
939
940 //- /lib.rs crate:core
941 #[prelude_import]
942 use clone::*;
943 mod clone {
944     trait Clone {
945         fn clone(&self) -> Self;
946     }
947     #[rustc_builtin_macro]
948     macro Clone {}
949 }
950 "#,
951     );
952 }
953
954 #[test]
955 fn infer_derive_clone_in_core() {
956     check_types(
957         r#"
958 //- /lib.rs crate:core
959 #[prelude_import]
960 use clone::*;
961 mod clone {
962     trait Clone {
963         fn clone(&self) -> Self;
964     }
965     #[rustc_builtin_macro]
966     macro Clone {}
967 }
968 #[derive(Clone)]
969 pub struct S;
970
971 //- /main.rs crate:main deps:core
972 use core::S;
973 fn test() {
974     S.clone();
975 }         //^ S
976 "#,
977     );
978 }
979
980 #[test]
981 fn infer_derive_clone_with_params() {
982     check_types(
983         r#"
984 //- /main.rs crate:main deps:core
985 #[derive(Clone)]
986 struct S;
987 #[derive(Clone)]
988 struct Wrapper<T>(T);
989 struct NonClone;
990 fn test() {
991     (Wrapper(S).clone(), Wrapper(NonClone).clone());
992   //^ (Wrapper<S>, {unknown})
993 }
994
995 //- /lib.rs crate:core
996 #[prelude_import]
997 use clone::*;
998 mod clone {
999     trait Clone {
1000         fn clone(&self) -> Self;
1001     }
1002     #[rustc_builtin_macro]
1003     macro Clone {}
1004 }
1005 "#,
1006     );
1007 }
1008
1009 #[test]
1010 fn infer_custom_derive_simple() {
1011     // FIXME: this test current now do nothing
1012     check_types(
1013         r#"
1014 //- /main.rs crate:main
1015 use foo::Foo;
1016
1017 #[derive(Foo)]
1018 struct S{}
1019
1020 fn test() {
1021     S{};
1022 }   //^ S
1023 "#,
1024     );
1025 }
1026
1027 #[test]
1028 fn macro_in_arm() {
1029     check_infer(
1030         r#"
1031         macro_rules! unit {
1032             () => { () };
1033         }
1034
1035         fn main() {
1036             let x = match () {
1037                 unit!() => 92u32,
1038             };
1039         }
1040         "#,
1041         expect![[r#"
1042             51..110 '{     ...  }; }': ()
1043             61..62 'x': u32
1044             65..107 'match ...     }': u32
1045             71..73 '()': ()
1046             84..91 'unit!()': ()
1047             95..100 '92u32': u32
1048         "#]],
1049     );
1050 }