1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // ignore-tidy-linelength
13 macro_rules! enum_from_u32 {
14 ($(#[$attr:meta])* pub enum $name:ident {
15 $($variant:ident = $e:expr,)*
23 pub fn from_u32(u: u32) -> Option<$name> {
24 $(if u == $name::$variant as u32 {
25 return Some($name::$variant)
31 ($(#[$attr:meta])* pub enum $name:ident {
40 pub fn from_u32(u: u32) -> Option<$name> {
41 $(if u == $name::$variant as u32 {
42 return Some($name::$variant)
52 () => ( bug!("impossible case reached") );
53 ($($message:tt)*) => ({
54 $crate::util::bug::bug_fmt(file!(), line!(), format_args!($($message)*))
59 macro_rules! span_bug {
60 ($span:expr, $($message:tt)*) => ({
61 $crate::util::bug::span_bug_fmt(file!(), line!(), $span, format_args!($($message)*))
66 macro_rules! static_assert {
67 ($name:ident: $test:expr) => {
68 // Use the bool to access an array such that if the bool is false, the access
71 static $name: () = [()][!$test as usize];
76 macro_rules! __impl_stable_hash_field {
77 ($field:ident, $ctx:expr, $hasher:expr) => ($field.hash_stable($ctx, $hasher));
78 ($field:ident, $ctx:expr, $hasher:expr, _) => ({ let _ = $field; });
79 ($field:ident, $ctx:expr, $hasher:expr, $delegate:expr) => ($delegate.hash_stable($ctx, $hasher));
83 macro_rules! impl_stable_hash_for {
84 // FIXME(mark-i-m): Some of these should be `?` rather than `*`. See the git blame and change
85 // them back when `?` is supported again.
86 (enum $enum_name:path {
88 // this incorrectly allows specifying both tuple-like and struct-like fields, as in `Variant(a,b){c,d}`,
89 // when it should be only one or the other
90 $( ( $($field:ident $(-> $delegate:tt)*),* ) )*
91 $( { $($named_field:ident $(-> $named_delegate:tt)*),* } )*
94 impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $enum_name {
96 fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
97 __ctx: &mut $crate::ich::StableHashingContext<'a>,
98 __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
100 ::std::mem::discriminant(self).hash_stable(__ctx, __hasher);
104 $variant $( ( $(ref $field),* ) )* $( { $(ref $named_field),* } )* => {
105 $($( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*)*
106 $($( __impl_stable_hash_field!($named_field, __ctx, __hasher $(, $named_delegate)*) );*)*
113 // FIXME(mark-i-m): same here.
114 (struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => {
115 impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name {
117 fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
118 __ctx: &mut $crate::ich::StableHashingContext<'a>,
119 __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
124 $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
128 // FIXME(mark-i-m): same here.
129 (tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => {
130 impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name {
132 fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
133 __ctx: &mut $crate::ich::StableHashingContext<'a>,
134 __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
139 $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
144 (impl<$tcx:lifetime $(, $lt:lifetime $(: $lt_bound:lifetime)*)* $(, $T:ident)*> for struct $struct_name:path {
145 $($field:ident $(-> $delegate:tt)*),* $(,)*
147 impl<'a, $tcx, $($lt $(: $lt_bound)*,)* $($T,)*>
148 ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name
149 where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),*
152 fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
153 __ctx: &mut $crate::ich::StableHashingContext<'a>,
154 __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
159 $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
166 macro_rules! impl_stable_hash_for_spanned {
169 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ::syntax::source_map::Spanned<$T>
172 fn hash_stable<W: StableHasherResult>(&self,
173 hcx: &mut StableHashingContext<'a>,
174 hasher: &mut StableHasher<W>) {
175 self.node.hash_stable(hcx, hasher);
176 self.span.hash_stable(hcx, hasher);
182 ///////////////////////////////////////////////////////////////////////////
183 // Lift and TypeFoldable macros
185 // When possible, use one of these (relatively) convenient macros to write
186 // the impls for you.
189 macro_rules! CloneLiftImpls {
190 (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
192 impl<$tcx> $crate::ty::Lift<$tcx> for $ty {
194 fn lift_to_tcx<'a, 'gcx>(&self, _: $crate::ty::TyCtxt<'a, 'gcx, $tcx>) -> Option<Self> {
195 Some(Clone::clone(self))
210 /// Used for types that are `Copy` and which **do not care arena
211 /// allocated data** (i.e., don't need to be folded).
213 macro_rules! CloneTypeFoldableImpls {
214 (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
216 impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty {
217 fn super_fold_with<'gcx: $tcx, F: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
224 fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
236 CloneTypeFoldableImpls! {
245 macro_rules! CloneTypeFoldableAndLiftImpls {
247 CloneTypeFoldableImpls! { $($t)* }
248 CloneLiftImpls! { $($t)* }
253 macro_rules! BraceStructLiftImpl {
254 (impl<$($p:tt),*> Lift<$tcx:tt> for $s:path {
255 type Lifted = $lifted:ty;
256 $($field:ident),* $(,)*
257 } $(where $($wc:tt)*)*) => {
258 impl<$($p),*> $crate::ty::Lift<$tcx> for $s
261 type Lifted = $lifted;
263 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> {
264 $(let $field = tcx.lift(&self.$field)?;)*
265 Some(Self::Lifted { $($field),* })
272 macro_rules! EnumLiftImpl {
273 (impl<$($p:tt),*> Lift<$tcx:tt> for $s:path {
274 type Lifted = $lifted:ty;
276 } $(where $($wc:tt)*)*) => {
277 impl<$($p),*> $crate::ty::Lift<$tcx> for $s
280 type Lifted = $lifted;
282 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> {
283 EnumLiftImpl!(@Variants(self, tcx) input($($variants)*) output())
288 (@Variants($this:expr, $tcx:expr) input() output($($output:tt)*)) => {
294 (@Variants($this:expr, $tcx:expr)
295 input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
296 output( $($output:tt)*) ) => {
298 @Variants($this, $tcx)
301 $variant ( $($variant_arg),* ) => {
302 Some($variant ( $($tcx.lift($variant_arg)?),* ))
309 (@Variants($this:expr, $tcx:expr)
310 input( ($variant:path), $($input:tt)*)
311 output( $($output:tt)*) ) => {
313 @Variants($this, $tcx)
316 $variant => { Some($variant) }
324 macro_rules! BraceStructTypeFoldableImpl {
325 (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
326 $($field:ident),* $(,)*
327 } $(where $($wc:tt)*)*) => {
328 impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
331 fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
335 let $s { $($field,)* } = self;
336 $s { $($field: $crate::ty::fold::TypeFoldable::fold_with($field, folder),)* }
339 fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
343 let $s { $($field,)* } = self;
344 false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))*
351 macro_rules! TupleStructTypeFoldableImpl {
352 (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
353 $($field:ident),* $(,)*
354 } $(where $($wc:tt)*)*) => {
355 impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
358 fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
362 let $s($($field,)*)= self;
363 $s($($crate::ty::fold::TypeFoldable::fold_with($field, folder),)*)
366 fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
370 let $s($($field,)*) = self;
371 false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))*
378 macro_rules! EnumTypeFoldableImpl {
379 (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
381 } $(where $($wc:tt)*)*) => {
382 impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
385 fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
389 EnumTypeFoldableImpl!(@FoldVariants(self, folder) input($($variants)*) output())
392 fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
396 EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
401 (@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => {
407 (@FoldVariants($this:expr, $folder:expr)
408 input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
409 output( $($output:tt)*) ) => {
410 EnumTypeFoldableImpl!(
411 @FoldVariants($this, $folder)
414 $variant ( $($variant_arg),* ) => {
416 $($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)),*
424 (@FoldVariants($this:expr, $folder:expr)
425 input( ($variant:path) { $($variant_arg:ident),* $(,)* } , $($input:tt)*)
426 output( $($output:tt)*) ) => {
427 EnumTypeFoldableImpl!(
428 @FoldVariants($this, $folder)
431 $variant { $($variant_arg),* } => {
433 $($variant_arg: $crate::ty::fold::TypeFoldable::fold_with(
434 $variant_arg, $folder
442 (@FoldVariants($this:expr, $folder:expr)
443 input( ($variant:path), $($input:tt)*)
444 output( $($output:tt)*) ) => {
445 EnumTypeFoldableImpl!(
446 @FoldVariants($this, $folder)
449 $variant => { $variant }
455 (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => {
461 (@VisitVariants($this:expr, $visitor:expr)
462 input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
463 output( $($output:tt)*) ) => {
464 EnumTypeFoldableImpl!(
465 @VisitVariants($this, $visitor)
468 $variant ( $($variant_arg),* ) => {
469 false $(|| $crate::ty::fold::TypeFoldable::visit_with(
470 $variant_arg, $visitor
478 (@VisitVariants($this:expr, $visitor:expr)
479 input( ($variant:path) { $($variant_arg:ident),* $(,)* } , $($input:tt)*)
480 output( $($output:tt)*) ) => {
481 EnumTypeFoldableImpl!(
482 @VisitVariants($this, $visitor)
485 $variant { $($variant_arg),* } => {
486 false $(|| $crate::ty::fold::TypeFoldable::visit_with(
487 $variant_arg, $visitor
495 (@VisitVariants($this:expr, $visitor:expr)
496 input( ($variant:path), $($input:tt)*)
497 output( $($output:tt)*) ) => {
498 EnumTypeFoldableImpl!(
499 @VisitVariants($this, $visitor)
502 $variant => { false }