improve TypeFoldable/Lift macros and make a bunch of stuff use them

Improvements:

- Use Clone not Copy for the "simple cases"
- Separate TypeFoldable and Lift for the "simple cases"
- Support generics type parameters
- Support named fields in enum variants
- etc
This commit is contained in:
Niko Matsakis 2018-02-09 10:34:23 -05:00
parent f873c1e2db
commit 23837c1901
10 changed files with 553 additions and 815 deletions

View file

@ -1647,19 +1647,6 @@ impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for TypeTrace<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
TypeTrace {
cause: self.cause.fold_with(folder),
values: self.values.fold_with(folder)
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.cause.visit_with(visitor) || self.values.visit_with(visitor)
}
}
impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "RegionObligation(sub_region={:?}, sup_type={:?})",

View file

@ -57,6 +57,7 @@
#![feature(inclusive_range)]
#![feature(inclusive_range_syntax)]
#![cfg_attr(windows, feature(libc))]
#![feature(macro_lifetime_matcher)]
#![feature(macro_vis_matcher)]
#![feature(match_default_bindings)]
#![feature(never_type)]

View file

@ -138,3 +138,303 @@ macro_rules! impl_stable_hash_for_spanned {
);
}
///////////////////////////////////////////////////////////////////////////
// Lift and TypeFoldable macros
//
// When possible, use one of these (relatively) convenient macros to write
// the impls for you.
#[macro_export]
macro_rules! CloneLiftImpls {
(for <$tcx:lifetime> { $($ty:ty,)+ }) => {
$(
impl<$tcx> $crate::ty::Lift<$tcx> for $ty {
type Lifted = Self;
fn lift_to_tcx<'a, 'gcx>(&self, _: $crate::ty::TyCtxt<'a, 'gcx, $tcx>) -> Option<Self> {
Some(Clone::clone(self))
}
}
)+
};
($($ty:ty,)+) => {
CloneLiftImpls! {
for <'tcx> {
$($ty,)+
}
}
};
}
/// Used for types that are `Copy` and which **do not care arena
/// allocated data** (i.e., don't need to be folded).
#[macro_export]
macro_rules! CloneTypeFoldableImpls {
(for <$tcx:lifetime> { $($ty:ty,)+ }) => {
$(
impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty {
fn super_fold_with<'gcx: $tcx, F: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
&self,
_: &mut F
) -> $ty {
Clone::clone(self)
}
fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
_: &mut F)
-> bool
{
false
}
}
)+
};
($($ty:ty,)+) => {
CloneTypeFoldableImpls! {
for <'tcx> {
$($ty,)+
}
}
};
}
#[macro_export]
macro_rules! CloneTypeFoldableAndLiftImpls {
($($t:tt)*) => {
CloneTypeFoldableImpls! { $($t)* }
CloneLiftImpls! { $($t)* }
}
}
#[macro_export]
macro_rules! BraceStructLiftImpl {
(impl<$($p:tt),*> Lift<$tcx:tt> for $s:path {
type Lifted = $lifted:ty;
$($field:ident),* $(,)*
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::Lift<$tcx> for $s
$(where $($wc)*)*
{
type Lifted = $lifted;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> {
$(let $field = tcx.lift(&self.$field)?;)*
Some(Self::Lifted { $($field),* })
}
}
};
}
#[macro_export]
macro_rules! EnumLiftImpl {
(impl<$($p:tt),*> Lift<$tcx:tt> for $s:path {
type Lifted = $lifted:ty;
$(
($variant:path) ( $( $variant_arg:ident),* )
),*
$(,)*
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::Lift<$tcx> for $s
$(where $($wc)*)*
{
type Lifted = $lifted;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> {
match self {
$($variant ( $($variant_arg),* ) => {
Some($variant ( $(tcx.lift($variant_arg)?),* ))
})*
}
}
}
};
}
#[macro_export]
macro_rules! BraceStructTypeFoldableImpl {
(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
$($field:ident),* $(,)*
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
$(where $($wc)*)*
{
fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
&self,
folder: &mut V,
) -> Self {
let $s { $($field,)* } = self;
$s { $($field: $crate::ty::fold::TypeFoldable::fold_with($field, folder),)* }
}
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
visitor: &mut V,
) -> bool {
let $s { $($field,)* } = self;
false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))*
}
}
};
}
#[macro_export]
macro_rules! TupleStructTypeFoldableImpl {
(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
$($field:ident),* $(,)*
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
$(where $($wc)*)*
{
fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
&self,
folder: &mut V,
) -> Self {
let $s($($field,)*)= self;
$s($($crate::ty::fold::TypeFoldable::fold_with($field, folder),)*)
}
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
visitor: &mut V,
) -> bool {
let $s($($field,)*) = self;
false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))*
}
}
};
}
#[macro_export]
macro_rules! EnumTypeFoldableImpl {
(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
$($variants:tt)*
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
$(where $($wc)*)*
{
fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
&self,
folder: &mut V,
) -> Self {
EnumTypeFoldableImpl!(@FoldVariants(self, folder) input($($variants)*) output())
}
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
visitor: &mut V,
) -> bool {
EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
}
}
};
(@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => {
match $this {
$($output)*
}
};
(@FoldVariants($this:expr, $folder:expr)
input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
output( $($output:tt)*) ) => {
EnumTypeFoldableImpl!(
@FoldVariants($this, $folder)
input($($input)*)
output(
$variant ( $($variant_arg),* ) => {
$variant (
$($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)),*
)
}
$($output)*
)
)
};
(@FoldVariants($this:expr, $folder:expr)
input( ($variant:path) { $($variant_arg:ident),* $(,)* } , $($input:tt)*)
output( $($output:tt)*) ) => {
EnumTypeFoldableImpl!(
@FoldVariants($this, $folder)
input($($input)*)
output(
$variant { $($variant_arg),* } => {
$variant {
$($variant_arg: $crate::ty::fold::TypeFoldable::fold_with(
$variant_arg, $folder
)),* }
}
$($output)*
)
)
};
(@FoldVariants($this:expr, $folder:expr)
input( ($variant:path), $($input:tt)*)
output( $($output:tt)*) ) => {
EnumTypeFoldableImpl!(
@FoldVariants($this, $folder)
input($($input)*)
output(
$variant => { $variant }
$($output)*
)
)
};
(@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => {
match $this {
$($output)*
}
};
(@VisitVariants($this:expr, $visitor:expr)
input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
output( $($output:tt)*) ) => {
EnumTypeFoldableImpl!(
@VisitVariants($this, $visitor)
input($($input)*)
output(
$variant ( $($variant_arg),* ) => {
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
$variant_arg, $visitor
))*
}
$($output)*
)
)
};
(@VisitVariants($this:expr, $visitor:expr)
input( ($variant:path) { $($variant_arg:ident),* $(,)* } , $($input:tt)*)
output( $($output:tt)*) ) => {
EnumTypeFoldableImpl!(
@VisitVariants($this, $visitor)
input($($input)*)
output(
$variant { $($variant_arg),* } => {
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
$variant_arg, $visitor
))*
}
$($output)*
)
)
};
(@VisitVariants($this:expr, $visitor:expr)
input( ($variant:path), $($input:tt)*)
output( $($output:tt)*) ) => {
EnumTypeFoldableImpl!(
@VisitVariants($this, $visitor)
input($($input)*)
output(
$variant => { false }
$($output)*
)
)
};
}

