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 ($field
:ident
, $ctx
:expr
, $hasher
:expr
) => ($field
.hash_stable($ctx
, $hasher
));
68 ($field
:ident
, $ctx
:expr
, $hasher
:expr
, _
) => ({ let _ = $field; }
);
69 ($field
:ident
, $ctx
:expr
, $hasher
:expr
, $delegate
:expr
) => ($delegate
.hash_stable($ctx
, $hasher
));
73 macro_rules
! impl_stable_hash_for
{
74 // FIXME(mark-i-m): Some of these should be `?` rather than `*`. See the git blame and change
75 // them back when `?` is supported again.
76 (enum $enum_name
:path { $( $variant:ident $( ( $($field:ident $(-> $delegate:tt)*),* ) )* ),* $(,)* }
) => {
77 impl<'a
, 'tcx
> ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>> for $enum_name
{
79 fn hash_stable
<W
: ::rustc_data_structures
::stable_hasher
::StableHasherResult
>(&self,
80 __ctx
: &mut $
crate::ich
::StableHashingContext
<'a
>,
81 __hasher
: &mut ::rustc_data_structures
::stable_hasher
::StableHasher
<W
>) {
83 ::std
::mem
::discriminant(self).hash_stable(__ctx
, __hasher
);
87 $variant $
( ( $
(ref $field
),* ) )* => {
88 $
($
( __impl_stable_hash_field
!($field
, __ctx
, __hasher $
(, $delegate
)*) );*)*
95 // FIXME(mark-i-m): same here.
96 (struct $struct_name
:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }
) => {
97 impl<'a
, 'tcx
> ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>> for $struct_name
{
99 fn hash_stable
<W
: ::rustc_data_structures
::stable_hasher
::StableHasherResult
>(&self,
100 __ctx
: &mut $
crate::ich
::StableHashingContext
<'a
>,
101 __hasher
: &mut ::rustc_data_structures
::stable_hasher
::StableHasher
<W
>) {
106 $
( __impl_stable_hash_field
!($field
, __ctx
, __hasher $
(, $delegate
)*) );*
110 // FIXME(mark-i-m): same here.
111 (tuple_struct $struct_name
:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }
) => {
112 impl<'a
, 'tcx
> ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>> for $struct_name
{
114 fn hash_stable
<W
: ::rustc_data_structures
::stable_hasher
::StableHasherResult
>(&self,
115 __ctx
: &mut $
crate::ich
::StableHashingContext
<'a
>,
116 __hasher
: &mut ::rustc_data_structures
::stable_hasher
::StableHasher
<W
>) {
121 $
( __impl_stable_hash_field
!($field
, __ctx
, __hasher $
(, $delegate
)*) );*
126 (impl<$tcx
:lifetime $
(, $T
:ident
)*> for struct $struct_name
:path
{
127 $
($field
:ident
),* $
(,)*
129 impl<'a
, $tcx
, $
($T
,)*> ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>> for $struct_name
130 where $
($T
: ::rustc_data_structures
::stable_hasher
::HashStable
<$
crate::ich
::StableHashingContext
<'a
>>),*
133 fn hash_stable
<W
: ::rustc_data_structures
::stable_hasher
::StableHasherResult
>(&self,
134 __ctx
: &mut $
crate::ich
::StableHashingContext
<'a
>,
135 __hasher
: &mut ::rustc_data_structures
::stable_hasher
::StableHasher
<W
>) {
140 $
( $field
.hash_stable(__ctx
, __hasher
));*
147 macro_rules
! impl_stable_hash_for_spanned
{
150 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for ::syntax
::codemap
::Spanned
<$T
>
153 fn hash_stable
<W
: StableHasherResult
>(&self,
154 hcx
: &mut StableHashingContext
<'a
>,
155 hasher
: &mut StableHasher
<W
>) {
156 self.node
.hash_stable(hcx
, hasher
);
157 self.span
.hash_stable(hcx
, hasher
);
163 ///////////////////////////////////////////////////////////////////////////
164 // Lift and TypeFoldable macros
166 // When possible, use one of these (relatively) convenient macros to write
167 // the impls for you.
170 macro_rules
! CloneLiftImpls
{
171 (for <$tcx
:lifetime
> { $($ty:ty,)+ }
) => {
173 impl<$tcx
> $
crate::ty
::Lift
<$tcx
> for $ty
{
175 fn lift_to_tcx
<'a
, 'gcx
>(&self, _
: $
crate::ty
::TyCtxt
<'a
, 'gcx
, $tcx
>) -> Option
<Self> {
176 Some(Clone
::clone(self))
191 /// Used for types that are `Copy` and which **do not care arena
192 /// allocated data** (i.e., don't need to be folded).
194 macro_rules
! CloneTypeFoldableImpls
{
195 (for <$tcx
:lifetime
> { $($ty:ty,)+ }
) => {
197 impl<$tcx
> $
crate::ty
::fold
::TypeFoldable
<$tcx
> for $ty
{
198 fn super_fold_with
<'gcx
: $tcx
, F
: $
crate::ty
::fold
::TypeFolder
<'gcx
, $tcx
>>(
205 fn super_visit_with
<F
: $
crate::ty
::fold
::TypeVisitor
<$tcx
>>(
217 CloneTypeFoldableImpls
! {
226 macro_rules
! CloneTypeFoldableAndLiftImpls
{
228 CloneTypeFoldableImpls
! { $($t)* }
229 CloneLiftImpls
! { $($t)* }
234 macro_rules
! BraceStructLiftImpl
{
235 (impl<$
($p
:tt
),*> Lift
<$tcx
:tt
> for $s
:path
{
236 type Lifted
= $lifted
:ty
;
237 $
($field
:ident
),* $
(,)*
238 } $
(where $
($wc
:tt
)*)*) => {
239 impl<$
($p
),*> $
crate::ty
::Lift
<$tcx
> for $s
242 type Lifted
= $lifted
;
244 fn lift_to_tcx
<'b
, 'gcx
>(&self, tcx
: TyCtxt
<'b
, 'gcx
, 'tcx
>) -> Option
<$lifted
> {
245 $
(let $field
= tcx
.lift(&self.$field
)?
;)*
246 Some(Self::Lifted { $($field),* }
)
253 macro_rules
! EnumLiftImpl
{
254 (impl<$
($p
:tt
),*> Lift
<$tcx
:tt
> for $s
:path
{
255 type Lifted
= $lifted
:ty
;
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 EnumLiftImpl
!(@
Variants(self, tcx
) input($
($variants
)*) output())
269 (@
Variants($this
:expr
, $tcx
:expr
) input() output($
($output
:tt
)*)) => {
275 (@
Variants($this
:expr
, $tcx
:expr
)
276 input( ($variant
:path
) ( $
($variant_arg
:ident
),* ) , $
($input
:tt
)*)
277 output( $
($output
:tt
)*) ) => {
279 @
Variants($this
, $tcx
)
282 $
variant ( $
($variant_arg
),* ) => {
283 Some($
variant ( $
($tcx
.lift($variant_arg
)?
),* ))
290 (@
Variants($this
:expr
, $tcx
:expr
)
291 input( ($variant
:path
), $
($input
:tt
)*)
292 output( $
($output
:tt
)*) ) => {
294 @
Variants($this
, $tcx
)
297 $variant
=> { Some($variant) }
305 macro_rules
! BraceStructTypeFoldableImpl
{
306 (impl<$
($p
:tt
),*> TypeFoldable
<$tcx
:tt
> for $s
:path
{
307 $
($field
:ident
),* $
(,)*
308 } $
(where $
($wc
:tt
)*)*) => {
309 impl<$
($p
),*> $
crate::ty
::fold
::TypeFoldable
<$tcx
> for $s
312 fn super_fold_with
<'gcx
: $tcx
, V
: $
crate::ty
::fold
::TypeFolder
<'gcx
, $tcx
>>(
316 let $s { $($field,)* }
= self;
317 $s { $($field: $crate::ty::fold::TypeFoldable::fold_with($field, folder),)* }
320 fn super_visit_with
<V
: $
crate::ty
::fold
::TypeVisitor
<$tcx
>>(
324 let $s { $($field,)* }
= self;
325 false $
(|| $
crate::ty
::fold
::TypeFoldable
::visit_with($field
, visitor
))*
332 macro_rules
! TupleStructTypeFoldableImpl
{
333 (impl<$
($p
:tt
),*> TypeFoldable
<$tcx
:tt
> for $s
:path
{
334 $
($field
:ident
),* $
(,)*
335 } $
(where $
($wc
:tt
)*)*) => {
336 impl<$
($p
),*> $
crate::ty
::fold
::TypeFoldable
<$tcx
> for $s
339 fn super_fold_with
<'gcx
: $tcx
, V
: $
crate::ty
::fold
::TypeFolder
<'gcx
, $tcx
>>(
343 let $
s($
($field
,)*)= self;
344 $
s($
($
crate::ty
::fold
::TypeFoldable
::fold_with($field
, folder
),)*)
347 fn super_visit_with
<V
: $
crate::ty
::fold
::TypeVisitor
<$tcx
>>(
351 let $
s($
($field
,)*) = self;
352 false $
(|| $
crate::ty
::fold
::TypeFoldable
::visit_with($field
, visitor
))*
359 macro_rules
! EnumTypeFoldableImpl
{
360 (impl<$
($p
:tt
),*> TypeFoldable
<$tcx
:tt
> for $s
:path
{
362 } $
(where $
($wc
:tt
)*)*) => {
363 impl<$
($p
),*> $
crate::ty
::fold
::TypeFoldable
<$tcx
> for $s
366 fn super_fold_with
<'gcx
: $tcx
, V
: $
crate::ty
::fold
::TypeFolder
<'gcx
, $tcx
>>(
370 EnumTypeFoldableImpl
!(@
FoldVariants(self, folder
) input($
($variants
)*) output())
373 fn super_visit_with
<V
: $
crate::ty
::fold
::TypeVisitor
<$tcx
>>(
377 EnumTypeFoldableImpl
!(@
VisitVariants(self, visitor
) input($
($variants
)*) output())
382 (@
FoldVariants($this
:expr
, $folder
:expr
) input() output($
($output
:tt
)*)) => {
388 (@
FoldVariants($this
:expr
, $folder
:expr
)
389 input( ($variant
:path
) ( $
($variant_arg
:ident
),* ) , $
($input
:tt
)*)
390 output( $
($output
:tt
)*) ) => {
391 EnumTypeFoldableImpl
!(
392 @
FoldVariants($this
, $folder
)
395 $
variant ( $
($variant_arg
),* ) => {
397 $
($
crate::ty
::fold
::TypeFoldable
::fold_with($variant_arg
, $folder
)),*
405 (@
FoldVariants($this
:expr
, $folder
:expr
)
406 input( ($variant
:path
) { $($variant_arg:ident),* $(,)* }
, $
($input
:tt
)*)
407 output( $
($output
:tt
)*) ) => {
408 EnumTypeFoldableImpl
!(
409 @
FoldVariants($this
, $folder
)
412 $variant { $($variant_arg),* }
=> {
414 $
($variant_arg
: $
crate::ty
::fold
::TypeFoldable
::fold_with(
415 $variant_arg
, $folder
423 (@
FoldVariants($this
:expr
, $folder
:expr
)
424 input( ($variant
:path
), $
($input
:tt
)*)
425 output( $
($output
:tt
)*) ) => {
426 EnumTypeFoldableImpl
!(
427 @
FoldVariants($this
, $folder
)
430 $variant
=> { $variant }
436 (@
VisitVariants($this
:expr
, $visitor
:expr
) input() output($
($output
:tt
)*)) => {
442 (@
VisitVariants($this
:expr
, $visitor
:expr
)
443 input( ($variant
:path
) ( $
($variant_arg
:ident
),* ) , $
($input
:tt
)*)
444 output( $
($output
:tt
)*) ) => {
445 EnumTypeFoldableImpl
!(
446 @
VisitVariants($this
, $visitor
)
449 $
variant ( $
($variant_arg
),* ) => {
450 false $
(|| $
crate::ty
::fold
::TypeFoldable
::visit_with(
451 $variant_arg
, $visitor
459 (@
VisitVariants($this
:expr
, $visitor
:expr
)
460 input( ($variant
:path
) { $($variant_arg:ident),* $(,)* }
, $
($input
:tt
)*)
461 output( $
($output
:tt
)*) ) => {
462 EnumTypeFoldableImpl
!(
463 @
VisitVariants($this
, $visitor
)
466 $variant { $($variant_arg),* }
=> {
467 false $
(|| $
crate::ty
::fold
::TypeFoldable
::visit_with(
468 $variant_arg
, $visitor
476 (@
VisitVariants($this
:expr
, $visitor
:expr
)
477 input( ($variant
:path
), $
($input
:tt
)*)
478 output( $
($output
:tt
)*) ) => {
479 EnumTypeFoldableImpl
!(
480 @
VisitVariants($this
, $visitor
)
483 $variant
=> { false }