@@ -3687,6 +3687,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3687
3687
}
3688
3688
}
3689
3689
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
+
3690
3724
fn check_block_with_expected (
3691
3725
& self ,
3692
3726
blk : & ' tcx hir:: Block ,
@@ -3746,12 +3780,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3746
3780
let coerce = ctxt. coerce . as_mut ( ) . unwrap ( ) ;
3747
3781
if let Some ( tail_expr_ty) = tail_expr_ty {
3748
3782
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) ;
3755
3786
} else {
3756
3787
// Subtle: if there is no explicit tail expression,
3757
3788
// that is typically equivalent to a tail expression
0 commit comments