提交 23837c19 编写于 作者: N Niko Matsakis

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
上级 f873c1e2
......@@ -1647,19 +1647,6 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
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={:?})",
......
......@@ -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)]
......
......@@ -138,3 +138,303 @@ fn hash_stable<W: StableHasherResult>(&self,
);
}
///////////////////////////////////////////////////////////////////////////
// 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)*
)
)
};
}
......@@ -76,3 +76,7 @@ fn calculate_predecessors(mir: &Mir) -> IndexVec<BasicBlock, Vec<BasicBlock>> {
result
}
CloneTypeFoldableAndLiftImpls! {
Cache,
}
......@@ -2109,148 +2109,90 @@ 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()
}
}
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)
}
CloneTypeFoldableAndLiftImpls! {
Mutability,
SourceInfo,
UpvarDecl,
ValidationOp,
VisibilityScopeData,
VisibilityScope,
VisibilityScopeInfo,
}
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 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 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 GeneratorLayout<'tcx> {
fields
}
}
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
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> {
mutability,
is_user_variable,
internal,
ty,
name,
source_info,
syntactic_scope,
}
}
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,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ValidationOperand<'tcx, Place<'tcx>> {
place, ty, re, 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 Statement<'tcx> {
source_info, kind
}
}
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,
}
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),
}
}
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, T> TypeFoldable<'tcx> for ClearCrossCrate<T> {
(ClearCrossCrate::Clear),
(ClearCrossCrate::Set)(a),
} where T: TypeFoldable<'tcx>
}
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
......
......@@ -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 @@ pub fn projection_ty(self, tcx: TyCtxt<'a, 'gcx, '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 },
}
}
......
......@@ -363,258 +363,67 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
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)
}
}
......@@ -49,6 +49,9 @@
/// 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 {
......
......@@ -18,7 +18,6 @@
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 @@ fn relate<'a, 'gcx, R>(relation: &mut R,
#[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
}
}
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册