Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit a5ab8da

Browse files
committed
derive TypeVisitable and TypeFoldable for mir types
1 parent d376012 commit a5ab8da

File tree

5 files changed

+25
-312
lines changed

5 files changed

+25
-312
lines changed

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,6 +2028,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
20282028
/// particular, one must be wary of `NaN`!
20292029
20302030
#[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
2031+
#[derive(TypeFoldable, TypeVisitable)]
20312032
pub struct Constant<'tcx> {
20322033
pub span: Span,
20332034

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ pub struct CopyNonOverlapping<'tcx> {
488488
/// must also be `cleanup`. This is a part of the type system and checked statically, so it is
489489
/// still an error to have such an edge in the CFG even if it's known that it won't be taken at
490490
/// runtime.
491-
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
491+
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
492492
pub enum TerminatorKind<'tcx> {
493493
/// Block has one successor; we continue execution there.
494494
Goto { target: BasicBlock },
@@ -741,7 +741,7 @@ pub enum TerminatorKind<'tcx> {
741741
}
742742

743743
/// Information about an assertion failure.
744-
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
744+
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
745745
pub enum AssertKind<O> {
746746
BoundsCheck { len: O, index: O },
747747
Overflow(BinOp, O, O),
@@ -863,7 +863,7 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
863863
///
864864
/// Rust currently requires that every place obey those two rules. This is checked by MIRI and taken
865865
/// advantage of by codegen (via `gep inbounds`). That is possibly subject to change.
866-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable)]
866+
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable, TypeFoldable, TypeVisitable)]
867867
pub struct Place<'tcx> {
868868
pub local: Local,
869869

@@ -955,7 +955,7 @@ pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
955955
/// **Needs clarifiation:** Is loading a place that has its variant index set well-formed? Miri
956956
/// currently implements it, but it seems like this may be something to check against in the
957957
/// validator.
958-
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
958+
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
959959
pub enum Operand<'tcx> {
960960
/// Creates a value by loading the given place.
961961
///
@@ -986,7 +986,7 @@ pub enum Operand<'tcx> {
986986
/// Computing any rvalue begins by evaluating the places and operands in some order (**Needs
987987
/// clarification**: Which order?). These are then used to produce a "value" - the same kind of
988988
/// value that an [`Operand`] produces.
989-
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
989+
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
990990
pub enum Rvalue<'tcx> {
991991
/// Yields the operand unchanged
992992
Use(Operand<'tcx>),
@@ -1146,6 +1146,7 @@ pub enum CastKind {
11461146
}
11471147

11481148
#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
1149+
#[derive(TypeFoldable, TypeVisitable)]
11491150
pub enum AggregateKind<'tcx> {
11501151
/// The type is of the element
11511152
Array(Ty<'tcx>),

compiler/rustc_middle/src/mir/terminator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl<'a> Iterator for SwitchTargetsIter<'a> {
102102

103103
impl<'a> ExactSizeIterator for SwitchTargetsIter<'a> {}
104104

105-
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
105+
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
106106
pub struct Terminator<'tcx> {
107107
pub source_info: SourceInfo,
108108
pub kind: TerminatorKind<'tcx>,

compiler/rustc_middle/src/mir/type_foldable.rs

Lines changed: 17 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
//! `TypeFoldable` implementations for MIR types
22
3+
use rustc_ast::InlineAsmTemplatePiece;
4+
35
use super::*;
46
use crate::ty;
5-
use rustc_data_structures::functor::IdFunctor;
67

78
TrivialTypeTraversalAndLiftImpls! {
89
BlockTailInfo,
@@ -13,96 +14,27 @@ TrivialTypeTraversalAndLiftImpls! {
1314
SourceScope,
1415
SourceScopeLocalData,
1516
UserTypeAnnotationIndex,
17+
BorrowKind,
18+
CastKind,
19+
BinOp,
20+
NullOp,
21+
UnOp,
22+
hir::Movability,
23+
BasicBlock,
24+
SwitchTargets,
25+
GeneratorKind,
26+
GeneratorSavedLocal,
1627
}
1728

18-
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
19-
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
20-
use crate::mir::TerminatorKind::*;
21-
22-
let kind = match self.kind {
23-
Goto { target } => Goto { target },
24-
SwitchInt { discr, switch_ty, targets } => SwitchInt {
25-
discr: discr.try_fold_with(folder)?,
26-
switch_ty: switch_ty.try_fold_with(folder)?,
27-
targets,
28-
},
29-
Drop { place, target, unwind } => {
30-
Drop { place: place.try_fold_with(folder)?, target, unwind }
31-
}
32-
DropAndReplace { place, value, target, unwind } => DropAndReplace {
33-
place: place.try_fold_with(folder)?,
34-
value: value.try_fold_with(folder)?,
35-
target,
36-
unwind,
37-
},
38-
Yield { value, resume, resume_arg, drop } => Yield {
39-
value: value.try_fold_with(folder)?,
40-
resume,
41-
resume_arg: resume_arg.try_fold_with(folder)?,
42-
drop,
43-
},
44-
Call { func, args, destination, target, cleanup, from_hir_call, fn_span } => Call {
45-
func: func.try_fold_with(folder)?,
46-
args: args.try_fold_with(folder)?,
47-
destination: destination.try_fold_with(folder)?,
48-
target,
49-
cleanup,
50-
from_hir_call,
51-
fn_span,
52-
},
53-
Assert { cond, expected, msg, target, cleanup } => {
54-
use AssertKind::*;
55-
let msg = match msg {
56-
BoundsCheck { len, index } => BoundsCheck {
57-
len: len.try_fold_with(folder)?,
58-
index: index.try_fold_with(folder)?,
59-
},
60-
Overflow(op, l, r) => {
61-
Overflow(op, l.try_fold_with(folder)?, r.try_fold_with(folder)?)
62-
}
63-
OverflowNeg(op) => OverflowNeg(op.try_fold_with(folder)?),
64-
DivisionByZero(op) => DivisionByZero(op.try_fold_with(folder)?),
65-
RemainderByZero(op) => RemainderByZero(op.try_fold_with(folder)?),
66-
ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg,
67-
};
68-
Assert { cond: cond.try_fold_with(folder)?, expected, msg, target, cleanup }
69-
}
70-
GeneratorDrop => GeneratorDrop,
71-
Resume => Resume,
72-
Abort => Abort,
73-
Return => Return,
74-
Unreachable => Unreachable,
75-
FalseEdge { real_target, imaginary_target } => {
76-
FalseEdge { real_target, imaginary_target }
77-
}
78-
FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
79-
InlineAsm { template, operands, options, line_spans, destination, cleanup } => {
80-
InlineAsm {
81-
template,
82-
operands: operands.try_fold_with(folder)?,
83-
options,
84-
line_spans,
85-
destination,
86-
cleanup,
87-
}
88-
}
89-
};
90-
Ok(Terminator { source_info: self.source_info, kind })
91-
}
92-
}
93-
94-
impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
95-
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
29+
impl<'tcx> TypeFoldable<'tcx> for &'tcx [InlineAsmTemplatePiece] {
30+
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
9631
Ok(self)
9732
}
9833
}
9934

