11use crate :: build:: scope:: BreakableScope ;
22use crate :: build:: { BlockAnd , BlockAndExtension , BlockFrame , Builder } ;
33use crate :: hair:: * ;
4+ use rustc:: middle:: region;
45use rustc:: mir:: * ;
56
67impl < ' a , ' tcx > Builder < ' a , ' tcx > {
78 /// Builds a block of MIR statements to evaluate the HAIR `expr`.
89 /// If the original expression was an AST statement,
910 /// (e.g., `some().code(&here());`) then `opt_stmt_span` is the
1011 /// span of that statement (including its semicolon, if any).
11- /// Diagnostics use this span (which may be larger than that of
12- /// `expr`) to identify when statement temporaries are dropped.
13- pub fn stmt_expr ( & mut self ,
14- mut block : BasicBlock ,
15- expr : Expr < ' tcx > ,
16- opt_stmt_span : Option < StatementSpan > )
17- -> BlockAnd < ( ) >
18- {
12+ /// The scope is used if a statement temporary must be dropped.
13+ pub fn stmt_expr (
14+ & mut self ,
15+ mut block : BasicBlock ,
16+ expr : Expr < ' tcx > ,
17+ statement_scope : Option < region:: Scope > ,
18+ ) -> BlockAnd < ( ) > {
1919 let this = self ;
2020 let expr_span = expr. span ;
2121 let source_info = this. source_info ( expr. span ) ;
@@ -30,7 +30,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
3030 } => {
3131 let value = this. hir . mirror ( value) ;
3232 this. in_scope ( ( region_scope, source_info) , lint_level, |this| {
33- this. stmt_expr ( block, value, opt_stmt_span )
33+ this. stmt_expr ( block, value, statement_scope )
3434 } )
3535 }
3636 ExprKind :: Assign { lhs, rhs } => {
@@ -199,7 +199,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
199199 block. unit ( )
200200 }
201201 _ => {
202- let expr_ty = expr. ty ;
202+ assert ! (
203+ statement_scope. is_some( ) ,
204+ "Should not be calling `stmt_expr` on a general expression \
205+ without a statement scope",
206+ ) ;
203207
204208 // Issue #54382: When creating temp for the value of
205209 // expression like:
@@ -208,48 +212,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
208212 //
209213 // it is usually better to focus on `the_value` rather
210214 // than the entirety of block(s) surrounding it.
211- let mut temp_span = expr_span ;
212- let mut temp_in_tail_of_block = false ;
213- if let ExprKind :: Block { body } = expr . kind {
214- if let Some ( tail_expr ) = & body . expr {
215- let mut expr = tail_expr ;
216- while let rustc :: hir :: ExprKind :: Block ( subblock , _label ) = & expr . node {
217- if let Some ( subtail_expr ) = & subblock . expr {
218- expr = subtail_expr
219- } else {
220- break ;
215+ let adjusted_span = ( || {
216+ if let ExprKind :: Block { body } = expr . kind {
217+ if let Some ( tail_expr ) = & body . expr {
218+ let mut expr = tail_expr ;
219+ while let rustc :: hir :: ExprKind :: Block ( subblock , _label ) = & expr . node {
220+ if let Some ( subtail_expr ) = & subblock . expr {
221+ expr = subtail_expr
222+ } else {
223+ break ;
224+ }
221225 }
222- }
223- temp_span = expr. span ;
224- temp_in_tail_of_block = true ;
225- }
226- }
227-
228- let temp = {
229- let mut local_decl = LocalDecl :: new_temp ( expr. ty . clone ( ) , temp_span) ;
230- if temp_in_tail_of_block {
231- if this. block_context . currently_ignores_tail_results ( ) {
232- local_decl = local_decl. block_tail ( BlockTailInfo {
226+ this. block_context . push ( BlockFrame :: TailExpr {
233227 tail_result_is_ignored : true
234228 } ) ;
229+ return Some ( expr. span ) ;
235230 }
236231 }
237- let temp = this. local_decls . push ( local_decl) ;
238- let place = Place :: from ( temp) ;
239- debug ! ( "created temp {:?} for expr {:?} in block_context: {:?}" ,
240- temp, expr, this. block_context) ;
241- place
242- } ;
243- unpack ! ( block = this. into( & temp, block, expr) ) ;
232+ None
233+ } ) ( ) ;
234+
235+ let temp = unpack ! ( block =
236+ this. as_temp( block, statement_scope, expr, Mutability :: Not ) ) ;
244237
245- // Attribute drops of the statement's temps to the
246- // semicolon at the statement's end.
247- let drop_point = this. hir . tcx ( ) . sess . source_map ( ) . end_point ( match opt_stmt_span {
248- None => expr_span,
249- Some ( StatementSpan ( span) ) => span,
250- } ) ;
238+ if let Some ( span) = adjusted_span {
239+ this. local_decls [ temp] . source_info . span = span;
240+ this. block_context . pop ( ) ;
241+ }
251242
252- unpack ! ( block = this. build_drop( block, drop_point, temp, expr_ty) ) ;
253243 block. unit ( )
254244 }
255245 }
0 commit comments