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 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! TrivialTypeFoldableImpls { 52 (for <$tcx:lifetime> { $($ty:ty,)+ }) => { 53 $( 54 impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty { 55 fn super_fold_with<F: $crate::ty::fold::TypeFolder<$tcx>>( 56 self, 57 _: &mut F 58 ) -> $ty { 59 self 60 } 61 62 fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>( 63 &self, 64 _: &mut F) 65 -> ::std::ops::ControlFlow<F::BreakTy> 66 { 67 ::std::ops::ControlFlow::CONTINUE 68 } 69 } 70 )+ 71 }; 72 73 ($($ty:ty,)+) => { 74 TrivialTypeFoldableImpls! { 75 for <'tcx> { 76 $($ty,)+ 77 } 78 } 79 }; 80 } 81 82 #[macro_export] 83 macro_rules! TrivialTypeFoldableAndLiftImpls { 84 ($($t:tt)*) => { 85 TrivialTypeFoldableImpls! { $($t)* } 86 CloneLiftImpls! { $($t)* } 87 } 88 } 89 90 #[macro_export] 91 macro_rules! EnumTypeFoldableImpl { 92 (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { 93 $($variants:tt)* 94 } $(where $($wc:tt)*)*) => { 95 impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s 96 $(where $($wc)*)* 97 { 98 fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>( 99 self, 100 folder: &mut V, 101 ) -> Self { 102 EnumTypeFoldableImpl!(@FoldVariants(self, folder) input($($variants)*) output()) 103 } 104 105 fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>( 106 &self, 107 visitor: &mut V, 108 ) -> ::std::ops::ControlFlow<V::BreakTy> { 109 EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) 110 } 111 } 112 }; 113 114 (@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => { 115 match $this { 116 $($output)* 117 } 118 }; 119 120 (@FoldVariants($this:expr, $folder:expr) 121 input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) 122 output( $($output:tt)*) ) => { 123 EnumTypeFoldableImpl!( 124 @FoldVariants($this, $folder) 125 input($($input)*) 126 output( 127 $variant ( $($variant_arg),* ) => { 128 $variant ( 129 $($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)),* 130 ) 131 } 132 $($output)* 133 ) 134 ) 135 }; 136 137 (@FoldVariants($this:expr, $folder:expr) 138 input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*) 139 output( $($output:tt)*) ) => { 140 EnumTypeFoldableImpl!( 141 @FoldVariants($this, $folder) 142 input($($input)*) 143 output( 144 $variant { $($variant_arg),* } => { 145 $variant { 146 $($variant_arg: $crate::ty::fold::TypeFoldable::fold_with( 147 $variant_arg, $folder 148 )),* } 149 } 150 $($output)* 151 ) 152 ) 153 }; 154 155 (@FoldVariants($this:expr, $folder:expr) 156 input( ($variant:path), $($input:tt)*) 157 output( $($output:tt)*) ) => { 158 EnumTypeFoldableImpl!( 159 @FoldVariants($this, $folder) 160 input($($input)*) 161 output( 162 $variant => { $variant } 163 $($output)* 164 ) 165 ) 166 }; 167 168 (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => { 169 match $this { 170 $($output)* 171 } 172 }; 173 174 (@VisitVariants($this:expr, $visitor:expr) 175 input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) 176 output( $($output:tt)*) ) => { 177 EnumTypeFoldableImpl!( 178 @VisitVariants($this, $visitor) 179 input($($input)*) 180 output( 181 $variant ( $($variant_arg),* ) => { 182 $($crate::ty::fold::TypeFoldable::visit_with( 183 $variant_arg, $visitor 184 )?;)* 185 ::std::ops::ControlFlow::CONTINUE 186 } 187 $($output)* 188 ) 189 ) 190 }; 191 192 (@VisitVariants($this:expr, $visitor:expr) 193 input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*) 194 output( $($output:tt)*) ) => { 195 EnumTypeFoldableImpl!( 196 @VisitVariants($this, $visitor) 197 input($($input)*) 198 output( 199 $variant { $($variant_arg),* } => { 200 $($crate::ty::fold::TypeFoldable::visit_with( 201 $variant_arg, $visitor 202 )?;)* 203 ::std::ops::ControlFlow::CONTINUE 204 } 205 $($output)* 206 ) 207 ) 208 }; 209 210 (@VisitVariants($this:expr, $visitor:expr) 211 input( ($variant:path), $($input:tt)*) 212 output( $($output:tt)*) ) => { 213 EnumTypeFoldableImpl!( 214 @VisitVariants($this, $visitor) 215 input($($input)*) 216 output( 217 $variant => { ::std::ops::ControlFlow::CONTINUE } 218 $($output)* 219 ) 220 ) 221 }; 222 } 223