100-
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
101-
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
102-
Ok(Place {
103-
local: self.local.try_fold_with(folder)?,
104-
projection: self.projection.try_fold_with(folder)?,
105-
})
35+
impl<'tcx> TypeFoldable<'tcx> for &'tcx [Span] {
36+
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
37+
Ok(self)
10638
}
10739
}
10840

@@ -112,91 +44,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
11244
}
11345
}
11446

115-
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
116-
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
117-
use crate::mir::Rvalue::*;
118-
Ok(match self {
119-
Use(op) => Use(op.try_fold_with(folder)?),
120-
Repeat(op, len) => Repeat(op.try_fold_with(folder)?, len.try_fold_with(folder)?),
121-
ThreadLocalRef(did) => ThreadLocalRef(did.try_fold_with(folder)?),
122-
Ref(region, bk, place) => {
123-
Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?)
124-
}
125-
CopyForDeref(place) => CopyForDeref(place.try_fold_with(folder)?),
126-
AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?),
127-
Len(place) => Len(place.try_fold_with(folder)?),
128-
Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?),
129-
BinaryOp(op, box (rhs, lhs)) => {
130-
BinaryOp(op, Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)))
131-
}
132-
CheckedBinaryOp(op, box (rhs, lhs)) => CheckedBinaryOp(
133-
op,
134-
Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)),
135-
),
136-
UnaryOp(op, val) => UnaryOp(op, val.try_fold_with(folder)?),
137-
Discriminant(place) => Discriminant(place.try_fold_with(folder)?),
138-
NullaryOp(op, ty) => NullaryOp(op, ty.try_fold_with(folder)?),
139-
Aggregate(kind, fields) => {
140-
let kind = kind.try_map_id(|kind| {
141-
Ok(match kind {
142-
AggregateKind::Array(ty) => AggregateKind::Array(ty.try_fold_with(folder)?),
143-
AggregateKind::Tuple => AggregateKind::Tuple,
144-
AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
145-
def,
146-
v,
147-
substs.try_fold_with(folder)?,
148-
user_ty.try_fold_with(folder)?,
149-
n,
150-
),
151-
AggregateKind::Closure(id, substs) => {
152-
AggregateKind::Closure(id, substs.try_fold_with(folder)?)
153-
}
154-
AggregateKind::Generator(id, substs, movablity) => {
155-
AggregateKind::Generator(id, substs.try_fold_with(folder)?, movablity)
156-
}
157-
})
158-
})?;
159-
Aggregate(kind, fields.try_fold_with(folder)?)
160-
}
161-
ShallowInitBox(op, ty) => {
162-
ShallowInitBox(op.try_fold_with(folder)?, ty.try_fold_with(folder)?)
163-
}
164-
})
165-
}
166-
}
167-
168-
impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
169-
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
170-
Ok(match self {
171-
Operand::Copy(place) => Operand::Copy(place.try_fold_with(folder)?),
172-
Operand::Move(place) => Operand::Move(place.try_fold_with(folder)?),
173-
Operand::Constant(c) => Operand::Constant(c.try_fold_with(folder)?),
174-
})
175-
}
176-
}
177-
178-
impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
179-
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
180-
Ok(self)
181-
}
182-
}
183-
18447
impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
18548
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
18649
Ok(self)
18750
}
18851
}
18952

190-
impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
191-
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
192-
Ok(Constant {
193-
span: self.span,
194-
user_ty: self.user_ty.try_fold_with(folder)?,
195-
literal: self.literal.try_fold_with(folder)?,
196-
})
197-
}
198-
}
199-
20053
impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
20154
#[inline(always)]
20255
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {

0 commit comments

Comments
 (0)