Skip to content

Commit 60def4d

Browse files
[WIP] Eagerly construct bodies of THIR
1 parent 3a5d45f commit 60def4d

File tree

18 files changed

+1315
-1554
lines changed

18 files changed

+1315
-1554
lines changed

compiler/rustc_mir_build/src/build/block.rs

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use crate::build::matches::ArmHasGuard;
22
use crate::build::ForGuard::OutsideGuard;
33
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
44
use crate::thir::*;
5-
use rustc_hir as hir;
65
use rustc_middle::mir::*;
76
use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN;
87
use rustc_session::lint::Level;
@@ -13,7 +12,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1312
&mut self,
1413
destination: Place<'tcx>,
1514
block: BasicBlock,
16-
ast_block: &'tcx hir::Block<'tcx>,
15+
ast_block: &Block<'tcx>,
1716
source_info: SourceInfo,
1817
) -> BlockAnd<()> {
1918
let Block {
@@ -24,22 +23,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2423
expr,
2524
targeted_by_break,
2625
safety_mode,
27-
} = self.hir.mirror(ast_block);
26+
} = ast_block;
2827
self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| {
29-
this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
30-
if targeted_by_break {
31-
this.in_breakable_scope(None, destination, span, |this| {
28+
this.in_scope((*region_scope, source_info), LintLevel::Inherited, move |this| {
29+
if *targeted_by_break {
30+
this.in_breakable_scope(None, destination, *span, |this| {
3231
Some(this.ast_block_stmts(
3332
destination,
3433
block,
35-
span,
36-
stmts,
37-
expr,
38-
safety_mode,
34+
*span,
35+
&stmts,
36+
expr.as_deref(),
37+
*safety_mode,
3938
))
4039
})
4140
} else {
42-
this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode)
41+
this.ast_block_stmts(
42+
destination,
43+
block,
44+
*span,
45+
&stmts,
46+
expr.as_deref(),
47+
*safety_mode,
48+
)
4349
}
4450
})
4551
})
@@ -50,8 +56,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5056
destination: Place<'tcx>,
5157
mut block: BasicBlock,
5258
span: Span,
53-
stmts: Vec<StmtRef<'tcx>>,
54-
expr: Option<ExprRef<'tcx>>,
59+
stmts: &[Stmt<'tcx>],
60+
expr: Option<&Expr<'tcx>>,
5561
safety_mode: BlockSafety,
5662
) -> BlockAnd<()> {
5763
let this = self;
@@ -79,19 +85,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7985
this.update_source_scope_for_safety_mode(span, safety_mode);
8086

8187
let source_info = this.source_info(span);
82-
for stmt in stmts {
83-
let Stmt { kind, opt_destruction_scope } = this.hir.mirror(stmt);
88+
for Stmt { kind, opt_destruction_scope } in stmts {
8489
match kind {
8590
StmtKind::Expr { scope, expr } => {
8691
this.block_context.push(BlockFrame::Statement { ignores_expr_result: true });
8792
unpack!(
8893
block = this.in_opt_scope(
8994
opt_destruction_scope.map(|de| (de, source_info)),
9095
|this| {
91-
let si = (scope, source_info);
96+
let si = (*scope, source_info);
9297
this.in_scope(si, LintLevel::Inherited, |this| {
93-
let expr = this.hir.mirror(expr);
94-
this.stmt_expr(block, expr, Some(scope))
98+
this.stmt_expr(block, &expr, Some(*scope))
9599
})
96100
}
97101
)
@@ -102,7 +106,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
102106
this.block_context.push(BlockFrame::Statement { ignores_expr_result });
103107

104108
// Enter the remainder scope, i.e., the bindings' destruction scope.
105-
this.push_scope((remainder_scope, source_info));
109+
this.push_scope((*remainder_scope, source_info));
106110
let_scope_stack.push(remainder_scope);
107111

108112
// Declare the bindings, which may create a source scope.
@@ -114,29 +118,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
114118

115119
// Evaluate the initializer, if present.
116120
if let Some(init) = initializer {
117-
let initializer_span = init.span();
121+
let initializer_span = init.span;
118122

119123
unpack!(
120124
block = this.in_opt_scope(
121125
opt_destruction_scope.map(|de| (de, source_info)),
122126
|this| {
123-
let scope = (init_scope, source_info);
124-
this.in_scope(scope, lint_level, |this| {
127+
let scope = (*init_scope, source_info);
128+
this.in_scope(scope, *lint_level, |this| {
125129
this.declare_bindings(
126130
visibility_scope,
127131
remainder_span,
128132
&pattern,
129133
ArmHasGuard(false),
130134
Some((None, initializer_span)),
131135
);
132-
this.expr_into_pattern(block, pattern, init)
136+
this.expr_into_pattern(block, pattern.clone(), &init)
133137
})
134138
}
135139
)
136140
);
137141
} else {
138-
let scope = (init_scope, source_info);
139-
unpack!(this.in_scope(scope, lint_level, |this| {
142+
let scope = (*init_scope, source_info);
143+
unpack!(this.in_scope(scope, *lint_level, |this| {
140144
this.declare_bindings(
141145
visibility_scope,
142146
remainder_span,
@@ -176,13 +180,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
176180
if let Some(expr) = expr {
177181
let tail_result_is_ignored =
178182
destination_ty.is_unit() || this.block_context.currently_ignores_tail_results();
179-
let span = match expr {
180-
ExprRef::Thir(expr) => expr.span,
181-
ExprRef::Mirror(ref expr) => expr.span,
182-
};
183-
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored, span });
183+
this.block_context
184+
.push(BlockFrame::TailExpr { tail_result_is_ignored, span: expr.span });
184185

185-
unpack!(block = this.into(destination, block, expr));
186+
unpack!(block = this.expr_into_dest(destination, block, expr));
186187
let popped = this.block_context.pop();
187188

188189
assert!(popped.map_or(false, |bf| bf.is_tail_expr()));
@@ -200,7 +201,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
200201
// Finally, we pop all the let scopes before exiting out from the scope of block
201202
// itself.
202203
for scope in let_scope_stack.into_iter().rev() {
203-
unpack!(block = this.pop_scope((scope, source_info), block));
204+
unpack!(block = this.pop_scope((*scope, source_info), block));
204205
}
205206
// Restore the original source scope.
206207
this.source_scope = outer_source_scope;

compiler/rustc_mir_build/src/build/expr/as_constant.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,27 @@ use rustc_middle::ty::CanonicalUserTypeAnnotation;
88
impl<'a, 'tcx> Builder<'a, 'tcx> {
99
/// Compile `expr`, yielding a compile-time constant. Assumes that
1010
/// `expr` is a valid compile-time constant!
11-
crate fn as_constant<M>(&mut self, expr: M) -> Constant<'tcx>
12-
where
13-
M: Mirror<'tcx, Output = Expr<'tcx>>,
14-
{
15-
let expr = self.hir.mirror(expr);
16-
self.expr_as_constant(expr)
17-
}
18-
19-
fn expr_as_constant(&mut self, expr: Expr<'tcx>) -> Constant<'tcx> {
11+
crate fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> {
2012
let this = self;
2113
let Expr { ty, temp_lifetime: _, span, kind } = expr;
2214
match kind {
23-
ExprKind::Scope { region_scope: _, lint_level: _, value } => this.as_constant(value),
15+
ExprKind::Scope { region_scope: _, lint_level: _, value } => this.as_constant(&value),
2416
ExprKind::Literal { literal, user_ty, const_id: _ } => {
2517
let user_ty = user_ty.map(|user_ty| {
2618
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
27-
span,
19+
span: *span,
2820
user_ty,
2921
inferred_ty: ty,
3022
})
3123
});
32-
assert_eq!(literal.ty, ty);
33-
Constant { span, user_ty, literal }
24+
assert_eq!(literal.ty, *ty);
25+
Constant { span: *span, user_ty, literal }
26+
}
27+
ExprKind::StaticRef { literal, .. } => Constant { span: *span, user_ty: None, literal },
28+
ExprKind::ConstBlock { value } => {
29+
Constant { span: *span, user_ty: None, literal: value }
3430
}
35-
ExprKind::StaticRef { literal, .. } => Constant { span, user_ty: None, literal },
36-
ExprKind::ConstBlock { value } => Constant { span, user_ty: None, literal: value },
37-
_ => span_bug!(span, "expression is not a valid constant {:?}", kind),
31+
_ => span_bug!(*span, "expression is not a valid constant {:?}", kind),
3832
}
3933
}
4034
}

compiler/rustc_mir_build/src/build/expr/as_operand.rs

Lines changed: 24 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1414
/// after the current enclosing `ExprKind::Scope` has ended, so
1515
/// please do *not* return it from functions to avoid bad
1616
/// miscompiles.
17-
crate fn as_local_operand<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Operand<'tcx>>
18-
where
19-
M: Mirror<'tcx, Output = Expr<'tcx>>,
20-
{
17+
crate fn as_local_operand(
18+
&mut self,
19+
block: BasicBlock,
20+
expr: &Expr<'tcx>,
21+
) -> BlockAnd<Operand<'tcx>> {
2122
let local_scope = self.local_scope();
2223
self.as_operand(block, Some(local_scope), expr)
2324
}
@@ -70,14 +71,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7071
/// value to the stack.
7172
///
7273
/// See #68034 for more details.
73-
crate fn as_local_call_operand<M>(
74+
crate fn as_local_call_operand(
7475
&mut self,
7576
block: BasicBlock,
76-
expr: M,
77-
) -> BlockAnd<Operand<'tcx>>
78-
where
79-
M: Mirror<'tcx, Output = Expr<'tcx>>,
80-
{
77+
expr: &Expr<'tcx>,
78+
) -> BlockAnd<Operand<'tcx>> {
8179
let local_scope = self.local_scope();
8280
self.as_call_operand(block, Some(local_scope), expr)
8381
}
@@ -88,52 +86,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8886
/// this time.
8987
///
9088
/// The operand is known to be live until the end of `scope`.
91-
crate fn as_operand<M>(
92-
&mut self,
93-
block: BasicBlock,
94-
scope: Option<region::Scope>,
95-
expr: M,
96-
) -> BlockAnd<Operand<'tcx>>
97-
where
98-
M: Mirror<'tcx, Output = Expr<'tcx>>,
99-
{
100-
let expr = self.hir.mirror(expr);
101-
self.expr_as_operand(block, scope, expr)
102-
}
103-
89+
///
10490
/// Like `as_local_call_operand`, except that the argument will
10591
/// not be valid once `scope` ends.
106-
fn as_call_operand<M>(
107-
&mut self,
108-
block: BasicBlock,
109-
scope: Option<region::Scope>,
110-
expr: M,
111-
) -> BlockAnd<Operand<'tcx>>
112-
where
113-
M: Mirror<'tcx, Output = Expr<'tcx>>,
114-
{
115-
let expr = self.hir.mirror(expr);
116-
self.expr_as_call_operand(block, scope, expr)
117-
}
118-
119-
fn expr_as_operand(
92+
crate fn as_operand(
12093
&mut self,
12194
mut block: BasicBlock,
12295
scope: Option<region::Scope>,
123-
expr: Expr<'tcx>,
96+
expr: &Expr<'tcx>,
12497
) -> BlockAnd<Operand<'tcx>> {
125-
debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
98+
debug!("as_operand(block={:?}, expr={:?})", block, expr);
12699
let this = self;
127100

128-
if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind {
101+
if let ExprKind::Scope { region_scope, lint_level, value } = &expr.kind {
129102
let source_info = this.source_info(expr.span);
130-
let region_scope = (region_scope, source_info);
103+
let region_scope = (*region_scope, source_info);
131104
return this
132-
.in_scope(region_scope, lint_level, |this| this.as_operand(block, scope, value));
105+
.in_scope(region_scope, *lint_level, |this| this.as_operand(block, scope, &value));
133106
}
134107

135108
let category = Category::of(&expr.kind).unwrap();
136-
debug!("expr_as_operand: category={:?} for={:?}", category, expr.kind);
109+
debug!("as_operand: category={:?} for={:?}", category, expr.kind);
137110
match category {
138111
Category::Constant => {
139112
let constant = this.as_constant(expr);
@@ -146,20 +119,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
146119
}
147120
}
148121

149-
fn expr_as_call_operand(
122+
crate fn as_call_operand(
150123
&mut self,
151124
mut block: BasicBlock,
152125
scope: Option<region::Scope>,
153-
expr: Expr<'tcx>,
126+
expr: &Expr<'tcx>,
154127
) -> BlockAnd<Operand<'tcx>> {
155-
debug!("expr_as_call_operand(block={:?}, expr={:?})", block, expr);
128+
debug!("as_call_operand(block={:?}, expr={:?})", block, expr);
156129
let this = self;
157130

158-
if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind {
131+
if let ExprKind::Scope { region_scope, lint_level, value } = &expr.kind {
159132
let source_info = this.source_info(expr.span);
160-
let region_scope = (region_scope, source_info);
161-
return this.in_scope(region_scope, lint_level, |this| {
162-
this.as_call_operand(block, scope, value)
133+
let region_scope = (*region_scope, source_info);
134+
return this.in_scope(region_scope, *lint_level, |this| {
135+
this.as_call_operand(block, scope, &value)
163136
});
164137
}
165138

@@ -177,8 +150,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
177150
// As described above, detect the case where we are passing a value of unsized
178151
// type, and that value is coming from the deref of a box.
179152
if let ExprKind::Deref { ref arg } = expr.kind {
180-
let arg = this.hir.mirror(arg.clone());
181-
182153
// Generate let tmp0 = arg0
183154
let operand = unpack!(block = this.as_temp(block, scope, arg, Mutability::Mut));
184155

@@ -193,6 +164,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
193164
}
194165
}
195166

196-
this.expr_as_operand(block, scope, expr)
167+
this.as_operand(block, scope, expr)
197168
}
198169
}

0 commit comments

Comments
 (0)