|  | 
| 1 | 1 | use rustc_errors::{Applicability, Diag}; | 
| 2 | 2 | use rustc_hir::def::{CtorOf, DefKind, Res}; | 
| 3 | 3 | use rustc_hir::def_id::LocalDefId; | 
| 4 |  | -use rustc_hir::{self as hir, ExprKind, PatKind}; | 
|  | 4 | +use rustc_hir::{self as hir, ExprKind, HirId, PatKind}; | 
| 5 | 5 | use rustc_hir_pretty::ty_to_string; | 
| 6 | 6 | use rustc_middle::ty::{self, Ty}; | 
| 7 | 7 | use rustc_span::Span; | 
| 8 | 8 | use rustc_trait_selection::traits::{ | 
| 9 |  | -    IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, | 
|  | 9 | +    MatchExpressionArmCause, ObligationCause, ObligationCauseCode, | 
| 10 | 10 | }; | 
| 11 | 11 | use tracing::{debug, instrument}; | 
| 12 | 12 | 
 | 
| @@ -414,105 +414,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | 
| 414 | 414 | 
 | 
| 415 | 415 |     pub(crate) fn if_cause( | 
| 416 | 416 |         &self, | 
| 417 |  | -        span: Span, | 
| 418 |  | -        cond_span: Span, | 
| 419 |  | -        then_expr: &'tcx hir::Expr<'tcx>, | 
|  | 417 | +        expr_id: HirId, | 
| 420 | 418 |         else_expr: &'tcx hir::Expr<'tcx>, | 
| 421 |  | -        then_ty: Ty<'tcx>, | 
| 422 |  | -        else_ty: Ty<'tcx>, | 
| 423 | 419 |         tail_defines_return_position_impl_trait: Option<LocalDefId>, | 
| 424 | 420 |     ) -> ObligationCause<'tcx> { | 
| 425 |  | -        let mut outer_span = if self.tcx.sess.source_map().is_multiline(span) { | 
| 426 |  | -            // The `if`/`else` isn't in one line in the output, include some context to make it | 
| 427 |  | -            // clear it is an if/else expression: | 
| 428 |  | -            // ``` | 
| 429 |  | -            // LL |      let x = if true { | 
| 430 |  | -            //    | _____________- | 
| 431 |  | -            // LL ||         10i32 | 
| 432 |  | -            //    ||         ----- expected because of this | 
| 433 |  | -            // LL ||     } else { | 
| 434 |  | -            // LL ||         10u32 | 
| 435 |  | -            //    ||         ^^^^^ expected `i32`, found `u32` | 
| 436 |  | -            // LL ||     }; | 
| 437 |  | -            //    ||_____- `if` and `else` have incompatible types | 
| 438 |  | -            // ``` | 
| 439 |  | -            Some(span) | 
| 440 |  | -        } else { | 
| 441 |  | -            // The entire expression is in one line, only point at the arms | 
| 442 |  | -            // ``` | 
| 443 |  | -            // LL |     let x = if true { 10i32 } else { 10u32 }; | 
| 444 |  | -            //    |                       -----          ^^^^^ expected `i32`, found `u32` | 
| 445 |  | -            //    |                       | | 
| 446 |  | -            //    |                       expected because of this | 
| 447 |  | -            // ``` | 
| 448 |  | -            None | 
| 449 |  | -        }; | 
| 450 |  | - | 
| 451 |  | -        let (error_sp, else_id) = if let ExprKind::Block(block, _) = &else_expr.kind { | 
| 452 |  | -            let block = block.innermost_block(); | 
| 453 |  | - | 
| 454 |  | -            // Avoid overlapping spans that aren't as readable: | 
| 455 |  | -            // ``` | 
| 456 |  | -            // 2 |        let x = if true { | 
| 457 |  | -            //   |   _____________- | 
| 458 |  | -            // 3 |  |         3 | 
| 459 |  | -            //   |  |         - expected because of this | 
| 460 |  | -            // 4 |  |     } else { | 
| 461 |  | -            //   |  |____________^ | 
| 462 |  | -            // 5 | || | 
| 463 |  | -            // 6 | ||     }; | 
| 464 |  | -            //   | ||     ^ | 
| 465 |  | -            //   | ||_____| | 
| 466 |  | -            //   | |______if and else have incompatible types | 
| 467 |  | -            //   |        expected integer, found `()` | 
| 468 |  | -            // ``` | 
| 469 |  | -            // by not pointing at the entire expression: | 
| 470 |  | -            // ``` | 
| 471 |  | -            // 2 |       let x = if true { | 
| 472 |  | -            //   |               ------- `if` and `else` have incompatible types | 
| 473 |  | -            // 3 |           3 | 
| 474 |  | -            //   |           - expected because of this | 
| 475 |  | -            // 4 |       } else { | 
| 476 |  | -            //   |  ____________^ | 
| 477 |  | -            // 5 | | | 
| 478 |  | -            // 6 | |     }; | 
| 479 |  | -            //   | |_____^ expected integer, found `()` | 
| 480 |  | -            // ``` | 
| 481 |  | -            if block.expr.is_none() | 
| 482 |  | -                && block.stmts.is_empty() | 
| 483 |  | -                && let Some(outer_span) = &mut outer_span | 
| 484 |  | -                && let Some(cond_span) = cond_span.find_ancestor_inside(*outer_span) | 
| 485 |  | -            { | 
| 486 |  | -                *outer_span = outer_span.with_hi(cond_span.hi()) | 
| 487 |  | -            } | 
| 488 |  | - | 
| 489 |  | -            (self.find_block_span(block), block.hir_id) | 
| 490 |  | -        } else { | 
| 491 |  | -            (else_expr.span, else_expr.hir_id) | 
| 492 |  | -        }; | 
| 493 |  | - | 
| 494 |  | -        let then_id = if let ExprKind::Block(block, _) = &then_expr.kind { | 
| 495 |  | -            let block = block.innermost_block(); | 
| 496 |  | -            // Exclude overlapping spans | 
| 497 |  | -            if block.expr.is_none() && block.stmts.is_empty() { | 
| 498 |  | -                outer_span = None; | 
| 499 |  | -            } | 
| 500 |  | -            block.hir_id | 
| 501 |  | -        } else { | 
| 502 |  | -            then_expr.hir_id | 
| 503 |  | -        }; | 
|  | 421 | +        let error_sp = self.find_block_span_from_hir_id(else_expr.hir_id); | 
| 504 | 422 | 
 | 
| 505 | 423 |         // Finally construct the cause: | 
| 506 | 424 |         self.cause( | 
| 507 | 425 |             error_sp, | 
| 508 |  | -            ObligationCauseCode::IfExpression(Box::new(IfExpressionCause { | 
| 509 |  | -                else_id, | 
| 510 |  | -                then_id, | 
| 511 |  | -                then_ty, | 
| 512 |  | -                else_ty, | 
| 513 |  | -                outer_span, | 
| 514 |  | -                tail_defines_return_position_impl_trait, | 
| 515 |  | -            })), | 
|  | 426 | +            ObligationCauseCode::IfExpression { expr_id, tail_defines_return_position_impl_trait }, | 
| 516 | 427 |         ) | 
| 517 | 428 |     } | 
| 518 | 429 | 
 | 
|  | 
0 commit comments