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::session
::bug_fmt(file
!(), line
!(), format_args
!($
($message
)*))
59 macro_rules
! span_bug
{
60 ($span
:expr
, $
($message
:tt
)*) => ({
61 $
crate::session
::span_bug_fmt(file
!(), line
!(), $span
, format_args
!($
($message
)*))
66 macro_rules
! __impl_stable_hash_field
{
67 (DECL IGNORED
) => (_
);
68 (DECL $name
:ident
) => (ref $name
);
69 (USE IGNORED $ctx
:expr
, $hasher
:expr
) => ({}
);
70 (USE $name
:ident
, $ctx
:expr
, $hasher
:expr
) => ($name
.hash_stable($ctx
, $hasher
));
74 macro_rules
! impl_stable_hash_for
{
75 (enum $enum_name
:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* $(,)* }
) => {
76 impl<'a
, 'tcx
> ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>> for $enum_name
{
78 fn hash_stable
<W
: ::rustc_data_structures
::stable_hasher
::StableHasherResult
>(&self,
79 __ctx
: &mut $
crate::ich
::StableHashingContext
<'a
>,
80 __hasher
: &mut ::rustc_data_structures
::stable_hasher
::StableHasher
<W
>) {
82 ::std
::mem
::discriminant(self).hash_stable(__ctx
, __hasher
);
86 $variant $
( ( $
( __impl_stable_hash_field
!(DECL $arg
) ),* ) )* => {
87 $
($
( __impl_stable_hash_field
!(USE $arg
, __ctx
, __hasher
) );*)*
94 (struct $struct_name
:path { $($field:ident),* }
) => {
95 impl<'a
, 'tcx
> ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>> for $struct_name
{
97 fn hash_stable
<W
: ::rustc_data_structures
::stable_hasher
::StableHasherResult
>(&self,
98 __ctx
: &mut $
crate::ich
::StableHashingContext
<'a
>,
99 __hasher
: &mut ::rustc_data_structures
::stable_hasher
::StableHasher
<W
>) {
104 $
( $field
.hash_stable(__ctx
, __hasher
));*
108 (tuple_struct $struct_name
:path { $($field:ident),* }
) => {
109 impl<'a
, 'tcx
> ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>> for $struct_name
{
111 fn hash_stable
<W
: ::rustc_data_structures
::stable_hasher
::StableHasherResult
>(&self,
112 __ctx
: &mut $
crate::ich
::StableHashingContext
<'a
>,
113 __hasher
: &mut ::rustc_data_structures
::stable_hasher
::StableHasher
<W
>) {
118 $
( $field
.hash_stable(__ctx
, __hasher
));*
123 (impl<$tcx
:lifetime $
(, $T
:ident
)*> for struct $struct_name
:path
{
124 $
($field
:ident
),* $
(,)*
126 impl<'a
, $tcx
, $
($T
,)*> ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>> for $struct_name
127 where $
($T
: ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>>),*
130 fn hash_stable
<W
: ::rustc_data_structures
::stable_hasher
::StableHasherResult
>(&self,
131 __ctx
: &mut $
crate::ich
::StableHashingContext
<'a
>,
132 __hasher
: &mut ::rustc_data_structures
::stable_hasher
::StableHasher
<W
>) {
137 $
( $field
.hash_stable(__ctx
, __hasher
));*
144 macro_rules
! impl_stable_hash_for_spanned
{
147 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for ::syntax
::codemap
::Spanned
<$T
>
150 fn hash_stable
<W
: StableHasherResult
>(&self,
151 hcx
: &mut StableHashingContext
<'a
>,
152 hasher
: &mut StableHasher
<W
>) {
153 self.node
.hash_stable(hcx
, hasher
);
154 self.span
.hash_stable(hcx
, hasher
);
160 ///////////////////////////////////////////////////////////////////////////
161 // Lift and TypeFoldable macros
163 // When possible, use one of these (relatively) convenient macros to write
164 // the impls for you.
167 macro_rules
! CloneLiftImpls
{
168 (for <$tcx
:lifetime
> { $($ty:ty,)+ }
) => {
170 impl<$tcx
> $
crate::ty
::Lift
<$tcx
> for $ty
{
172 fn lift_to_tcx
<'a
, 'gcx
>(&self, _
: $
crate::ty
::TyCtxt
<'a
, 'gcx
, $tcx
>) -> Option
<Self> {
173 Some(Clone
::clone(self))
188 /// Used for types that are `Copy` and which **do not care arena
189 /// allocated data** (i.e., don't need to be folded).
191 macro_rules
! CloneTypeFoldableImpls
{
192 (for <$tcx
:lifetime
> { $($ty:ty,)+ }
) => {
194 impl<$tcx
> $
crate::ty
::fold
::TypeFoldable
<$tcx
> for $ty
{
195 fn super_fold_with
<'gcx
: $tcx
, F
: $
crate::ty
::fold
::TypeFolder
<'gcx
, $tcx
>>(
202 fn super_visit_with
<F
: $
crate::ty
::fold
::TypeVisitor
<$tcx
>>(
214 CloneTypeFoldableImpls
! {
223 macro_rules
! CloneTypeFoldableAndLiftImpls
{
225 CloneTypeFoldableImpls
! { $($t)* }
226 CloneLiftImpls
! { $($t)* }
231 macro_rules
! BraceStructLiftImpl
{
232 (impl<$
($p
:tt
),*> Lift
<$tcx
:tt
> for $s
:path
{
233 type Lifted
= $lifted
:ty
;
234 $
($field
:ident
),* $
(,)*
235 } $
(where $
($wc
:tt
)*)*) => {
236 impl<$
($p
),*> $
crate::ty
::Lift
<$tcx
> for $s
239 type Lifted
= $lifted
;
241 fn lift_to_tcx
<'b
, 'gcx
>(&self, tcx
: TyCtxt
<'b
, 'gcx
, 'tcx
>) -> Option
<$lifted
> {
242 $
(let $field
= tcx
.lift(&self.$field
)?
;)*
243 Some(Self::Lifted { $($field),* }
)
250 macro_rules
! EnumLiftImpl
{
251 (impl<$
($p
:tt
),*> Lift
<$tcx
:tt
> for $s
:path
{
252 type Lifted
= $lifted
:ty
;
254 ($variant
:path
) ( $
( $variant_arg
: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
> {
265 $
($
variant ( $
($variant_arg
),* ) => {
266 Some($
variant ( $
(tcx
.lift($variant_arg
)?
),* ))
275 macro_rules
! BraceStructTypeFoldableImpl
{
276 (impl<$
($p
:tt
),*> TypeFoldable
<$tcx
:tt
> for $s
:path
{
277 $
($field
:ident
),* $
(,)*
278 } $
(where $
($wc
:tt
)*)*) => {
279 impl<$
($p
),*> $
crate::ty
::fold
::TypeFoldable
<$tcx
> for $s
282 fn super_fold_with
<'gcx
: $tcx
, V
: $
crate::ty
::fold
::TypeFolder
<'gcx
, $tcx
>>(
286 let $s { $($field,)* }
= self;
287 $s { $($field: $crate::ty::fold::TypeFoldable::fold_with($field, folder),)* }
290 fn super_visit_with
<V
: $
crate::ty
::fold
::TypeVisitor
<$tcx
>>(
294 let $s { $($field,)* }
= self;
295 false $
(|| $
crate::ty
::fold
::TypeFoldable
::visit_with($field
, visitor
))*
302 macro_rules
! TupleStructTypeFoldableImpl
{
303 (impl<$
($p
:tt
),*> TypeFoldable
<$tcx
:tt
> for $s
:path
{
304 $
($field
:ident
),* $
(,)*
305 } $
(where $
($wc
:tt
)*)*) => {
306 impl<$
($p
),*> $
crate::ty
::fold
::TypeFoldable
<$tcx
> for $s
309 fn super_fold_with
<'gcx
: $tcx
, V
: $
crate::ty
::fold
::TypeFolder
<'gcx
, $tcx
>>(
313 let $
s($
($field
,)*)= self;
314 $
s($
($
crate::ty
::fold
::TypeFoldable
::fold_with($field
, folder
),)*)
317 fn super_visit_with
<V
: $
crate::ty
::fold
::TypeVisitor
<$tcx
>>(
321 let $
s($
($field
,)*) = self;
322 false $
(|| $
crate::ty
::fold
::TypeFoldable
::visit_with($field
, visitor
))*
329 macro_rules
! EnumTypeFoldableImpl
{
330 (impl<$
($p
:tt
),*> TypeFoldable
<$tcx
:tt
> for $s
:path
{
332 } $
(where $
($wc
:tt
)*)*) => {
333 impl<$
($p
),*> $
crate::ty
::fold
::TypeFoldable
<$tcx
> for $s
336 fn super_fold_with
<'gcx
: $tcx
, V
: $
crate::ty
::fold
::TypeFolder
<'gcx
, $tcx
>>(
340 EnumTypeFoldableImpl
!(@
FoldVariants(self, folder
) input($
($variants
)*) output())
343 fn super_visit_with
<V
: $
crate::ty
::fold
::TypeVisitor
<$tcx
>>(
347 EnumTypeFoldableImpl
!(@
VisitVariants(self, visitor
) input($
($variants
)*) output())
352 (@
FoldVariants($this
:expr
, $folder
:expr
) input() output($
($output
:tt
)*)) => {
358 (@
FoldVariants($this
:expr
, $folder
:expr
)
359 input( ($variant
:path
) ( $
($variant_arg
:ident
),* ) , $
($input
:tt
)*)
360 output( $
($output
:tt
)*) ) => {
361 EnumTypeFoldableImpl
!(
362 @
FoldVariants($this
, $folder
)
365 $
variant ( $
($variant_arg
),* ) => {
367 $
($
crate::ty
::fold
::TypeFoldable
::fold_with($variant_arg
, $folder
)),*
375 (@
FoldVariants($this
:expr
, $folder
:expr
)
376 input( ($variant
:path
) { $($variant_arg:ident),* $(,)* }
, $
($input
:tt
)*)
377 output( $
($output
:tt
)*) ) => {
378 EnumTypeFoldableImpl
!(
379 @
FoldVariants($this
, $folder
)
382 $variant { $($variant_arg),* }
=> {
384 $
($variant_arg
: $
crate::ty
::fold
::TypeFoldable
::fold_with(
385 $variant_arg
, $folder
393 (@
FoldVariants($this
:expr
, $folder
:expr
)
394 input( ($variant
:path
), $
($input
:tt
)*)
395 output( $
($output
:tt
)*) ) => {
396 EnumTypeFoldableImpl
!(
397 @
FoldVariants($this
, $folder
)
400 $variant
=> { $variant }
406 (@
VisitVariants($this
:expr
, $visitor
:expr
) input() output($
($output
:tt
)*)) => {
412 (@
VisitVariants($this
:expr
, $visitor
:expr
)
413 input( ($variant
:path
) ( $
($variant_arg
:ident
),* ) , $
($input
:tt
)*)
414 output( $
($output
:tt
)*) ) => {
415 EnumTypeFoldableImpl
!(
416 @
VisitVariants($this
, $visitor
)
419 $
variant ( $
($variant_arg
),* ) => {
420 false $
(|| $
crate::ty
::fold
::TypeFoldable
::visit_with(
421 $variant_arg
, $visitor
429 (@
VisitVariants($this
:expr
, $visitor
:expr
)
430 input( ($variant
:path
) { $($variant_arg:ident),* $(,)* }
, $
($input
:tt
)*)
431 output( $
($output
:tt
)*) ) => {
432 EnumTypeFoldableImpl
!(
433 @
VisitVariants($this
, $visitor
)
436 $variant { $($variant_arg),* }
=> {
437 false $
(|| $
crate::ty
::fold
::TypeFoldable
::visit_with(
438 $variant_arg
, $visitor
446 (@
VisitVariants($this
:expr
, $visitor
:expr
)
447 input( ($variant
:path
), $
($input
:tt
)*)
448 output( $
($output
:tt
)*) ) => {
449 EnumTypeFoldableImpl
!(
450 @
VisitVariants($this
, $visitor
)
453 $variant
=> { false }