View file

@ -76,3 +76,7 @@ fn calculate_predecessors(mir: &Mir) -> IndexVec<BasicBlock, Vec<BasicBlock>> {
result
}
CloneTypeFoldableAndLiftImpls! {
Cache,
}

View file

@ -2109,150 +2109,92 @@ pub enum ClosureOutlivesSubject<'tcx> {
* TypeFoldable implementations for MIR types
*/
impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
Mir {
basic_blocks: self.basic_blocks.fold_with(folder),
visibility_scopes: self.visibility_scopes.clone(),
visibility_scope_info: self.visibility_scope_info.clone(),
promoted: self.promoted.fold_with(folder),
yield_ty: self.yield_ty.fold_with(folder),
generator_drop: self.generator_drop.fold_with(folder),
generator_layout: self.generator_layout.fold_with(folder),
local_decls: self.local_decls.fold_with(folder),
arg_count: self.arg_count,
upvar_decls: self.upvar_decls.clone(),
spread_arg: self.spread_arg,
span: self.span,
cache: cache::Cache::new()
}
}
CloneTypeFoldableAndLiftImpls! {
Mutability,
SourceInfo,
UpvarDecl,
ValidationOp,
VisibilityScopeData,
VisibilityScope,
VisibilityScopeInfo,
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.basic_blocks.visit_with(visitor) ||
self.generator_drop.visit_with(visitor) ||
self.generator_layout.visit_with(visitor) ||
self.yield_ty.visit_with(visitor) ||
self.promoted.visit_with(visitor) ||
self.local_decls.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> {
basic_blocks,
visibility_scopes,
visibility_scope_info,
promoted,
yield_ty,
generator_drop,
generator_layout,
local_decls,
arg_count,
upvar_decls,
spread_arg,
span,
cache,
}
}
impl<'tcx> TypeFoldable<'tcx> for GeneratorLayout<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
GeneratorLayout {
fields: self.fields.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.fields.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for GeneratorLayout<'tcx> {
fields
}
}
impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
LocalDecl {
ty: self.ty.fold_with(folder),
..self.clone()
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.ty.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> {
mutability,
is_user_variable,
internal,
ty,
name,
source_info,
syntactic_scope,
}
}
impl<'tcx> TypeFoldable<'tcx> for BasicBlockData<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
BasicBlockData {
statements: self.statements.fold_with(folder),
terminator: self.terminator.fold_with(folder),
is_cleanup: self.is_cleanup
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.statements.visit_with(visitor) || self.terminator.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for BasicBlockData<'tcx> {
statements,
terminator,
is_cleanup,
}
}
impl<'tcx> TypeFoldable<'tcx> for ValidationOperand<'tcx, Place<'tcx>> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ValidationOperand {
place: self.place.fold_with(folder),
ty: self.ty.fold_with(folder),
re: self.re,
mutbl: self.mutbl,
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.place.visit_with(visitor) || self.ty.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ValidationOperand<'tcx, Place<'tcx>> {
place, ty, re, mutbl
}
}
impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
use mir::StatementKind::*;
let kind = match self.kind {
Assign(ref place, ref rval) => Assign(place.fold_with(folder), rval.fold_with(folder)),
SetDiscriminant { ref place, variant_index } => SetDiscriminant {
place: place.fold_with(folder),
variant_index,
},
StorageLive(ref local) => StorageLive(local.fold_with(folder)),
StorageDead(ref local) => StorageDead(local.fold_with(folder)),
InlineAsm { ref asm, ref outputs, ref inputs } => InlineAsm {
asm: asm.clone(),
outputs: outputs.fold_with(folder),
inputs: inputs.fold_with(folder)
},
// Note for future: If we want to expose the region scopes
// during the fold, we need to either generalize EndRegion
// to carry `[ty::Region]`, or extend the `TypeFolder`
// trait with a `fn fold_scope`.
EndRegion(ref region_scope) => EndRegion(region_scope.clone()),
Validate(ref op, ref places) =>
Validate(op.clone(),
places.iter().map(|operand| operand.fold_with(folder)).collect()),
Nop => Nop,
};
Statement {
source_info: self.source_info,
kind,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
source_info, kind
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
use mir::StatementKind::*;
match self.kind {
Assign(ref place, ref rval) => { place.visit_with(visitor) || rval.visit_with(visitor) }
SetDiscriminant { ref place, .. } => place.visit_with(visitor),
StorageLive(ref local) |
StorageDead(ref local) => local.visit_with(visitor),
InlineAsm { ref outputs, ref inputs, .. } =>
outputs.visit_with(visitor) || inputs.visit_with(visitor),
// Note for future: If we want to expose the region scopes
// during the visit, we need to either generalize EndRegion
// to carry `[ty::Region]`, or extend the `TypeVisitor`
// trait with a `fn visit_scope`.
EndRegion(ref _scope) => false,
Validate(ref _op, ref places) =>
places.iter().any(|ty_and_place| ty_and_place.visit_with(visitor)),
Nop => false,
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> {
(StatementKind::Assign)(a, b),
(StatementKind::SetDiscriminant) { place, variant_index },
(StatementKind::StorageLive)(a),
(StatementKind::StorageDead)(a),
(StatementKind::InlineAsm) { asm, outputs, inputs },
(StatementKind::Validate)(a, b),
(StatementKind::EndRegion)(a),
(StatementKind::Nop),
}
}
EnumTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for ClearCrossCrate<T> {
(ClearCrossCrate::Clear),
(ClearCrossCrate::Set)(a),
} where T: TypeFoldable<'tcx>
}
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
use mir::TerminatorKind::*;

