Split out some impls from rustc::mir into a separate submodule
This commit is contained in:
parent
5aa15bfa1c
commit
4f513b5fd7
@ -45,6 +45,7 @@ pub mod mono;
|
||||
mod query;
|
||||
pub mod tcx;
|
||||
pub mod traversal;
|
||||
mod type_foldable;
|
||||
pub mod visit;
|
||||
|
||||
/// Types for locals
|
||||
@ -2683,325 +2684,3 @@ impl Location {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* `TypeFoldable` implementations for MIR types
|
||||
*/
|
||||
|
||||
CloneTypeFoldableAndLiftImpls! {
|
||||
BlockTailInfo,
|
||||
MirPhase,
|
||||
SourceInfo,
|
||||
FakeReadCause,
|
||||
RetagKind,
|
||||
SourceScope,
|
||||
SourceScopeData,
|
||||
SourceScopeLocalData,
|
||||
UserTypeAnnotationIndex,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
use crate::mir::TerminatorKind::*;
|
||||
|
||||
let kind = match self.kind {
|
||||
Goto { target } => Goto { target },
|
||||
SwitchInt { ref discr, switch_ty, ref values, ref targets } => SwitchInt {
|
||||
discr: discr.fold_with(folder),
|
||||
switch_ty: switch_ty.fold_with(folder),
|
||||
values: values.clone(),
|
||||
targets: targets.clone(),
|
||||
},
|
||||
Drop { ref location, target, unwind } => {
|
||||
Drop { location: location.fold_with(folder), target, unwind }
|
||||
}
|
||||
DropAndReplace { ref location, ref value, target, unwind } => DropAndReplace {
|
||||
location: location.fold_with(folder),
|
||||
value: value.fold_with(folder),
|
||||
target,
|
||||
unwind,
|
||||
},
|
||||
Yield { ref value, resume, ref resume_arg, drop } => Yield {
|
||||
value: value.fold_with(folder),
|
||||
resume,
|
||||
resume_arg: resume_arg.fold_with(folder),
|
||||
drop,
|
||||
},
|
||||
Call { ref func, ref args, ref destination, cleanup, from_hir_call } => {
|
||||
let dest =
|
||||
destination.as_ref().map(|&(ref loc, dest)| (loc.fold_with(folder), dest));
|
||||
|
||||
Call {
|
||||
func: func.fold_with(folder),
|
||||
args: args.fold_with(folder),
|
||||
destination: dest,
|
||||
cleanup,
|
||||
from_hir_call,
|
||||
}
|
||||
}
|
||||
Assert { ref cond, expected, ref msg, target, cleanup } => {
|
||||
use AssertKind::*;
|
||||
let msg = match msg {
|
||||
BoundsCheck { ref len, ref index } => {
|
||||
BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder) }
|
||||
}
|
||||
Overflow(_)
|
||||
| OverflowNeg
|
||||
| DivisionByZero
|
||||
| RemainderByZero
|
||||
| ResumedAfterReturn(_)
|
||||
| ResumedAfterPanic(_) => msg.clone(),
|
||||
};
|
||||
Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup }
|
||||
}
|
||||
GeneratorDrop => GeneratorDrop,
|
||||
Resume => Resume,
|
||||
Abort => Abort,
|
||||
Return => Return,
|
||||
Unreachable => Unreachable,
|
||||
FalseEdges { real_target, imaginary_target } => {
|
||||
FalseEdges { real_target, imaginary_target }
|
||||
}
|
||||
FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
|
||||
};
|
||||
Terminator { source_info: self.source_info, kind }
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
use crate::mir::TerminatorKind::*;
|
||||
|
||||
match self.kind {
|
||||
SwitchInt { ref discr, switch_ty, .. } => {
|
||||
discr.visit_with(visitor) || switch_ty.visit_with(visitor)
|
||||
}
|
||||
Drop { ref location, .. } => location.visit_with(visitor),
|
||||
DropAndReplace { ref location, ref value, .. } => {
|
||||
location.visit_with(visitor) || value.visit_with(visitor)
|
||||
}
|
||||
Yield { ref value, .. } => value.visit_with(visitor),
|
||||
Call { ref func, ref args, ref destination, .. } => {
|
||||
let dest = if let Some((ref loc, _)) = *destination {
|
||||
loc.visit_with(visitor)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
dest || func.visit_with(visitor) || args.visit_with(visitor)
|
||||
}
|
||||
Assert { ref cond, ref msg, .. } => {
|
||||
if cond.visit_with(visitor) {
|
||||
use AssertKind::*;
|
||||
match msg {
|
||||
BoundsCheck { ref len, ref index } => {
|
||||
len.visit_with(visitor) || index.visit_with(visitor)
|
||||
}
|
||||
Overflow(_)
|
||||
| OverflowNeg
|
||||
| DivisionByZero
|
||||
| RemainderByZero
|
||||
| ResumedAfterReturn(_)
|
||||
| ResumedAfterPanic(_) => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
Goto { .. }
|
||||
| Resume
|
||||
| Abort
|
||||
| Return
|
||||
| GeneratorDrop
|
||||
| Unreachable
|
||||
| FalseEdges { .. }
|
||||
| FalseUnwind { .. } => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) }
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.local.visit_with(visitor) || self.projection.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
let v = self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>();
|
||||
folder.tcx().intern_place_elems(&v)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
use crate::mir::Rvalue::*;
|
||||
match *self {
|
||||
Use(ref op) => Use(op.fold_with(folder)),
|
||||
Repeat(ref op, len) => Repeat(op.fold_with(folder), len),
|
||||
Ref(region, bk, ref place) => {
|
||||
Ref(region.fold_with(folder), bk, place.fold_with(folder))
|
||||
}
|
||||
AddressOf(mutability, ref place) => AddressOf(mutability, place.fold_with(folder)),
|
||||
Len(ref place) => Len(place.fold_with(folder)),
|
||||
Cast(kind, ref op, ty) => Cast(kind, op.fold_with(folder), ty.fold_with(folder)),
|
||||
BinaryOp(op, ref rhs, ref lhs) => {
|
||||
BinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
|
||||
}
|
||||
CheckedBinaryOp(op, ref rhs, ref lhs) => {
|
||||
CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
|
||||
}
|
||||
UnaryOp(op, ref val) => UnaryOp(op, val.fold_with(folder)),
|
||||
Discriminant(ref place) => Discriminant(place.fold_with(folder)),
|
||||
NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
|
||||
Aggregate(ref kind, ref fields) => {
|
||||
let kind = box match **kind {
|
||||
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
|
||||
AggregateKind::Tuple => AggregateKind::Tuple,
|
||||
AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
|
||||
def,
|
||||
v,
|
||||
substs.fold_with(folder),
|
||||
user_ty.fold_with(folder),
|
||||
n,
|
||||
),
|
||||
AggregateKind::Closure(id, substs) => {
|
||||
AggregateKind::Closure(id, substs.fold_with(folder))
|
||||
}
|
||||
AggregateKind::Generator(id, substs, movablity) => {
|
||||
AggregateKind::Generator(id, substs.fold_with(folder), movablity)
|
||||
}
|
||||
};
|
||||
Aggregate(kind, fields.fold_with(folder))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
use crate::mir::Rvalue::*;
|
||||
match *self {
|
||||
Use(ref op) => op.visit_with(visitor),
|
||||
Repeat(ref op, _) => op.visit_with(visitor),
|
||||
Ref(region, _, ref place) => region.visit_with(visitor) || place.visit_with(visitor),
|
||||
AddressOf(_, ref place) => place.visit_with(visitor),
|
||||
Len(ref place) => place.visit_with(visitor),
|
||||
Cast(_, ref op, ty) => op.visit_with(visitor) || ty.visit_with(visitor),
|
||||
BinaryOp(_, ref rhs, ref lhs) | CheckedBinaryOp(_, ref rhs, ref lhs) => {
|
||||
rhs.visit_with(visitor) || lhs.visit_with(visitor)
|
||||
}
|
||||
UnaryOp(_, ref val) => val.visit_with(visitor),
|
||||
Discriminant(ref place) => place.visit_with(visitor),
|
||||
NullaryOp(_, ty) => ty.visit_with(visitor),
|
||||
Aggregate(ref kind, ref fields) => {
|
||||
(match **kind {
|
||||
AggregateKind::Array(ty) => ty.visit_with(visitor),
|
||||
AggregateKind::Tuple => false,
|
||||
AggregateKind::Adt(_, _, substs, user_ty, _) => {
|
||||
substs.visit_with(visitor) || user_ty.visit_with(visitor)
|
||||
}
|
||||
AggregateKind::Closure(_, substs) => substs.visit_with(visitor),
|
||||
AggregateKind::Generator(_, substs, _) => substs.visit_with(visitor),
|
||||
}) || fields.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
match *self {
|
||||
Operand::Copy(ref place) => Operand::Copy(place.fold_with(folder)),
|
||||
Operand::Move(ref place) => Operand::Move(place.fold_with(folder)),
|
||||
Operand::Constant(ref c) => Operand::Constant(c.fold_with(folder)),
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
match *self {
|
||||
Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
|
||||
Operand::Constant(ref c) => c.visit_with(visitor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
use crate::mir::ProjectionElem::*;
|
||||
|
||||
match *self {
|
||||
Deref => Deref,
|
||||
Field(f, ty) => Field(f, ty.fold_with(folder)),
|
||||
Index(v) => Index(v.fold_with(folder)),
|
||||
Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
|
||||
ConstantIndex { offset, min_length, from_end } => {
|
||||
ConstantIndex { offset, min_length, from_end }
|
||||
}
|
||||
Subslice { from, to, from_end } => Subslice { from, to, from_end },
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
|
||||
use crate::mir::ProjectionElem::*;
|
||||
|
||||
match self {
|
||||
Field(_, ty) => ty.visit_with(visitor),
|
||||
Index(v) => v.visit_with(visitor),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Field {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
self.clone()
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
Constant {
|
||||
span: self.span,
|
||||
user_ty: self.user_ty.fold_with(folder),
|
||||
literal: self.literal.fold_with(folder),
|
||||
}
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.literal.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
322
src/librustc/mir/type_foldable.rs
Normal file
322
src/librustc/mir/type_foldable.rs
Normal file
@ -0,0 +1,322 @@
|
||||
//! `TypeFoldable` implementations for MIR types
|
||||
|
||||
use super::*;
|
||||
use crate::ty;
|
||||
|
||||
CloneTypeFoldableAndLiftImpls! {
|
||||
BlockTailInfo,
|
||||
MirPhase,
|
||||
SourceInfo,
|
||||
FakeReadCause,
|
||||
RetagKind,
|
||||
SourceScope,
|
||||
SourceScopeData,
|
||||
SourceScopeLocalData,
|
||||
UserTypeAnnotationIndex,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
use crate::mir::TerminatorKind::*;
|
||||
|
||||
let kind = match self.kind {
|
||||
Goto { target } => Goto { target },
|
||||
SwitchInt { ref discr, switch_ty, ref values, ref targets } => SwitchInt {
|
||||
discr: discr.fold_with(folder),
|
||||
switch_ty: switch_ty.fold_with(folder),
|
||||
values: values.clone(),
|
||||
targets: targets.clone(),
|
||||
},
|
||||
Drop { ref location, target, unwind } => {
|
||||
Drop { location: location.fold_with(folder), target, unwind }
|
||||
}
|
||||
DropAndReplace { ref location, ref value, target, unwind } => DropAndReplace {
|
||||
location: location.fold_with(folder),
|
||||
value: value.fold_with(folder),
|
||||
target,
|
||||
unwind,
|
||||
},
|
||||
Yield { ref value, resume, ref resume_arg, drop } => Yield {
|
||||
value: value.fold_with(folder),
|
||||
resume,
|
||||
resume_arg: resume_arg.fold_with(folder),
|
||||
drop,
|
||||
},
|
||||
Call { ref func, ref args, ref destination, cleanup, from_hir_call } => {
|
||||
let dest =
|
||||
destination.as_ref().map(|&(ref loc, dest)| (loc.fold_with(folder), dest));
|
||||
|
||||
Call {
|
||||
func: func.fold_with(folder),
|
||||
args: args.fold_with(folder),
|
||||
destination: dest,
|
||||
cleanup,
|
||||
from_hir_call,
|
||||
}
|
||||
}
|
||||
Assert { ref cond, expected, ref msg, target, cleanup } => {
|
||||
use AssertKind::*;
|
||||
let msg = match msg {
|
||||
BoundsCheck { ref len, ref index } => {
|
||||
BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder) }
|
||||
}
|
||||
Overflow(_)
|
||||
| OverflowNeg
|
||||
| DivisionByZero
|
||||
| RemainderByZero
|
||||
| ResumedAfterReturn(_)
|
||||
| ResumedAfterPanic(_) => msg.clone(),
|
||||
};
|
||||
Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup }
|
||||
}
|
||||
GeneratorDrop => GeneratorDrop,
|
||||
Resume => Resume,
|
||||
Abort => Abort,
|
||||
Return => Return,
|
||||
Unreachable => Unreachable,
|
||||
FalseEdges { real_target, imaginary_target } => {
|
||||
FalseEdges { real_target, imaginary_target }
|
||||
}
|
||||
FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
|
||||
};
|
||||
Terminator { source_info: self.source_info, kind }
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
use crate::mir::TerminatorKind::*;
|
||||
|
||||
match self.kind {
|
||||
SwitchInt { ref discr, switch_ty, .. } => {
|
||||
discr.visit_with(visitor) || switch_ty.visit_with(visitor)
|
||||
}
|
||||
Drop { ref location, .. } => location.visit_with(visitor),
|
||||
DropAndReplace { ref location, ref value, .. } => {
|
||||
location.visit_with(visitor) || value.visit_with(visitor)
|
||||
}
|
||||
Yield { ref value, .. } => value.visit_with(visitor),
|
||||
Call { ref func, ref args, ref destination, .. } => {
|
||||
let dest = if let Some((ref loc, _)) = *destination {
|
||||
loc.visit_with(visitor)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
dest || func.visit_with(visitor) || args.visit_with(visitor)
|
||||
}
|
||||
Assert { ref cond, ref msg, .. } => {
|
||||
if cond.visit_with(visitor) {
|
||||
use AssertKind::*;
|
||||
match msg {
|
||||
BoundsCheck { ref len, ref index } => {
|
||||
len.visit_with(visitor) || index.visit_with(visitor)
|
||||
}
|
||||
Overflow(_)
|
||||
| OverflowNeg
|
||||
| DivisionByZero
|
||||
| RemainderByZero
|
||||
| ResumedAfterReturn(_)
|
||||
| ResumedAfterPanic(_) => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
Goto { .. }
|
||||
| Resume
|
||||
| Abort
|
||||
| Return
|
||||
| GeneratorDrop
|
||||
| Unreachable
|
||||
| FalseEdges { .. }
|
||||
| FalseUnwind { .. } => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) }
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.local.visit_with(visitor) || self.projection.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
let v = self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>();
|
||||
folder.tcx().intern_place_elems(&v)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.iter().any(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
use crate::mir::Rvalue::*;
|
||||
match *self {
|
||||
Use(ref op) => Use(op.fold_with(folder)),
|
||||
Repeat(ref op, len) => Repeat(op.fold_with(folder), len),
|
||||
Ref(region, bk, ref place) => {
|
||||
Ref(region.fold_with(folder), bk, place.fold_with(folder))
|
||||
}
|
||||
AddressOf(mutability, ref place) => AddressOf(mutability, place.fold_with(folder)),
|
||||
Len(ref place) => Len(place.fold_with(folder)),
|
||||
Cast(kind, ref op, ty) => Cast(kind, op.fold_with(folder), ty.fold_with(folder)),
|
||||
BinaryOp(op, ref rhs, ref lhs) => {
|
||||
BinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
|
||||
}
|
||||
CheckedBinaryOp(op, ref rhs, ref lhs) => {
|
||||
CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
|
||||
}
|
||||
UnaryOp(op, ref val) => UnaryOp(op, val.fold_with(folder)),
|
||||
Discriminant(ref place) => Discriminant(place.fold_with(folder)),
|
||||
NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
|
||||
Aggregate(ref kind, ref fields) => {
|
||||
let kind = box match **kind {
|
||||
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
|
||||
AggregateKind::Tuple => AggregateKind::Tuple,
|
||||
AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
|
||||
def,
|
||||
v,
|
||||
substs.fold_with(folder),
|
||||
user_ty.fold_with(folder),
|
||||
n,
|
||||
),
|
||||
AggregateKind::Closure(id, substs) => {
|
||||
AggregateKind::Closure(id, substs.fold_with(folder))
|
||||
}
|
||||
AggregateKind::Generator(id, substs, movablity) => {
|
||||
AggregateKind::Generator(id, substs.fold_with(folder), movablity)
|
||||
}
|
||||
};
|
||||
Aggregate(kind, fields.fold_with(folder))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
use crate::mir::Rvalue::*;
|
||||
match *self {
|
||||
Use(ref op) => op.visit_with(visitor),
|
||||
Repeat(ref op, _) => op.visit_with(visitor),
|
||||
Ref(region, _, ref place) => region.visit_with(visitor) || place.visit_with(visitor),
|
||||
AddressOf(_, ref place) => place.visit_with(visitor),
|
||||
Len(ref place) => place.visit_with(visitor),
|
||||
Cast(_, ref op, ty) => op.visit_with(visitor) || ty.visit_with(visitor),
|
||||
BinaryOp(_, ref rhs, ref lhs) | CheckedBinaryOp(_, ref rhs, ref lhs) => {
|
||||
rhs.visit_with(visitor) || lhs.visit_with(visitor)
|
||||
}
|
||||
UnaryOp(_, ref val) => val.visit_with(visitor),
|
||||
Discriminant(ref place) => place.visit_with(visitor),
|
||||
NullaryOp(_, ty) => ty.visit_with(visitor),
|
||||
Aggregate(ref kind, ref fields) => {
|
||||
(match **kind {
|
||||
AggregateKind::Array(ty) => ty.visit_with(visitor),
|
||||
AggregateKind::Tuple => false,
|
||||
AggregateKind::Adt(_, _, substs, user_ty, _) => {
|
||||
substs.visit_with(visitor) || user_ty.visit_with(visitor)
|
||||
}
|
||||
AggregateKind::Closure(_, substs) => substs.visit_with(visitor),
|
||||
AggregateKind::Generator(_, substs, _) => substs.visit_with(visitor),
|
||||
}) || fields.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
match *self {
|
||||
Operand::Copy(ref place) => Operand::Copy(place.fold_with(folder)),
|
||||
Operand::Move(ref place) => Operand::Move(place.fold_with(folder)),
|
||||
Operand::Constant(ref c) => Operand::Constant(c.fold_with(folder)),
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
match *self {
|
||||
Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
|
||||
Operand::Constant(ref c) => c.visit_with(visitor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
use crate::mir::ProjectionElem::*;
|
||||
|
||||
match *self {
|
||||
Deref => Deref,
|
||||
Field(f, ty) => Field(f, ty.fold_with(folder)),
|
||||
Index(v) => Index(v.fold_with(folder)),
|
||||
Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
|
||||
ConstantIndex { offset, min_length, from_end } => {
|
||||
ConstantIndex { offset, min_length, from_end }
|
||||
}
|
||||
Subslice { from, to, from_end } => Subslice { from, to, from_end },
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
|
||||
use crate::mir::ProjectionElem::*;
|
||||
|
||||
match self {
|
||||
Field(_, ty) => ty.visit_with(visitor),
|
||||
Index(v) => v.visit_with(visitor),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Field {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
*self
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
|
||||
self.clone()
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
Constant {
|
||||
span: self.span,
|
||||
user_ty: self.user_ty.fold_with(folder),
|
||||
literal: self.literal.fold_with(folder),
|
||||
}
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.literal.visit_with(visitor)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user