For diagnostics, set spans of drops of temps to be that of the statement's terminating semicolon.
This commit is contained in:
parent
1d834550d5
commit
ece4f472c9
@ -90,7 +90,7 @@ fn ast_block_stmts(&mut self,
|
||||
|
||||
let source_info = this.source_info(span);
|
||||
for stmt in stmts {
|
||||
let Stmt { kind, opt_destruction_scope } = this.hir.mirror(stmt);
|
||||
let Stmt { kind, opt_destruction_scope, span: stmt_span } = this.hir.mirror(stmt);
|
||||
match kind {
|
||||
StmtKind::Expr { scope, expr } => {
|
||||
this.block_context.push(BlockFrame::Statement { ignores_expr_result: true });
|
||||
@ -99,7 +99,7 @@ fn ast_block_stmts(&mut self,
|
||||
let si = (scope, source_info);
|
||||
this.in_scope(si, LintLevel::Inherited, block, |this| {
|
||||
let expr = this.hir.mirror(expr);
|
||||
this.stmt_expr(block, expr)
|
||||
this.stmt_expr(block, expr, Some(stmt_span))
|
||||
})
|
||||
}));
|
||||
}
|
||||
|
@ -351,7 +351,7 @@ fn expr_as_rvalue(
|
||||
block.and(Rvalue::Aggregate(adt, fields))
|
||||
}
|
||||
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
|
||||
block = unpack!(this.stmt_expr(block, expr));
|
||||
block = unpack!(this.stmt_expr(block, expr, None));
|
||||
block.and(this.unit_rvalue())
|
||||
}
|
||||
ExprKind::Yield { value } => {
|
||||
|
@ -351,7 +351,7 @@ pub fn into_expr(
|
||||
| ExprKind::Break { .. }
|
||||
| ExprKind::InlineAsm { .. }
|
||||
| ExprKind::Return { .. } => {
|
||||
unpack!(block = this.stmt_expr(block, expr));
|
||||
unpack!(block = this.stmt_expr(block, expr, None));
|
||||
this.cfg.push_assign_unit(block, source_info, destination);
|
||||
block.unit()
|
||||
}
|
||||
|
@ -14,7 +14,18 @@
|
||||
use rustc::mir::*;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<()> {
|
||||
/// Builds a block of MIR statements to evaluate the HAIR `expr`.
|
||||
/// If the original expression was an AST statement,
|
||||
/// (e.g. `some().code(&here());`) then `opt_stmt_span` is the
|
||||
/// span of that statement (including its semicolon, if any).
|
||||
/// Diagnostics use this span (which may be larger than that of
|
||||
/// `expr`) to identify when statement temporaries are dropped.
|
||||
pub fn stmt_expr(&mut self,
|
||||
mut block: BasicBlock,
|
||||
expr: Expr<'tcx>,
|
||||
opt_stmt_span: Option<StatementSpan>)
|
||||
-> BlockAnd<()>
|
||||
{
|
||||
let this = self;
|
||||
let expr_span = expr.span;
|
||||
let source_info = this.source_info(expr.span);
|
||||
@ -29,7 +40,7 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
|
||||
} => {
|
||||
let value = this.hir.mirror(value);
|
||||
this.in_scope((region_scope, source_info), lint_level, block, |this| {
|
||||
this.stmt_expr(block, value)
|
||||
this.stmt_expr(block, value, opt_stmt_span)
|
||||
})
|
||||
}
|
||||
ExprKind::Assign { lhs, rhs } => {
|
||||
@ -192,7 +203,15 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
|
||||
let expr_ty = expr.ty;
|
||||
let temp = this.temp(expr.ty.clone(), expr_span);
|
||||
unpack!(block = this.into(&temp, block, expr));
|
||||
unpack!(block = this.build_drop(block, expr_span, temp, expr_ty));
|
||||
|
||||
// Attribute drops of the statement's temps to the
|
||||
// semicolon at the statement's end.
|
||||
let drop_point = this.hir.tcx().sess.source_map().end_point(match opt_stmt_span {
|
||||
None => expr_span,
|
||||
Some(StatementSpan(span)) => span,
|
||||
});
|
||||
|
||||
unpack!(block = this.build_drop(block, drop_point, temp, expr_ty));
|
||||
block.unit()
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
for (index, stmt) in stmts.iter().enumerate() {
|
||||
let hir_id = cx.tcx.hir.node_to_hir_id(stmt.node.id());
|
||||
let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
|
||||
let stmt_span = StatementSpan(cx.tcx.hir.span(stmt.node.id()));
|
||||
match stmt.node {
|
||||
hir::StmtKind::Expr(ref expr, _) |
|
||||
hir::StmtKind::Semi(ref expr, _) => {
|
||||
@ -69,6 +70,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
expr: expr.to_ref(),
|
||||
},
|
||||
opt_destruction_scope: opt_dxn_ext,
|
||||
span: stmt_span,
|
||||
})))
|
||||
}
|
||||
hir::StmtKind::Decl(ref decl, _) => {
|
||||
@ -111,6 +113,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
lint_level: cx.lint_level_of(local.id),
|
||||
},
|
||||
opt_destruction_scope: opt_dxn_ext,
|
||||
span: stmt_span,
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
@ -71,10 +71,14 @@ pub enum StmtRef<'tcx> {
|
||||
Mirror(Box<Stmt<'tcx>>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct StatementSpan(pub Span);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Stmt<'tcx> {
|
||||
pub kind: StmtKind<'tcx>,
|
||||
pub opt_destruction_scope: Option<region::Scope>,
|
||||
pub span: StatementSpan,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
Loading…
Reference in New Issue
Block a user