Skip to content

Commit 7093a21

Browse files
Adapt the THIR visitor to the vec-stored THIR
1 parent dc3eabd commit 7093a21

File tree

2 files changed

+96
-95
lines changed

2 files changed

+96
-95
lines changed

compiler/rustc_mir_build/src/check_unsafety.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ use rustc_session::lint::Level;
99
use rustc_span::def_id::{DefId, LocalDefId};
1010
use rustc_span::Span;
1111

12-
struct UnsafetyVisitor<'tcx> {
12+
struct UnsafetyVisitor<'a, 'tcx> {
1313
tcx: TyCtxt<'tcx>,
14+
thir: &'a Thir<'tcx>,
1415
/// The `HirId` of the current scope, which would be the `HirId`
1516
/// of the current HIR node, modulo adjustments. Used for lint levels.
1617
hir_context: hir::HirId,
@@ -20,7 +21,7 @@ struct UnsafetyVisitor<'tcx> {
2021
body_unsafety: BodyUnsafety,
2122
}
2223

23-
impl<'tcx> UnsafetyVisitor<'tcx> {
24+
impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
2425
fn in_safety_context<R>(
2526
&mut self,
2627
safety_context: SafetyContext,
@@ -127,8 +128,12 @@ impl<'tcx> UnsafetyVisitor<'tcx> {
127128
}
128129
}
129130

130-
impl<'thir, 'tcx> Visitor<'thir, 'tcx> for UnsafetyVisitor<'tcx> {
131-
fn visit_block(&mut self, block: &Block<'thir, 'tcx>) {
131+
impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
132+
fn thir(&self) -> &'a Thir<'tcx> {
133+
&self.thir
134+
}
135+
136+
fn visit_block(&mut self, block: &Block) {
132137
if let BlockSafety::ExplicitUnsafe(hir_id) = block.safety_mode {
133138
self.in_safety_context(
134139
SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false },
@@ -139,17 +144,17 @@ impl<'thir, 'tcx> Visitor<'thir, 'tcx> for UnsafetyVisitor<'tcx> {
139144
}
140145
}
141146

142-
fn visit_expr(&mut self, expr: &'thir Expr<'thir, 'tcx>) {
147+
fn visit_expr(&mut self, expr: &Expr<'tcx>) {
143148
match expr.kind {
144149
ExprKind::Scope { value, lint_level: LintLevel::Explicit(hir_id), region_scope: _ } => {
145150
let prev_id = self.hir_context;
146151
self.hir_context = hir_id;
147-
self.visit_expr(value);
152+
self.visit_expr(&self.thir[value]);
148153
self.hir_context = prev_id;
149154
return;
150155
}
151156
ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => {
152-
if fun.ty.fn_sig(self.tcx).unsafety() == hir::Unsafety::Unsafe {
157+
if self.thir[fun].ty.fn_sig(self.tcx).unsafety() == hir::Unsafety::Unsafe {
153158
self.requires_unsafe(expr.span, CallToUnsafeFunction);
154159
}
155160
}
@@ -293,7 +298,12 @@ impl UnsafeOpKind {
293298

294299
// FIXME: checking unsafety for closures should be handled by their parent body,
295300
// as they inherit their "safety context" from their declaration site.
296-
pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, thir: &Expr<'_, 'tcx>, hir_id: hir::HirId) {
301+
pub fn check_unsafety<'tcx>(
302+
tcx: TyCtxt<'tcx>,
303+
thir: &Thir<'tcx>,
304+
expr: ExprId,
305+
hir_id: hir::HirId,
306+
) {
297307
let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| {
298308
if fn_sig.header.unsafety == hir::Unsafety::Unsafe {
299309
BodyUnsafety::Unsafe(fn_sig.span)
@@ -303,8 +313,9 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, thir: &Expr<'_, 'tcx>, hir_id: hi
303313
});
304314
let safety_context =
305315
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
306-
let mut visitor = UnsafetyVisitor { tcx, safety_context, hir_context: hir_id, body_unsafety };
307-
visitor.visit_expr(thir);
316+
let mut visitor =
317+
UnsafetyVisitor { tcx, thir, safety_context, hir_context: hir_id, body_unsafety };
318+
visitor.visit_expr(&thir[expr]);
308319
}
309320

310321
crate fn thir_check_unsafety_inner<'tcx>(
@@ -314,10 +325,8 @@ crate fn thir_check_unsafety_inner<'tcx>(
314325
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
315326
let body_id = tcx.hir().body_owned_by(hir_id);
316327
let body = tcx.hir().body(body_id);
317-
318-
let arena = Arena::default();
319-
let thir = cx::build_thir(tcx, def, &arena, &body.value);
320-
check_unsafety(tcx, thir, hir_id);
328+
let (thir, expr) = cx::build_thir(tcx, def, &body.value);
329+
check_unsafety(tcx, &thir, expr, hir_id);
321330
}
322331

323332
crate fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
+73-81
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,124 @@
11
use crate::thir::*;
22

3-
pub trait Visitor<'thir, 'tcx>: Sized {
4-
fn visit_expr(&mut self, expr: &'thir Expr<'thir, 'tcx>) {
3+
pub trait Visitor<'a, 'tcx: 'a>: Sized {
4+
fn thir(&self) -> &'a Thir<'tcx>;
5+
6+
fn visit_expr(&mut self, expr: &Expr<'tcx>) {
57
walk_expr(self, expr);
68
}
79

8-
fn visit_stmt(&mut self, stmt: &'thir Stmt<'thir, 'tcx>) {
10+
fn visit_stmt(&mut self, stmt: &Stmt<'tcx>) {
911
walk_stmt(self, stmt);
1012
}
1113

12-
fn visit_block(&mut self, block: &Block<'thir, 'tcx>) {
14+
fn visit_block(&mut self, block: &Block) {
1315
walk_block(self, block);
1416
}
1517

16-
fn visit_arm(&mut self, arm: &'thir Arm<'thir, 'tcx>) {
18+
fn visit_arm(&mut self, arm: &Arm<'tcx>) {
1719
walk_arm(self, arm);
1820
}
1921

2022
fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
2123
}
2224

23-
pub fn walk_expr<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
24-
visitor: &mut V,
25-
expr: &'thir Expr<'thir, 'tcx>,
26-
) {
25+
pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) {
2726
use ExprKind::*;
2827
match expr.kind {
29-
Scope { value, region_scope: _, lint_level: _ } => visitor.visit_expr(value),
30-
Box { value } => visitor.visit_expr(value),
28+
Scope { value, region_scope: _, lint_level: _ } => {
29+
visitor.visit_expr(&visitor.thir()[value])
30+
}
31+
Box { value } => visitor.visit_expr(&visitor.thir()[value]),
3132
If { cond, then, else_opt } => {
32-
visitor.visit_expr(cond);
33-
visitor.visit_expr(then);
33+
visitor.visit_expr(&visitor.thir()[cond]);
34+
visitor.visit_expr(&visitor.thir()[then]);
3435
if let Some(else_expr) = else_opt {
35-
visitor.visit_expr(else_expr);
36+
visitor.visit_expr(&visitor.thir()[else_expr]);
3637
}
3738
}
38-
Call { fun, args, ty: _, from_hir_call: _, fn_span: _ } => {
39-
visitor.visit_expr(fun);
40-
for arg in args {
41-
visitor.visit_expr(arg);
39+
Call { fun, ref args, ty: _, from_hir_call: _, fn_span: _ } => {
40+
visitor.visit_expr(&visitor.thir()[fun]);
41+
for &arg in &**args {
42+
visitor.visit_expr(&visitor.thir()[arg]);
4243
}
4344
}
44-
Deref { arg } => visitor.visit_expr(arg),
45+
Deref { arg } => visitor.visit_expr(&visitor.thir()[arg]),
4546
Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => {
46-
visitor.visit_expr(lhs);
47-
visitor.visit_expr(rhs);
48-
}
49-
Unary { arg, op: _ } => visitor.visit_expr(arg),
50-
Cast { source } => visitor.visit_expr(source),
51-
Use { source } => visitor.visit_expr(source),
52-
NeverToAny { source } => visitor.visit_expr(source),
53-
Pointer { source, cast: _ } => visitor.visit_expr(source),
54-
Loop { body } => visitor.visit_expr(body),
55-
Match { scrutinee, arms } => {
56-
visitor.visit_expr(scrutinee);
57-
for arm in arms {
58-
visitor.visit_arm(arm);
47+
visitor.visit_expr(&visitor.thir()[lhs]);
48+
visitor.visit_expr(&visitor.thir()[rhs]);
49+
}
50+
Unary { arg, op: _ } => visitor.visit_expr(&visitor.thir()[arg]),
51+
Cast { source } => visitor.visit_expr(&visitor.thir()[source]),
52+
Use { source } => visitor.visit_expr(&visitor.thir()[source]),
53+
NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
54+
Pointer { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
55+
Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
56+
Match { scrutinee, ref arms } => {
57+
visitor.visit_expr(&visitor.thir()[scrutinee]);
58+
for &arm in &**arms {
59+
visitor.visit_arm(&visitor.thir()[arm]);
5960
}
6061
}
6162
Block { ref body } => visitor.visit_block(body),
6263
Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => {
63-
visitor.visit_expr(lhs);
64-
visitor.visit_expr(rhs);
64+
visitor.visit_expr(&visitor.thir()[lhs]);
65+
visitor.visit_expr(&visitor.thir()[rhs]);
6566
}
66-
Field { lhs, name: _ } => visitor.visit_expr(lhs),
67+
Field { lhs, name: _ } => visitor.visit_expr(&visitor.thir()[lhs]),
6768
Index { lhs, index } => {
68-
visitor.visit_expr(lhs);
69-
visitor.visit_expr(index);
69+
visitor.visit_expr(&visitor.thir()[lhs]);
70+
visitor.visit_expr(&visitor.thir()[index]);
7071
}
7172
VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {}
72-
Borrow { arg, borrow_kind: _ } => visitor.visit_expr(arg),
73-
AddressOf { arg, mutability: _ } => visitor.visit_expr(arg),
73+
Borrow { arg, borrow_kind: _ } => visitor.visit_expr(&visitor.thir()[arg]),
74+
AddressOf { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
7475
Break { value, label: _ } => {
7576
if let Some(value) = value {
76-
visitor.visit_expr(value)
77+
visitor.visit_expr(&visitor.thir()[value])
7778
}
7879
}
7980
Continue { label: _ } => {}
8081
Return { value } => {
8182
if let Some(value) = value {
82-
visitor.visit_expr(value)
83+
visitor.visit_expr(&visitor.thir()[value])
8384
}
8485
}
8586
ConstBlock { value } => visitor.visit_const(value),
8687
Repeat { value, count } => {
87-
visitor.visit_expr(value);
88+
visitor.visit_expr(&visitor.thir()[value]);
8889
visitor.visit_const(count);
8990
}
90-
Array { fields } | Tuple { fields } => {
91-
for field in fields {
92-
visitor.visit_expr(field);
91+
Array { ref fields } | Tuple { ref fields } => {
92+
for &field in &**fields {
93+
visitor.visit_expr(&visitor.thir()[field]);
9394
}
9495
}
95-
Adt { fields, ref base, adt_def: _, variant_index: _, substs: _, user_ty: _ } => {
96-
for field in fields {
97-
visitor.visit_expr(field.expr);
96+
Adt { ref fields, ref base, adt_def: _, variant_index: _, substs: _, user_ty: _ } => {
97+
for field in &**fields {
98+
visitor.visit_expr(&visitor.thir()[field.expr]);
9899
}
99100
if let Some(base) = base {
100-
visitor.visit_expr(base.base);
101+
visitor.visit_expr(&visitor.thir()[base.base]);
101102
}
102103
}
103104
PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
104-
visitor.visit_expr(source)
105+
visitor.visit_expr(&visitor.thir()[source])
105106
}
106107
Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
107108
Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal),
108109
StaticRef { literal, def_id: _ } => visitor.visit_const(literal),
109-
InlineAsm { operands, template: _, options: _, line_spans: _ } => {
110-
for op in operands {
110+
InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
111+
for op in &**operands {
111112
use InlineAsmOperand::*;
112113
match op {
113114
In { expr, reg: _ }
114115
| Out { expr: Some(expr), reg: _, late: _ }
115116
| InOut { expr, reg: _, late: _ }
116-
| SymFn { expr } => visitor.visit_expr(expr),
117+
| SymFn { expr } => visitor.visit_expr(&visitor.thir()[*expr]),
117118
SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
118-
visitor.visit_expr(in_expr);
119+
visitor.visit_expr(&visitor.thir()[*in_expr]);
119120
if let Some(out_expr) = out_expr {
120-
visitor.visit_expr(out_expr);
121+
visitor.visit_expr(&visitor.thir()[*out_expr]);
121122
}
122123
}
123124
Out { expr: None, reg: _, late: _ }
@@ -127,24 +128,21 @@ pub fn walk_expr<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
127128
}
128129
}
129130
ThreadLocalRef(_) => {}
130-
LlvmInlineAsm { outputs, inputs, asm: _ } => {
131-
for out_expr in outputs {
132-
visitor.visit_expr(out_expr);
131+
LlvmInlineAsm { ref outputs, ref inputs, asm: _ } => {
132+
for &out_expr in &**outputs {
133+
visitor.visit_expr(&visitor.thir()[out_expr]);
133134
}
134-
for in_expr in inputs {
135-
visitor.visit_expr(in_expr);
135+
for &in_expr in &**inputs {
136+
visitor.visit_expr(&visitor.thir()[in_expr]);
136137
}
137138
}
138-
Yield { value } => visitor.visit_expr(value),
139+
Yield { value } => visitor.visit_expr(&visitor.thir()[value]),
139140
}
140141
}
141142

142-
pub fn walk_stmt<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
143-
visitor: &mut V,
144-
stmt: &'thir Stmt<'thir, 'tcx>,
145-
) {
143+
pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stmt<'tcx>) {
146144
match stmt.kind {
147-
StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(expr),
145+
StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[expr]),
148146
StmtKind::Let {
149147
initializer,
150148
remainder_scope: _,
@@ -153,34 +151,28 @@ pub fn walk_stmt<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
153151
lint_level: _,
154152
} => {
155153
if let Some(init) = initializer {
156-
visitor.visit_expr(init);
154+
visitor.visit_expr(&visitor.thir()[init]);
157155
}
158156
}
159157
}
160158
}
161159

162-
pub fn walk_block<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
163-
visitor: &mut V,
164-
block: &Block<'thir, 'tcx>,
165-
) {
166-
for stmt in block.stmts {
167-
visitor.visit_stmt(stmt);
160+
pub fn walk_block<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, block: &Block) {
161+
for &stmt in &*block.stmts {
162+
visitor.visit_stmt(&visitor.thir()[stmt]);
168163
}
169164
if let Some(expr) = block.expr {
170-
visitor.visit_expr(expr);
165+
visitor.visit_expr(&visitor.thir()[expr]);
171166
}
172167
}
173168

174-
pub fn walk_arm<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
175-
visitor: &mut V,
176-
arm: &'thir Arm<'thir, 'tcx>,
177-
) {
169+
pub fn walk_arm<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, arm: &Arm<'tcx>) {
178170
match arm.guard {
179-
Some(Guard::If(expr)) => visitor.visit_expr(expr),
171+
Some(Guard::If(expr)) => visitor.visit_expr(&visitor.thir()[expr]),
180172
Some(Guard::IfLet(ref _pat, expr)) => {
181-
visitor.visit_expr(expr);
173+
visitor.visit_expr(&visitor.thir()[expr]);
182174
}
183175
None => {}
184176
}
185-
visitor.visit_expr(arm.body);
177+
visitor.visit_expr(&visitor.thir()[arm.body]);
186178
}

0 commit comments

Comments
 (0)