Skip to content

Commit ac06d9c

Browse files
committed
diagnostics: avoid syntactically invalid suggestion in if conditionals
Fixes #101065
1 parent 4a14677 commit ac06d9c

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

compiler/rustc_typeck/src/check/demand.rs

+10
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
417417
hir::def::CtorKind::Const => unreachable!(),
418418
};
419419

420+
// Suggest constructor as deep into the block tree as possible.
421+
// This fixes https://github.com/rust-lang/rust/issues/101065,
422+
// and also just helps make the most minimal suggestions.
423+
let mut expr = expr;
424+
while let hir::ExprKind::Block(block, _) = &expr.kind
425+
&& let Some(expr_) = &block.expr
426+
{
427+
expr = expr_
428+
}
429+
420430
vec![
421431
(expr.span.shrink_to_lo(), format!("{prefix}{variant}{open}")),
422432
(expr.span.shrink_to_hi(), close.to_owned()),
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-fail
2+
// run-rustfix
3+
4+
enum FakeResult<T> {
5+
Ok(T)
6+
}
7+
8+
fn main() {
9+
let _x = if true {
10+
FakeResult::Ok(FakeResult::Ok(()))
11+
} else {
12+
FakeResult::Ok(FakeResult::Ok(())) //~ERROR E0308
13+
};
14+
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-fail
2+
// run-rustfix
3+
4+
enum FakeResult<T> {
5+
Ok(T)
6+
}
7+
8+
fn main() {
9+
let _x = if true {
10+
FakeResult::Ok(FakeResult::Ok(()))
11+
} else {
12+
FakeResult::Ok(()) //~ERROR E0308
13+
};
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0308]: `if` and `else` have incompatible types
2+
--> $DIR/issue-101065.rs:12:9
3+
|
4+
LL | let _x = if true {
5+
| ______________-
6+
LL | | FakeResult::Ok(FakeResult::Ok(()))
7+
| | ---------------------------------- expected because of this
8+
LL | | } else {
9+
LL | | FakeResult::Ok(())
10+
| | ^^^^^^^^^^^^^^^^^^ expected enum `FakeResult`, found `()`
11+
LL | | };
12+
| |_____- `if` and `else` have incompatible types
13+
|
14+
= note: expected enum `FakeResult<FakeResult<()>>`
15+
found enum `FakeResult<()>`
16+
help: try wrapping the expression in `FakeResult::Ok`
17+
|
18+
LL | FakeResult::Ok(FakeResult::Ok(()))
19+
| +++++++++++++++ +
20+
21+
error: aborting due to previous error
22+
23+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)