View file

@ -16,7 +16,6 @@
use mir::*;
use ty::subst::{Subst, Substs};
use ty::{self, AdtDef, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use hir;
use ty::util::IntTypeExt;
@ -100,25 +99,10 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for PlaceTy<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
match *self {
PlaceTy::Ty { ty } => PlaceTy::Ty { ty: ty.fold_with(folder) },
PlaceTy::Downcast { adt_def, substs, variant_index } => {
PlaceTy::Downcast {
adt_def,
substs: substs.fold_with(folder),
variant_index,
}
}
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
PlaceTy::Ty { ty } => ty.visit_with(visitor),
PlaceTy::Downcast { substs, .. } => substs.visit_with(visitor)
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for PlaceTy<'tcx> {
(PlaceTy::Ty) { ty },
(PlaceTy::Downcast) { adt_def, substs, variant_index },
}
}

View file

@ -363,258 +363,67 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx
}
}
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
traits::VtableImplData {
impl_def_id: self.impl_def_id,
substs: self.substs.fold_with(folder),
nested: self.nested.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
impl_def_id, substs, nested
} where N: TypeFoldable<'tcx>
}
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
traits::VtableGeneratorData {
closure_def_id: self.closure_def_id,
substs: self.substs.fold_with(folder),
nested: self.nested.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
closure_def_id, substs, nested
} where N: TypeFoldable<'tcx>
}
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
traits::VtableClosureData {
closure_def_id: self.closure_def_id,
substs: self.substs.fold_with(folder),
nested: self.nested.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
closure_def_id, substs, nested
} where N: TypeFoldable<'tcx>
}
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
traits::VtableAutoImplData {
trait_def_id: self.trait_def_id,
nested: self.nested.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.nested.visit_with(visitor)
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
trait_def_id, nested
} where N: TypeFoldable<'tcx>
}
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
traits::VtableBuiltinData {
nested: self.nested.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.nested.visit_with(visitor)
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
nested
} where N: TypeFoldable<'tcx>
}
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
traits::VtableObjectData {
upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
vtable_base: self.vtable_base,
nested: self.nested.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor)
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
upcast_trait_ref, vtable_base, nested
} where N: TypeFoldable<'tcx>
}
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
traits::VtableFnPointerData {
fn_ty: self.fn_ty.fold_with(folder),
nested: self.nested.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor)
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
fn_ty,
nested
} where N: TypeFoldable<'tcx>
}
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
match *self {
traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
traits::VtableAutoImpl(ref t) => traits::VtableAutoImpl(t.fold_with(folder)),
traits::VtableGenerator(ref d) => {
traits::VtableGenerator(d.fold_with(folder))
}
traits::VtableClosure(ref d) => {
traits::VtableClosure(d.fold_with(folder))
}
traits::VtableFnPointer(ref d) => {
traits::VtableFnPointer(d.fold_with(folder))
}
traits::VtableParam(ref n) => traits::VtableParam(n.fold_with(folder)),
traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)),
traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
traits::VtableImpl(ref v) => v.visit_with(visitor),
traits::VtableAutoImpl(ref t) => t.visit_with(visitor),
traits::VtableGenerator(ref d) => d.visit_with(visitor),
traits::VtableClosure(ref d) => d.visit_with(visitor),
traits::VtableFnPointer(ref d) => d.visit_with(visitor),
traits::VtableParam(ref n) => n.visit_with(visitor),
traits::VtableBuiltin(ref d) => d.visit_with(visitor),
traits::VtableObject(ref d) => d.visit_with(visitor),
}
}
EnumTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
(traits::VtableImpl)(a),
(traits::VtableAutoImpl)(a),
(traits::VtableGenerator)(a),
(traits::VtableClosure)(a),
(traits::VtableFnPointer)(a),
(traits::VtableParam)(a),
(traits::VtableBuiltin)(a),
(traits::VtableObject)(a),
} where N: TypeFoldable<'tcx>
}
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
Normalized {
value: self.value.fold_with(folder),
obligations: self.obligations.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.value.visit_with(visitor) || self.obligations.visit_with(visitor)
}
BraceStructTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for Normalized<'tcx, T> {
value,
obligations
} where T: TypeFoldable<'tcx>
}
impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
match *self {
super::ExprAssignable |
super::MatchExpressionArm { arm_span: _, source: _ } |
super::IfExpression |
super::IfExpressionWithNoElse |
super::MainFunctionType |
super::StartFunctionType |
super::IntrinsicType |
super::MethodReceiver |
super::MiscObligation |
super::SliceOrArrayElem |
super::TupleElem |
super::ItemObligation(_) |
super::AssignmentLhsSized |
super::TupleInitializerSized |
super::StructInitializerSized |
super::VariableType(_) |
super::ReturnType(_) |
super::SizedReturnType |
super::SizedYieldType |
super::ReturnNoExpression |
super::RepeatVec |
super::FieldSized(_) |
super::ConstSized |
super::SharedStatic |
super::BlockTailExpression(_) |
super::CompareImplMethodObligation { .. } => self.clone(),
super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)),
super::ReferenceOutlivesReferent(ty) => {
super::ReferenceOutlivesReferent(ty.fold_with(folder))
}
super::ObjectTypeBound(ty, r) => {
super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder))
}
super::ObjectCastObligation(ty) => {
super::ObjectCastObligation(ty.fold_with(folder))
}
super::BuiltinDerivedObligation(ref cause) => {
super::BuiltinDerivedObligation(cause.fold_with(folder))
}
super::ImplDerivedObligation(ref cause) => {
super::ImplDerivedObligation(cause.fold_with(folder))
}
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
super::ExprAssignable |
super::MatchExpressionArm { arm_span: _, source: _ } |
super::IfExpression |
super::IfExpressionWithNoElse |
super::MainFunctionType |
super::StartFunctionType |
super::IntrinsicType |
super::MethodReceiver |
super::MiscObligation |
super::SliceOrArrayElem |
super::TupleElem |
super::ItemObligation(_) |
super::AssignmentLhsSized |
super::TupleInitializerSized |
super::StructInitializerSized |
super::VariableType(_) |
super::ReturnType(_) |
super::SizedReturnType |
super::SizedYieldType |
super::ReturnNoExpression |
super::RepeatVec |
super::FieldSized(_) |
super::ConstSized |
super::SharedStatic |
super::BlockTailExpression(_) |
super::CompareImplMethodObligation { .. } => false,
super::ProjectionWf(proj) => proj.visit_with(visitor),
super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor),
super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor),
super::ObjectCastObligation(ty) => ty.visit_with(visitor),
super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor),
super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor)
}
}
}
impl<'tcx> TypeFoldable<'tcx> for traits::DerivedObligationCause<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
traits::DerivedObligationCause {
parent_trait_ref: self.parent_trait_ref.fold_with(folder),
parent_code: self.parent_code.fold_with(folder)
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.parent_trait_ref.visit_with(visitor) || self.parent_code.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
traits::ObligationCause {
span: self.span,
body_id: self.body_id,
code: self.code.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.code.visit_with(visitor)
}
}

