Auto merge of #139594 - compiler-errors:if-cause, r= · rust-lang/rust@a62fc50 (original) (raw)

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;

`

`@@ -412,89 +412,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

`

412

412

``

413

413

`pub(crate) fn if_cause(

`

414

414

`&self,

`

415

``

`-

span: Span,

`

416

``

`-

cond_span: Span,

`

``

415

`+

expr_id: HirId,

`

417

416

`then_expr: &'tcx hir::Expr<'tcx>,

`

418

417

`else_expr: &'tcx hir::Expr<'tcx>,

`

419

418

`then_ty: Ty<'tcx>,

`

420

419

`else_ty: Ty<'tcx>,

`

421

420

`tail_defines_return_position_impl_trait: Option,

`

422

421

`) -> ObligationCause<'tcx> {

`

423

``

`-

let mut outer_span = if self.tcx.sess.source_map().is_multiline(span) {

`

424

``

`` -

// The if/else isn't in one line in the output, include some context to make it

``

425

``

`-

// clear it is an if/else expression:

`

426

``


// ```

427

``

`-

// LL | let x = if true {

`

428

``

`-

// | _____________-

`

429

``

`-

// LL || 10i32

`

430

``

`-

// || ----- expected because of this

`

431

``

`-

// LL || } else {

`

432

``

`-

// LL || 10u32

`

433

``

`` -

// || ^^^^^ expected i32, found u32

``

434

``

`-

// LL || };

`

435

``

`` -

// ||_____- if and else have incompatible types

``

436

``


// ```

437

``

`-

Some(span)

`

438

``

`-

} else {

`

439

``

`-

// The entire expression is in one line, only point at the arms

`

440

``


// ```

441

``

`-

// LL | let x = if true { 10i32 } else { 10u32 };

`

442

``

`` -

// | ----- ^^^^^ expected i32, found u32

``

443

``

`-

// | |

`

444

``

`-

// | expected because of this

`

445

``


// ```

446

``

`-

None

`

447

``

`-

};

`

448

``

-

449

422

`let (error_sp, else_id) = if let ExprKind::Block(block, _) = &else_expr.kind {

`

450

423

`let block = block.innermost_block();

`

451

``

-

452

``

`-

// Avoid overlapping spans that aren't as readable:

`

453

``


// ```

454

``

`-

// 2 | let x = if true {

`

455

``

`-

// | _____________-

`

456

``

`-

// 3 | | 3

`

457

``

`-

// | | - expected because of this

`

458

``

`-

// 4 | | } else {

`

459

``

`-

// | |____________^

`

460

``

`-

// 5 | ||

`

461

``

`-

// 6 | || };

`

462

``

`-

// | || ^

`

463

``

`-

// | ||_____|

`

464

``

`-

// | |______if and else have incompatible types

`

465

``

`` -

// | expected integer, found ()

``

466

``


// ```

467

``

`-

// by not pointing at the entire expression:

`

468

``


// ```

469

``

`-

// 2 | let x = if true {

`

470

``

`` -

// | ------- if and else have incompatible types

``

471

``

`-

// 3 | 3

`

472

``

`-

// | - expected because of this

`

473

``

`-

// 4 | } else {

`

474

``

`-

// | ____________^

`

475

``

`-

// 5 | |

`

476

``

`-

// 6 | | };

`

477

``

`` -

// | |_____^ expected integer, found ()

``

478

``


// ```

479

``

`-

if block.expr.is_none()

`

480

``

`-

&& block.stmts.is_empty()

`

481

``

`-

&& let Some(outer_span) = &mut outer_span

`

482

``

`-

&& let Some(cond_span) = cond_span.find_ancestor_inside(*outer_span)

`

483

``

`-

{

`

484

``

`-

*outer_span = outer_span.with_hi(cond_span.hi())

`

485

``

`-

}

`

486

``

-

487

424

`(self.find_block_span(block), block.hir_id)

`

488

425

`} else {

`

489

426

`(else_expr.span, else_expr.hir_id)

`

490

427

`};

`

491

428

``

492

429

`let then_id = if let ExprKind::Block(block, _) = &then_expr.kind {

`

493

430

`let block = block.innermost_block();

`

494

``

`-

// Exclude overlapping spans

`

495

``

`-

if block.expr.is_none() && block.stmts.is_empty() {

`

496

``

`-

outer_span = None;

`

497

``

`-

}

`

498

431

` block.hir_id

`

499

432

`} else {

`

500

433

` then_expr.hir_id

`

`@@ -504,11 +437,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

`

504

437

`self.cause(

`

505

438

` error_sp,

`

506

439

`ObligationCauseCode::IfExpression(Box::new(IfExpressionCause {

`

``

440

`+

expr_id,

`

507

441

` else_id,

`

508

442

` then_id,

`

509

443

` then_ty,

`

510

444

` else_ty,

`

511

``

`-

outer_span,

`

512

445

` tail_defines_return_position_impl_trait,

`

513

446

`})),

`

514

447

`)

`