Skip to content

Commit

Permalink
diagnostics: avoid syntactically invalid suggestion in if conditionals
Browse files Browse the repository at this point in the history
Fixes #101065
  • Loading branch information
notriddle committed Sep 23, 2022
1 parent 4a14677 commit ac06d9c
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
10 changes: 10 additions & 0 deletions compiler/rustc_typeck/src/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::def::CtorKind::Const => unreachable!(),
};

// Suggest constructor as deep into the block tree as possible.
// This fixes https://github.com/rust-lang/rust/issues/101065,
// and also just helps make the most minimal suggestions.
let mut expr = expr;
while let hir::ExprKind::Block(block, _) = &expr.kind
&& let Some(expr_) = &block.expr
{
expr = expr_
}

vec![
(expr.span.shrink_to_lo(), format!("{prefix}{variant}{open}")),
(expr.span.shrink_to_hi(), close.to_owned()),
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/suggestions/issue-101065.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// check-fail
// run-rustfix

enum FakeResult<T> {
Ok(T)
}

fn main() {
let _x = if true {
FakeResult::Ok(FakeResult::Ok(()))
} else {
FakeResult::Ok(FakeResult::Ok(())) //~ERROR E0308
};
}
14 changes: 14 additions & 0 deletions src/test/ui/suggestions/issue-101065.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// check-fail
// run-rustfix

enum FakeResult<T> {
Ok(T)
}

fn main() {
let _x = if true {
FakeResult::Ok(FakeResult::Ok(()))
} else {
FakeResult::Ok(()) //~ERROR E0308
};
}
23 changes: 23 additions & 0 deletions src/test/ui/suggestions/issue-101065.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0308]: `if` and `else` have incompatible types
--> $DIR/issue-101065.rs:12:9
|
LL | let _x = if true {
| ______________-
LL | | FakeResult::Ok(FakeResult::Ok(()))
| | ---------------------------------- expected because of this
LL | | } else {
LL | | FakeResult::Ok(())
| | ^^^^^^^^^^^^^^^^^^ expected enum `FakeResult`, found `()`
LL | | };
| |_____- `if` and `else` have incompatible types
|
= note: expected enum `FakeResult<FakeResult<()>>`
found enum `FakeResult<()>`
help: try wrapping the expression in `FakeResult::Ok`
|
LL | FakeResult::Ok(FakeResult::Ok(()))
| +++++++++++++++ +

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

0 comments on commit ac06d9c

Please sign in to comment.