@@ -3687,6 +3687,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
36873687 }
36883688 }
36893689
3690+ /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
3691+ /// expression's `Span`, otherwise return `expr.span`. This is done to give bettern errors
3692+ /// when given code like the following:
3693+ /// ```text
3694+ /// if false { return 0i32; } else { 1u32 }
3695+ /// // ^^^^ point at this instead of the whole `if` expression
3696+ /// ```
3697+ fn get_expr_coercion_span ( & self , expr : & hir:: Expr ) -> syntax_pos:: Span {
3698+ if let hir:: ExprKind :: Match ( _, arms, _) = & expr. node {
3699+ let arm_spans: Vec < Span > = arms. iter ( ) . filter_map ( |arm| {
3700+ self . in_progress_tables
3701+ . and_then ( |tables| tables. borrow ( ) . node_type_opt ( arm. body . hir_id ) )
3702+ . and_then ( |arm_ty| {
3703+ if arm_ty. is_never ( ) {
3704+ None
3705+ } else {
3706+ Some ( match & arm. body . node {
3707+ // Point at the tail expression when possible.
3708+ hir:: ExprKind :: Block ( block, _) => block. expr
3709+ . as_ref ( )
3710+ . map ( |e| e. span )
3711+ . unwrap_or ( block. span ) ,
3712+ _ => arm. body . span ,
3713+ } )
3714+ }
3715+ } )
3716+ } ) . collect ( ) ;
3717+ if arm_spans. len ( ) == 1 {
3718+ return arm_spans[ 0 ] ;
3719+ }
3720+ }
3721+ expr. span
3722+ }
3723+
36903724 fn check_block_with_expected (
36913725 & self ,
36923726 blk : & ' tcx hir:: Block ,
@@ -3746,12 +3780,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
37463780 let coerce = ctxt. coerce . as_mut ( ) . unwrap ( ) ;
37473781 if let Some ( tail_expr_ty) = tail_expr_ty {
37483782 let tail_expr = tail_expr. unwrap ( ) ;
3749- let cause = self . cause ( tail_expr. span ,
3750- ObligationCauseCode :: BlockTailExpression ( blk. hir_id ) ) ;
3751- coerce. coerce ( self ,
3752- & cause,
3753- tail_expr,
3754- tail_expr_ty) ;
3783+ let span = self . get_expr_coercion_span ( tail_expr) ;
3784+ let cause = self . cause ( span, ObligationCauseCode :: BlockTailExpression ( blk. hir_id ) ) ;
3785+ coerce. coerce ( self , & cause, tail_expr, tail_expr_ty) ;
37553786 } else {
37563787 // Subtle: if there is no explicit tail expression,
37573788 // that is typically equivalent to a tail expression
0 commit comments