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