View file

@ -49,6 +49,9 @@ use util::nodemap::FxHashSet;
/// The TypeFoldable trait is implemented for every type that can be folded.
/// Basically, every type that has a corresponding method in TypeFolder.
///
/// To implement this conveniently, use the
/// `BraceStructTypeFoldableImpl` etc macros found in `macros.rs`.
pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self;
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {

View file

@ -18,7 +18,6 @@ use middle::const_val::ConstVal;
use traits::Reveal;
use ty::subst::{UnpackedKind, Substs};
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::fold::{TypeVisitor, TypeFolder};
use ty::error::{ExpectedFound, TypeError};
use mir::interpret::{GlobalId, Value, PrimVal};
use util::common::ErrorReported;
@ -326,13 +325,9 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
#[derive(Debug, Clone)]
struct GeneratorWitness<'tcx>(&'tcx ty::Slice<Ty<'tcx>>);
impl<'tcx> TypeFoldable<'tcx> for GeneratorWitness<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
GeneratorWitness(self.0.fold_with(folder))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.0.visit_with(visitor)
TupleStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for GeneratorWitness<'tcx> {
a
}
}

View file

@ -28,153 +28,37 @@ use std::rc::Rc;
// For things that don't carry any arena-allocated data (and are
// copy...), just add them to this list.
macro_rules! CopyImpls {
($($ty:ty,)+) => {
$(
impl<'tcx> Lift<'tcx> for $ty {
type Lifted = Self;
fn lift_to_tcx<'a, 'gcx>(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self> {
Some(*self)
}
}
impl<'tcx> TypeFoldable<'tcx> for $ty {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> $ty {
*self
}
fn super_visit_with<F: TypeVisitor<'tcx>>(&self, _: &mut F) -> bool {
false
}
}
)+
}
}
CopyImpls! {
CloneTypeFoldableAndLiftImpls! {
(),
bool,
usize,
u64,
::middle::region::Scope,
::syntax::ast::FloatTy,
::syntax::ast::NodeId,
::syntax_pos::symbol::Symbol,
::hir::def::Def,
::hir::def_id::DefId,
::hir::InlineAsm,
::hir::MatchSource,
::hir::Mutability,
::hir::Unsafety,
::syntax::abi::Abi,
::hir::def_id::DefId,
::mir::Local,
::mir::Promoted,
::traits::Reveal,
::ty::adjustment::AutoBorrowMutability,
::ty::AdtKind,
// Including `BoundRegion` is a *bit* dubious, but direct
// references to bound region appear in `ty::Error`, and aren't
// really meant to be folded. In general, we can only fold a fully
// general `Region`.
::ty::BoundRegion,
::ty::ClosureKind,
::ty::IntVarValue,
::syntax_pos::Span,
}
///////////////////////////////////////////////////////////////////////////
// Macros
//
// When possible, use one of these (relatively) convenient macros to write
// the impls for you.
#[macro_export]
macro_rules! BraceStructLiftImpl {
(impl<$($p:tt),*> Lift<$tcx:tt> for $s:path {
type Lifted = $lifted:ty;
$($field:ident),* $(,)*
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::Lift<$tcx> for $s
$(where $($wc)*)*
{
type Lifted = $lifted;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> {
$(let $field = tcx.lift(&self.$field)?;)*
Some(Self::Lifted { $($field),* })
}
}
};
}
#[macro_export]
macro_rules! EnumLiftImpl {
(impl<$($p:tt),*> Lift<$tcx:tt> for $s:path {
type Lifted = $lifted:ty;
$(
($variant:path) ( $( $variant_arg:ident),* )
),*
$(,)*
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::Lift<$tcx> for $s
$(where $($wc)*)*
{
type Lifted = $lifted;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> {
match self {
$($variant ( $($variant_arg),* ) => {
Some($variant ( $(tcx.lift($variant_arg)?),* ))
})*
}
}
}
};
}
#[macro_export]
macro_rules! BraceStructTypeFoldableImpl {
(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
$($field:ident),* $(,)*
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
$(where $($wc)*)*
{
fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
&self,
folder: &mut V,
) -> Self {
let $s { $($field,)* } = self;
$s { $($field: $field.fold_with(folder),)* }
}
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
visitor: &mut V,
) -> bool {
let $s { $($field,)* } = self;
false $(|| $field.visit_with(visitor))*
}
}
};
}
#[macro_export]
macro_rules! EnumTypeFoldableImpl {
(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
$(
($variant:path) ( $( $variant_arg:ident),* )
),*
$(,)*
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
$(where $($wc)*)*
{
fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
&self,
folder: &mut V,
) -> Self {
match self {
$($variant ( $($variant_arg),* ) => {
$variant ( $($variant_arg.fold_with(folder)),* )
})*
}
}
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
visitor: &mut V,
) -> bool {
match self {
$($variant ( $($variant_arg),* ) => {
false $(|| $variant_arg.visit_with(visitor))*
})*
}
}
}
};
}
///////////////////////////////////////////////////////////////////////////
// Lift implementations
@ -776,6 +660,17 @@ BraceStructLiftImpl! {
// can easily refactor the folding into the TypeFolder trait as
// needed.
/// AdtDefs are basically the same as a DefId.
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
*self
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
false
}
}
impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
(self.0.fold_with(folder), self.1.fold_with(folder))
@ -786,14 +681,11 @@ impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T
}
}
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Option<T> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
self.as_ref().map(|t| t.fold_with(folder))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.iter().any(|t| t.visit_with(visitor))
}
EnumTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
(Some)(a),
(None),
} where T: TypeFoldable<'tcx>
}
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
@ -881,22 +773,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<ty::ExistentialPredicate<'tcx>
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
use ty::ExistentialPredicate::*;
match *self {
Trait(ref tr) => Trait(tr.fold_with(folder)),
Projection(ref p) => Projection(p.fold_with(folder)),
AutoTrait(did) => AutoTrait(did),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
ty::ExistentialPredicate::Trait(ref tr) => tr.visit_with(visitor),
ty::ExistentialPredicate::Projection(ref p) => p.visit_with(visitor),
ty::ExistentialPredicate::AutoTrait(_) => false,
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
(ty::ExistentialPredicate::Trait)(a),
(ty::ExistentialPredicate::Projection)(a),
(ty::ExistentialPredicate::AutoTrait)(a),
}
}
@ -1049,13 +930,9 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl }
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.ty.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
ty, mutbl
}
}
@ -1065,20 +942,9 @@ BraceStructTypeFoldableImpl! {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
let inputs_and_output = self.inputs_and_output.fold_with(folder);
ty::FnSig {
inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output),
variadic: self.variadic,
unsafety: self.unsafety,
abi: self.abi,
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.inputs().iter().any(|i| i.visit_with(visitor)) ||
self.output().visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
inputs_and_output, variadic, unsafety, abi
}
}
@ -1117,28 +983,15 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::ClosureSubsts {
substs: self.substs.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.substs.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
substs,
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::GeneratorInterior {
witness: self.witness.fold_with(folder),
movable: self.movable,
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.witness.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> {
witness, movable,
}
}
@ -1149,74 +1002,32 @@ BraceStructTypeFoldableImpl! {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
match *self {
ty::adjustment::Adjust::NeverToAny |
ty::adjustment::Adjust::ReifyFnPointer |
ty::adjustment::Adjust::UnsafeFnPointer |
ty::adjustment::Adjust::ClosureFnPointer |
ty::adjustment::Adjust::MutToConstPointer |
ty::adjustment::Adjust::Unsize => self.clone(),
ty::adjustment::Adjust::Deref(ref overloaded) => {
ty::adjustment::Adjust::Deref(overloaded.fold_with(folder))
}
ty::adjustment::Adjust::Borrow(ref autoref) => {
ty::adjustment::Adjust::Borrow(autoref.fold_with(folder))
}
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
ty::adjustment::Adjust::NeverToAny |
ty::adjustment::Adjust::ReifyFnPointer |
ty::adjustment::Adjust::UnsafeFnPointer |
ty::adjustment::Adjust::ClosureFnPointer |
ty::adjustment::Adjust::MutToConstPointer |
ty::adjustment::Adjust::Unsize => false,
ty::adjustment::Adjust::Deref(ref overloaded) => {
overloaded.visit_with(visitor)
}
ty::adjustment::Adjust::Borrow(ref autoref) => {
autoref.visit_with(visitor)
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> {
(ty::adjustment::Adjust::NeverToAny),
(ty::adjustment::Adjust::ReifyFnPointer),
(ty::adjustment::Adjust::UnsafeFnPointer),
(ty::adjustment::Adjust::ClosureFnPointer),
(ty::adjustment::Adjust::MutToConstPointer),
(ty::adjustment::Adjust::Unsize),
(ty::adjustment::Adjust::Deref)(a),
(ty::adjustment::Adjust::Borrow)(a),
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::adjustment::OverloadedDeref {
region: self.region.fold_with(folder),
mutbl: self.mutbl,
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.region.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> {
region, mutbl,
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
match *self {
ty::adjustment::AutoBorrow::Ref(ref r, m) => {
ty::adjustment::AutoBorrow::Ref(r.fold_with(folder), m)
}
ty::adjustment::AutoBorrow::RawPtr(m) => ty::adjustment::AutoBorrow::RawPtr(m)
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
ty::adjustment::AutoBorrow::Ref(r, _m) => r.visit_with(visitor),
ty::adjustment::AutoBorrow::RawPtr(_m) => false,
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
(ty::adjustment::AutoBorrow::Ref)(a, b),
(ty::adjustment::AutoBorrow::RawPtr)(m),
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
parent, predicates
@ -1234,43 +1045,17 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<ty::Predicate<'tcx>> {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
match *self {
ty::Predicate::Trait(ref a) =>
ty::Predicate::Trait(a.fold_with(folder)),
ty::Predicate::Subtype(ref binder) =>
ty::Predicate::Subtype(binder.fold_with(folder)),
ty::Predicate::RegionOutlives(ref binder) =>
ty::Predicate::RegionOutlives(binder.fold_with(folder)),
ty::Predicate::TypeOutlives(ref binder) =>
ty::Predicate::TypeOutlives(binder.fold_with(folder)),
ty::Predicate::Projection(ref binder) =>
ty::Predicate::Projection(binder.fold_with(folder)),
ty::Predicate::WellFormed(data) =>
ty::Predicate::WellFormed(data.fold_with(folder)),
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) =>
ty::Predicate::ClosureKind(closure_def_id, closure_substs.fold_with(folder), kind),
ty::Predicate::ObjectSafe(trait_def_id) =>
ty::Predicate::ObjectSafe(trait_def_id),
ty::Predicate::ConstEvaluatable(def_id, substs) =>
ty::Predicate::ConstEvaluatable(def_id, substs.fold_with(folder)),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
ty::Predicate::Trait(ref a) => a.visit_with(visitor),
ty::Predicate::Subtype(ref binder) => binder.visit_with(visitor),
ty::Predicate::RegionOutlives(ref binder) => binder.visit_with(visitor),
ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor),
ty::Predicate::Projection(ref binder) => binder.visit_with(visitor),
ty::Predicate::WellFormed(data) => data.visit_with(visitor),
ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) =>
closure_substs.visit_with(visitor),
ty::Predicate::ObjectSafe(_trait_def_id) => false,
ty::Predicate::ConstEvaluatable(_def_id, substs) => substs.visit_with(visitor),
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
(ty::Predicate::Trait)(a),
(ty::Predicate::Subtype)(a),
(ty::Predicate::RegionOutlives)(a),
(ty::Predicate::TypeOutlives)(a),
(ty::Predicate::Projection)(a),
(ty::Predicate::WellFormed)(a),
(ty::Predicate::ClosureKind)(a, b, c),
(ty::Predicate::ObjectSafe)(a),
(ty::Predicate::ConstEvaluatable)(a, b),
}
}
@ -1298,71 +1083,40 @@ BraceStructTypeFoldableImpl! {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::SubtypePredicate {
a_is_expected: self.a_is_expected,
a: self.a.fold_with(folder),
b: self.b.fold_with(folder)
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for ty::ParamEnvAnd<'tcx, T> {
param_env, value
} where T: TypeFoldable<'tcx>
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.a.visit_with(visitor) || self.b.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
a_is_expected, a, b
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::TraitPredicate {
trait_ref: self.trait_ref.fold_with(folder)
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.trait_ref.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
trait_ref
}
}
impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U>
where T : TypeFoldable<'tcx>,
U : TypeFoldable<'tcx>,
{
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::OutlivesPredicate(self.0.fold_with(folder),
self.1.fold_with(folder))
}
TupleStructTypeFoldableImpl! {
impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U> {
a, b
} where T : TypeFoldable<'tcx>, U : TypeFoldable<'tcx>,
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.0.visit_with(visitor) || self.1.visit_with(visitor)
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
def, span, ty
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::ClosureUpvar {
def: self.def,
span: self.span,
ty: self.ty.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.ty.visit_with(visitor)
}
}
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::error::ExpectedFound {
expected: self.expected.fold_with(folder),
found: self.found.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.expected.visit_with(visitor) || self.found.visit_with(visitor)
}
BraceStructTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
expected, found
} where T: TypeFoldable<'tcx>
}
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
@ -1375,69 +1129,28 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T>
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
use ty::error::TypeError::*;
match *self {
Mismatch => Mismatch,
UnsafetyMismatch(x) => UnsafetyMismatch(x.fold_with(folder)),
AbiMismatch(x) => AbiMismatch(x.fold_with(folder)),
Mutability => Mutability,
TupleSize(x) => TupleSize(x),
FixedArraySize(x) => FixedArraySize(x),
ArgCount => ArgCount,
RegionsDoesNotOutlive(a, b) => {
RegionsDoesNotOutlive(a.fold_with(folder), b.fold_with(folder))
},
RegionsInsufficientlyPolymorphic(a, b) => {
RegionsInsufficientlyPolymorphic(a, b.fold_with(folder))
},
RegionsOverlyPolymorphic(a, b) => {
RegionsOverlyPolymorphic(a, b.fold_with(folder))
},
IntMismatch(x) => IntMismatch(x),
FloatMismatch(x) => FloatMismatch(x),
Traits(x) => Traits(x),
VariadicMismatch(x) => VariadicMismatch(x),
CyclicTy(t) => CyclicTy(t.fold_with(folder)),
ProjectionMismatched(x) => ProjectionMismatched(x),
ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
Sorts(x) => Sorts(x.fold_with(folder)),
ExistentialMismatch(x) => ExistentialMismatch(x.fold_with(folder)),
OldStyleLUB(ref x) => OldStyleLUB(x.fold_with(folder)),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
use ty::error::TypeError::*;
match *self {
UnsafetyMismatch(x) => x.visit_with(visitor),
AbiMismatch(x) => x.visit_with(visitor),
RegionsDoesNotOutlive(a, b) => {
a.visit_with(visitor) || b.visit_with(visitor)
},
RegionsInsufficientlyPolymorphic(_, b) |
RegionsOverlyPolymorphic(_, b) => {
b.visit_with(visitor)
},
Sorts(x) => x.visit_with(visitor),
OldStyleLUB(ref x) => x.visit_with(visitor),
ExistentialMismatch(x) => x.visit_with(visitor),
CyclicTy(t) => t.visit_with(visitor),
Mismatch |
Mutability |
TupleSize(_) |
FixedArraySize(_) |
ArgCount |
IntMismatch(_) |
FloatMismatch(_) |
Traits(_) |
VariadicMismatch(_) |
ProjectionMismatched(_) |
ProjectionBoundsLength(_) => false,
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
(ty::error::TypeError::Mismatch),
(ty::error::TypeError::UnsafetyMismatch)(x),
(ty::error::TypeError::AbiMismatch)(x),
(ty::error::TypeError::Mutability),
(ty::error::TypeError::TupleSize)(x),
(ty::error::TypeError::FixedArraySize)(x),
(ty::error::TypeError::ArgCount),
(ty::error::TypeError::RegionsDoesNotOutlive)(a, b),
(ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b),
(ty::error::TypeError::RegionsOverlyPolymorphic)(a, b),
(ty::error::TypeError::IntMismatch)(x),
(ty::error::TypeError::FloatMismatch)(x),
(ty::error::TypeError::Traits)(x),
(ty::error::TypeError::VariadicMismatch)(x),
(ty::error::TypeError::CyclicTy)(t),
(ty::error::TypeError::ProjectionMismatched)(x),
(ty::error::TypeError::ProjectionBoundsLength)(x),
(ty::error::TypeError::Sorts)(x),
(ty::error::TypeError::ExistentialMismatch)(x),
(ty::error::TypeError::OldStyleLUB)(x),
}
}