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:: { self , CanonicalUserTypeAnnotation } ;
14
12
use rustc_span:: symbol:: sym;
15
13
use rustc_target:: spec:: abi:: Abi ;
16
14
17
- use std:: slice;
18
-
19
15
impl < ' a , ' tcx > Builder < ' a , ' tcx > {
20
16
/// Compile `expr`, storing the result into `destination`, which
21
17
/// is assumed to be uninitialized.
22
- /// If a `drop_scope` is provided, `destination` is scheduled to be dropped
23
- /// in `scope` once it has been initialized.
24
18
crate fn into_expr (
25
19
& mut self ,
26
20
destination : Place < ' tcx > ,
27
- scope : Option < region:: Scope > ,
28
21
mut block : BasicBlock ,
29
22
expr : Expr < ' tcx > ,
30
23
) -> BlockAnd < ( ) > {
31
- debug ! (
32
- "into_expr(destination={:?}, scope={:?}, block={:?}, expr={:?})" ,
33
- destination, scope, block, expr
34
- ) ;
24
+ debug ! ( "into_expr(destination={:?}, block={:?}, expr={:?})" , destination, block, expr) ;
35
25
36
26
// since we frequently have to reference `self` from within a
37
27
// closure, where `self` would be shadowed, it's easier to
@@ -46,14 +36,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
46
36
_ => false ,
47
37
} ;
48
38
49
- let schedule_drop = move |this : & mut Self | {
50
- if let Some ( drop_scope) = scope {
51
- let local =
52
- destination. as_local ( ) . expect ( "cannot schedule drop of non-Local place" ) ;
53
- this. schedule_drop ( expr_span, drop_scope, local, DropKind :: Value ) ;
54
- }
55
- } ;
56
-
57
39
if !expr_is_block_or_scope {
58
40
this. block_context . push ( BlockFrame :: SubExpr ) ;
59
41
}
@@ -63,15 +45,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
63
45
let region_scope = ( region_scope, source_info) ;
64
46
ensure_sufficient_stack ( || {
65
47
this. in_scope ( region_scope, lint_level, |this| {
66
- this. into ( destination, scope , block, value)
48
+ this. into ( destination, block, value)
67
49
} )
68
50
} )
69
51
}
70
52
ExprKind :: Block { body : ast_block } => {
71
- this. ast_block ( destination, scope , block, ast_block, source_info)
53
+ this. ast_block ( destination, block, ast_block, source_info)
72
54
}
73
55
ExprKind :: Match { scrutinee, arms } => {
74
- this. match_expr ( destination, scope , expr_span, block, scrutinee, arms)
56
+ this. match_expr ( destination, expr_span, block, scrutinee, arms)
75
57
}
76
58
ExprKind :: NeverToAny { source } => {
77
59
let source = this. hir . mirror ( source) ;
@@ -83,7 +65,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
83
65
84
66
// This is an optimization. If the expression was a call then we already have an
85
67
// unreachable block. Don't bother to terminate it and create a new one.
86
- schedule_drop ( this) ;
87
68
if is_call {
88
69
block. unit ( )
89
70
} else {
@@ -159,35 +140,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
159
140
// Start the loop.
160
141
this. cfg . goto ( block, source_info, loop_block) ;
161
142
162
- this. in_breakable_scope (
163
- Some ( loop_block) ,
164
- destination,
165
- scope,
166
- expr_span,
167
- move |this| {
168
- // conduct the test, if necessary
169
- let body_block = this. cfg . start_new_block ( ) ;
170
- this. cfg . terminate (
171
- loop_block,
172
- source_info,
173
- TerminatorKind :: FalseUnwind { real_target : body_block, unwind : None } ,
174
- ) ;
175
- this. diverge_from ( loop_block) ;
176
-
177
- // The “return” value of the loop body must always be an unit. We therefore
178
- // introduce a unit temporary as the destination for the loop body.
179
- let tmp = this. get_unit_temp ( ) ;
180
- // Execute the body, branching back to the test.
181
- // We don't need to provide a drop scope because `tmp`
182
- // has type `()`.
183
- let body_block_end = unpack ! ( this. into( tmp, None , body_block, body) ) ;
184
- this. cfg . goto ( body_block_end, source_info, loop_block) ;
185
- schedule_drop ( this) ;
186
-
187
- // Loops are only exited by `break` expressions.
188
- None
189
- } ,
190
- )
143
+ this. in_breakable_scope ( Some ( loop_block) , destination, expr_span, move |this| {
144
+ // conduct the test, if necessary
145
+ let body_block = this. cfg . start_new_block ( ) ;
146
+ this. cfg . terminate (
147
+ loop_block,
148
+ source_info,
149
+ TerminatorKind :: FalseUnwind { real_target : body_block, unwind : None } ,
150
+ ) ;
151
+ this. diverge_from ( loop_block) ;
152
+
153
+ // The “return” value of the loop body must always be an unit. We therefore
154
+ // introduce a unit temporary as the destination for the loop body.
155
+ let tmp = this. get_unit_temp ( ) ;
156
+ // Execute the body, branching back to the test.
157
+ let body_block_end = unpack ! ( this. into( tmp, body_block, body) ) ;
158
+ this. cfg . goto ( body_block_end, source_info, loop_block) ;
159
+
160
+ // Loops are only exited by `break` expressions.
161
+ None
162
+ } )
191
163
}
192
164
ExprKind :: Call { ty, fun, args, from_hir_call, fn_span } => {
193
165
let intrinsic = match * ty. kind ( ) {
@@ -220,13 +192,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
220
192
. push ( LocalDecl :: with_source_info ( ptr_ty, source_info) . internal ( ) ) ;
221
193
let ptr_temp = Place :: from ( ptr_temp) ;
222
194
// No need for a scope, ptr_temp doesn't need drop
223
- let block = unpack ! ( this. into( ptr_temp, None , block, ptr) ) ;
195
+ let block = unpack ! ( this. into( ptr_temp, block, ptr) ) ;
224
196
// Maybe we should provide a scope here so that
225
197
// `move_val_init` wouldn't leak on panic even with an
226
198
// arbitrary `val` expression, but `schedule_drop`,
227
199
// borrowck and drop elaboration all prevent us from
228
200
// dropping `ptr_temp.deref()`.
229
- this. into ( this. hir . tcx ( ) . mk_place_deref ( ptr_temp) , None , block, val)
201
+ this. into ( this. hir . tcx ( ) . mk_place_deref ( ptr_temp) , block, val)
230
202
} else {
231
203
let args: Vec < _ > = args
232
204
. into_iter ( )
@@ -259,11 +231,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
259
231
} ,
260
232
) ;
261
233
this. diverge_from ( block) ;
262
- schedule_drop ( this) ;
263
234
success. unit ( )
264
235
}
265
236
}
266
- ExprKind :: Use { source } => this. into ( destination, scope , block, source) ,
237
+ ExprKind :: Use { source } => this. into ( destination, block, source) ,
267
238
ExprKind :: Borrow { arg, borrow_kind } => {
268
239
// We don't do this in `as_rvalue` because we use `as_place`
269
240
// for borrow expressions, so we cannot create an `RValue` that
@@ -340,14 +311,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
340
311
user_ty,
341
312
active_field_index,
342
313
) ;
343
- this. record_operands_moved ( & fields) ;
344
314
this. cfg . push_assign (
345
315
block,
346
316
source_info,
347
317
destination,
348
318
Rvalue :: Aggregate ( adt, fields) ,
349
319
) ;
350
- schedule_drop ( this) ;
351
320
block. unit ( )
352
321
}
353
322
ExprKind :: InlineAsm { template, operands, options, line_spans } => {
@@ -444,7 +413,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
444
413
let place = unpack ! ( block = this. as_place( block, expr) ) ;
445
414
let rvalue = Rvalue :: Use ( this. consume_by_copy_or_move ( place) ) ;
446
415
this. cfg . push_assign ( block, source_info, destination, rvalue) ;
447
- schedule_drop ( this) ;
448
416
block. unit ( )
449
417
}
450
418
ExprKind :: Index { .. } | ExprKind :: Deref { .. } | ExprKind :: Field { .. } => {
@@ -462,22 +430,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
462
430
let place = unpack ! ( block = this. as_place( block, expr) ) ;
463
431
let rvalue = Rvalue :: Use ( this. consume_by_copy_or_move ( place) ) ;
464
432
this. cfg . push_assign ( block, source_info, destination, rvalue) ;
465
- schedule_drop ( this) ;
466
433
block. unit ( )
467
434
}
468
435
469
436
ExprKind :: Yield { value } => {
470
437
let scope = this. local_scope ( ) ;
471
438
let value = unpack ! ( block = this. as_operand( block, Some ( scope) , value) ) ;
472
439
let resume = this. cfg . start_new_block ( ) ;
473
- this. record_operands_moved ( slice:: from_ref ( & value) ) ;
474
440
this. cfg . terminate (
475
441
block,
476
442
source_info,
477
443
TerminatorKind :: Yield { value, resume, resume_arg : destination, drop : None } ,
478
444
) ;
479
445
this. generator_drop_cleanup ( block) ;
480
- schedule_drop ( this) ;
481
446
resume. unit ( )
482
447
}
483
448
@@ -509,7 +474,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
509
474
510
475
let rvalue = unpack ! ( block = this. as_local_rvalue( block, expr) ) ;
511
476
this. cfg . push_assign ( block, source_info, destination, rvalue) ;
512
- schedule_drop ( this) ;
513
477
block. unit ( )
514
478
}
515
479
} ;
0 commit comments