]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/macros.rs
Rollup merge of #98441 - calebzulawski:simd_as, r=oli-obk
[rust.git] / compiler / rustc_middle / src / macros.rs
1 #[macro_export]
2 macro_rules! bug {
3     () => ( $crate::bug!("impossible case reached") );
4     ($msg:expr) => ({ $crate::util::bug::bug_fmt(::std::format_args!($msg)) });
5     ($msg:expr,) => ({ $crate::bug!($msg) });
6     ($fmt:expr, $($arg:tt)+) => ({
7         $crate::util::bug::bug_fmt(::std::format_args!($fmt, $($arg)+))
8     });
9 }
10
11 #[macro_export]
12 macro_rules! span_bug {
13     ($span:expr, $msg:expr) => ({ $crate::util::bug::span_bug_fmt($span, ::std::format_args!($msg)) });
14     ($span:expr, $msg:expr,) => ({ $crate::span_bug!($span, $msg) });
15     ($span:expr, $fmt:expr, $($arg:tt)+) => ({
16         $crate::util::bug::span_bug_fmt($span, ::std::format_args!($fmt, $($arg)+))
17     });
18 }
19
20 ///////////////////////////////////////////////////////////////////////////
21 // Lift and TypeFoldable/TypeVisitable macros
22 //
23 // When possible, use one of these (relatively) convenient macros to write
24 // the impls for you.
25
26 #[macro_export]
27 macro_rules! CloneLiftImpls {
28     (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
29         $(
30             impl<$tcx> $crate::ty::Lift<$tcx> for $ty {
31                 type Lifted = Self;
32                 fn lift_to_tcx(self, _: $crate::ty::TyCtxt<$tcx>) -> Option<Self> {
33                     Some(self)
34                 }
35             }
36         )+
37     };
38
39     ($($ty:ty,)+) => {
40         CloneLiftImpls! {
41             for <'tcx> {
42                 $($ty,)+
43             }
44         }
45     };
46 }
47
48 /// Used for types that are `Copy` and which **do not care arena
49 /// allocated data** (i.e., don't need to be folded).
50 #[macro_export]
51 macro_rules! TrivialTypeTraversalImpls {
52     (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
53         $(
54             impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty {
55                 fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$tcx>>(
56                     self,
57                     _: &mut F
58                 ) -> ::std::result::Result<$ty, F::Error> {
59                     Ok(self)
60                 }
61             }
62
63             impl<$tcx> $crate::ty::visit::TypeVisitable<$tcx> for $ty {
64                 fn visit_with<F: $crate::ty::visit::TypeVisitor<$tcx>>(
65                     &self,
66                     _: &mut F)
67                     -> ::std::ops::ControlFlow<F::BreakTy>
68                 {
69                     ::std::ops::ControlFlow::CONTINUE
70                 }
71             }
72         )+
73     };
74
75     ($($ty:ty,)+) => {
76         TrivialTypeTraversalImpls! {
77             for <'tcx> {
78                 $($ty,)+
79             }
80         }
81     };
82 }
83
84 #[macro_export]
85 macro_rules! TrivialTypeTraversalAndLiftImpls {
86     ($($t:tt)*) => {
87         TrivialTypeTraversalImpls! { $($t)* }
88         CloneLiftImpls! { $($t)* }
89     }
90 }
91
92 #[macro_export]
93 macro_rules! EnumTypeTraversalImpl {
94     (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
95         $($variants:tt)*
96     } $(where $($wc:tt)*)*) => {
97         impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
98             $(where $($wc)*)*
99         {
100             fn try_fold_with<V: $crate::ty::fold::FallibleTypeFolder<$tcx>>(
101                 self,
102                 folder: &mut V,
103             ) -> ::std::result::Result<Self, V::Error> {
104                 EnumTypeTraversalImpl!(@FoldVariants(self, folder) input($($variants)*) output())
105             }
106         }
107     };
108
109     (impl<$($p:tt),*> TypeVisitable<$tcx:tt> for $s:path {
110         $($variants:tt)*
111     } $(where $($wc:tt)*)*) => {
112         impl<$($p),*> $crate::ty::visit::TypeVisitable<$tcx> for $s
113             $(where $($wc)*)*
114         {
115             fn visit_with<V: $crate::ty::visit::TypeVisitor<$tcx>>(
116                 &self,
117                 visitor: &mut V,
118             ) -> ::std::ops::ControlFlow<V::BreakTy> {
119                 EnumTypeTraversalImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
120             }
121         }
122     };
123
124     (@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => {
125         Ok(match $this {
126             $($output)*
127         })
128     };
129
130     (@FoldVariants($this:expr, $folder:expr)
131      input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
132      output( $($output:tt)*) ) => {
133         EnumTypeTraversalImpl!(
134             @FoldVariants($this, $folder)
135                 input($($input)*)
136                 output(
137                     $variant ( $($variant_arg),* ) => {
138                         $variant (
139                             $($crate::ty::fold::TypeFoldable::try_fold_with($variant_arg, $folder)?),*
140                         )
141                     }
142                     $($output)*
143                 )
144         )
145     };
146
147     (@FoldVariants($this:expr, $folder:expr)
148      input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*)
149      output( $($output:tt)*) ) => {
150         EnumTypeTraversalImpl!(
151             @FoldVariants($this, $folder)
152                 input($($input)*)
153                 output(
154                     $variant { $($variant_arg),* } => {
155                         $variant {
156                             $($variant_arg: $crate::ty::fold::TypeFoldable::fold_with(
157                                 $variant_arg, $folder
158                             )?),* }
159                     }
160                     $($output)*
161                 )
162         )
163     };
164
165     (@FoldVariants($this:expr, $folder:expr)
166      input( ($variant:path), $($input:tt)*)
167      output( $($output:tt)*) ) => {
168         EnumTypeTraversalImpl!(
169             @FoldVariants($this, $folder)
170                 input($($input)*)
171                 output(
172                     $variant => { $variant }
173                     $($output)*
174                 )
175         )
176     };
177
178     (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => {
179         match $this {
180             $($output)*
181         }
182     };
183
184     (@VisitVariants($this:expr, $visitor:expr)
185      input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
186      output( $($output:tt)*) ) => {
187         EnumTypeTraversalImpl!(
188             @VisitVariants($this, $visitor)
189                 input($($input)*)
190                 output(
191                     $variant ( $($variant_arg),* ) => {
192                         $($crate::ty::visit::TypeVisitable::visit_with(
193                             $variant_arg, $visitor
194                         )?;)*
195                         ::std::ops::ControlFlow::CONTINUE
196                     }
197                     $($output)*
198                 )
199         )
200     };
201
202     (@VisitVariants($this:expr, $visitor:expr)
203      input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*)
204      output( $($output:tt)*) ) => {
205         EnumTypeTraversalImpl!(
206             @VisitVariants($this, $visitor)
207                 input($($input)*)
208                 output(
209                     $variant { $($variant_arg),* } => {
210                         $($crate::ty::visit::TypeVisitable::visit_with(
211                             $variant_arg, $visitor
212                         )?;)*
213                         ::std::ops::ControlFlow::CONTINUE
214                     }
215                     $($output)*
216                 )
217         )
218     };
219
220     (@VisitVariants($this:expr, $visitor:expr)
221      input( ($variant:path), $($input:tt)*)
222      output( $($output:tt)*) ) => {
223         EnumTypeTraversalImpl!(
224             @VisitVariants($this, $visitor)
225                 input($($input)*)
226                 output(
227                     $variant => { ::std::ops::ControlFlow::CONTINUE }
228                     $($output)*
229                 )
230         )
231     };
232 }