1
1
//! See docs in build/expr/mod.rs
2
2
3
3
use crate :: build:: expr:: category:: { Category , RvalueFunc } ;
4
- use crate :: build:: scope:: DropKind ;
5
4
use crate :: build:: { BlockAnd , BlockAndExtension , BlockFrame , Builder } ;
6
5
use crate :: thir:: * ;
7
6
use rustc_ast:: InlineAsmOptions ;
8
7
use rustc_data_structures:: fx:: FxHashMap ;
9
8
use rustc_data_structures:: stack:: ensure_sufficient_stack;
10
9
use rustc_hir as hir;
11
- use rustc_middle:: middle:: region;
12
10
use rustc_middle:: mir:: * ;
13
11
use rustc_middle:: ty:: CanonicalUserTypeAnnotation ;
14
12
15
- use std:: slice;
16
-
17
13
impl < ' a , ' tcx > Builder < ' a , ' tcx > {
18
14
/// Compile `expr`, storing the result into `destination`, which
19
15
/// is assumed to be uninitialized.
20
- /// If a `drop_scope` is provided, `destination` is scheduled to be dropped
21
- /// in `scope` once it has been initialized.
22
16
crate fn into_expr (
23
17
& mut self ,
24
18
destination : Place < ' tcx > ,
25
- scope : Option < region:: Scope > ,
26
19
mut block : BasicBlock ,
27
20
expr : Expr < ' tcx > ,
28
21
) -> BlockAnd < ( ) > {
29
- debug ! (
30
- "into_expr(destination={:?}, scope={:?}, block={:?}, expr={:?})" ,
31
- destination, scope, block, expr
32
- ) ;
22
+ debug ! ( "into_expr(destination={:?}, block={:?}, expr={:?})" , destination, block, expr) ;
33
23
34
24
// since we frequently have to reference `self` from within a
35
25
// closure, where `self` would be shadowed, it's easier to
@@ -41,14 +31,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
41
31
let expr_is_block_or_scope =
42
32
matches ! ( expr. kind, ExprKind :: Block { .. } | ExprKind :: Scope { .. } ) ;
43
33
44
- let schedule_drop = move |this : & mut Self | {
45
- if let Some ( drop_scope) = scope {
46
- let local =
47
- destination. as_local ( ) . expect ( "cannot schedule drop of non-Local place" ) ;
48
- this. schedule_drop ( expr_span, drop_scope, local, DropKind :: Value ) ;
49
- }
50
- } ;
51
-
52
34
if !expr_is_block_or_scope {
53
35
this. block_context . push ( BlockFrame :: SubExpr ) ;
54
36
}
@@ -58,15 +40,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
58
40
let region_scope = ( region_scope, source_info) ;
59
41
ensure_sufficient_stack ( || {
60
42
this. in_scope ( region_scope, lint_level, |this| {
61
- this. into ( destination, scope , block, value)
43
+ this. into ( destination, block, value)
62
44
} )
63
45
} )
64
46
}
65
47
ExprKind :: Block { body : ast_block } => {
66
- this. ast_block ( destination, scope , block, ast_block, source_info)
48
+ this. ast_block ( destination, block, ast_block, source_info)
67
49
}
68
50
ExprKind :: Match { scrutinee, arms } => {
69
- this. match_expr ( destination, scope , expr_span, block, scrutinee, arms)
51
+ this. match_expr ( destination, expr_span, block, scrutinee, arms)
70
52
}
71
53
ExprKind :: If { cond, then, else_opt } => {
72
54
let place = unpack ! (
@@ -79,9 +61,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
79
61
let term = TerminatorKind :: if_ ( this. hir . tcx ( ) , operand, then_block, else_block) ;
80
62
this. cfg . terminate ( block, source_info, term) ;
81
63
82
- unpack ! ( then_block = this. into( destination, scope , then_block, then) ) ;
64
+ unpack ! ( then_block = this. into( destination, then_block, then) ) ;
83
65
else_block = if let Some ( else_opt) = else_opt {
84
- unpack ! ( this. into( destination, None , else_block, else_opt) )
66
+ unpack ! ( this. into( destination, else_block, else_opt) )
85
67
} else {
86
68
// Body of the `if` expression without an `else` clause must return `()`, thus
87
69
// we implicitly generate a `else {}` if it is not specified.
@@ -117,7 +99,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
117
99
118
100
// This is an optimization. If the expression was a call then we already have an
119
101
// unreachable block. Don't bother to terminate it and create a new one.
120
- schedule_drop ( this) ;
121
102
if is_call {
122
103
block. unit ( )
123
104
} else {
@@ -193,35 +174,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
193
174
// Start the loop.
194
175
this. cfg . goto ( block, source_info, loop_block) ;
195
176
196
- this. in_breakable_scope (
197
- Some ( loop_block) ,
198
- destination,
199
- scope,
200
- expr_span,
201
- move |this| {
202
- // conduct the test, if necessary
203
- let body_block = this. cfg . start_new_block ( ) ;
204
- this. cfg . terminate (
205
- loop_block,
206
- source_info,
207
- TerminatorKind :: FalseUnwind { real_target : body_block, unwind : None } ,
208
- ) ;
209
- this. diverge_from ( loop_block) ;
210
-
211
- // The “return” value of the loop body must always be an unit. We therefore
212
- // introduce a unit temporary as the destination for the loop body.
213
- let tmp = this. get_unit_temp ( ) ;
214
- // Execute the body, branching back to the test.
215
- // We don't need to provide a drop scope because `tmp`
216
- // has type `()`.
217
- let body_block_end = unpack ! ( this. into( tmp, None , body_block, body) ) ;
218
- this. cfg . goto ( body_block_end, source_info, loop_block) ;
219
- schedule_drop ( this) ;
220
-
221
- // Loops are only exited by `break` expressions.
222
- None
223
- } ,
224
- )
177
+ this. in_breakable_scope ( Some ( loop_block) , destination, expr_span, move |this| {
178
+ // conduct the test, if necessary
179
+ let body_block = this. cfg . start_new_block ( ) ;
180
+ this. cfg . terminate (
181
+ loop_block,
182
+ source_info,
183
+ TerminatorKind :: FalseUnwind { real_target : body_block, unwind : None } ,
184
+ ) ;
185
+ this. diverge_from ( loop_block) ;
186
+
187
+ // The “return” value of the loop body must always be an unit. We therefore
188
+ // introduce a unit temporary as the destination for the loop body.
189
+ let tmp = this. get_unit_temp ( ) ;
190
+ // Execute the body, branching back to the test.
191
+ let body_block_end = unpack ! ( this. into( tmp, body_block, body) ) ;
192
+ this. cfg . goto ( body_block_end, source_info, loop_block) ;
193
+
194
+ // Loops are only exited by `break` expressions.
195
+ None
196
+ } )
225
197
}
226
198
ExprKind :: Call { ty : _, fun, args, from_hir_call, fn_span } => {
227
199
let fun = unpack ! ( block = this. as_local_operand( block, fun) ) ;
@@ -256,10 +228,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
256
228
} ,
257
229
) ;
258
230
this. diverge_from ( block) ;
259
- schedule_drop ( this) ;
260
231
success. unit ( )
261
232
}
262
- ExprKind :: Use { source } => this. into ( destination, scope , block, source) ,
233
+ ExprKind :: Use { source } => this. into ( destination, block, source) ,
263
234
ExprKind :: Borrow { arg, borrow_kind } => {
264
235
// We don't do this in `as_rvalue` because we use `as_place`
265
236
// for borrow expressions, so we cannot create an `RValue` that
@@ -341,14 +312,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
341
312
user_ty,
342
313
active_field_index,
343
314
) ;
344
- this. record_operands_moved ( & fields) ;
345
315
this. cfg . push_assign (
346
316
block,
347
317
source_info,
348
318
destination,
349
319
Rvalue :: Aggregate ( adt, fields) ,
350
320
) ;
351
- schedule_drop ( this) ;
352
321
block. unit ( )
353
322
}
354
323
ExprKind :: InlineAsm { template, operands, options, line_spans } => {
@@ -445,7 +414,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
445
414
let place = unpack ! ( block = this. as_place( block, expr) ) ;
446
415
let rvalue = Rvalue :: Use ( this. consume_by_copy_or_move ( place) ) ;
447
416
this. cfg . push_assign ( block, source_info, destination, rvalue) ;
448
- schedule_drop ( this) ;
449
417
block. unit ( )
450
418
}
451
419
ExprKind :: Index { .. } | ExprKind :: Deref { .. } | ExprKind :: Field { .. } => {
@@ -463,22 +431,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
463
431
let place = unpack ! ( block = this. as_place( block, expr) ) ;
464
432
let rvalue = Rvalue :: Use ( this. consume_by_copy_or_move ( place) ) ;
465
433
this. cfg . push_assign ( block, source_info, destination, rvalue) ;
466
- schedule_drop ( this) ;
467
434
block. unit ( )
468
435
}
469
436
470
437
ExprKind :: Yield { value } => {
471
438
let scope = this. local_scope ( ) ;
472
439
let value = unpack ! ( block = this. as_operand( block, Some ( scope) , value) ) ;
473
440
let resume = this. cfg . start_new_block ( ) ;
474
- this. record_operands_moved ( slice:: from_ref ( & value) ) ;
475
441
this. cfg . terminate (
476
442
block,
477
443
source_info,
478
444
TerminatorKind :: Yield { value, resume, resume_arg : destination, drop : None } ,
479
445
) ;
480
446
this. generator_drop_cleanup ( block) ;
481
- schedule_drop ( this) ;
482
447
resume. unit ( )
483
448
}
484
449
@@ -510,7 +475,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
510
475
511
476
let rvalue = unpack ! ( block = this. as_local_rvalue( block, expr) ) ;
512
477
this. cfg . push_assign ( block, source_info, destination, rvalue) ;
513
- schedule_drop ( this) ;
514
478
block. unit ( )
515
479
}
516
480
} ;
0 commit comments