diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 28fedd9d2561..bd17080e8c2a 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -68,6 +68,26 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { } } +/// Adjust the span from the block, to the last expression of the +/// block. This is a better span when returning a mutable reference +/// with too short a lifetime. The error message will use the span +/// from the assignment to the return place, which should only point +/// at the returned value, not the entire function body. +/// +/// fn return_short_lived<'a>(x: &'a mut i32) -> &'static mut i32 { +/// x +/// // ^ error message points at this expression. +/// } +fn adjust_span<'tcx>(expr: &mut Expr<'tcx>) -> Span { + if let ExprKind::Block { body } = expr.kind { + if let Some(ref last_expr) = body.expr { + expr.span = last_expr.span; + } + } + + expr.span +} + fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir_expr: &'tcx hir::Expr, mut expr: Expr<'tcx>, @@ -76,12 +96,7 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let Expr { temp_lifetime, mut span, .. } = expr; let kind = match adjustment.kind { Adjust::Pointer(PointerCast::Unsize) => { - if let ExprKind::Block { body } = expr.kind { - if let Some(ref last_expr) = body.expr { - span = last_expr.span; - expr.span = span; - } - } + span = adjust_span(&mut expr); ExprKind::Pointer { cast: PointerCast::Unsize, source: expr.to_ref() } } Adjust::Pointer(cast) => { @@ -91,28 +106,12 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ExprKind::NeverToAny { source: expr.to_ref() } } Adjust::Deref(None) => { - // Adjust the span from the block, to the last expression of the - // block. This is a better span when returning a mutable reference - // with too short a lifetime. The error message will use the span - // from the assignment to the return place, which should only point - // at the returned value, not the entire function body. - // - // fn return_short_lived<'a>(x: &'a mut i32) -> &'static mut i32 { - // x - // // ^ error message points at this expression. - // } - // - // We don't need to do this adjustment in the next match arm since - // deref coercions always start with a built-in deref. - if let ExprKind::Block { body } = expr.kind { - if let Some(ref last_expr) = body.expr { - span = last_expr.span; - expr.span = span; - } - } + span = adjust_span(&mut expr); ExprKind::Deref { arg: expr.to_ref() } } Adjust::Deref(Some(deref)) => { + // We don't need to do call adjust_span here since + // deref coercions always start with a built-in deref. let call = deref.method_call(cx.tcx(), expr.ty); expr = Expr {