about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-09-24 14:29:56 +0200
committerGitHub <noreply@github.com>2022-09-24 14:29:56 +0200
commit81eb35f18a4d305ab88fd020c88b0113a5747f0e (patch)
treee8ce5ee8a6bd3ac47398784925e207f5aa18af3d
parent5fb41a60319ad34628b270ff8f9973b73f25b3df (diff)
parentac06d9cca369b164ab522eba81d6b048309f058a (diff)
downloadrust-81eb35f18a4d305ab88fd020c88b0113a5747f0e.tar.gz
rust-81eb35f18a4d305ab88fd020c88b0113a5747f0e.zip
Rollup merge of #102210 - notriddle:notriddle/did-you-mean, r=cjgillot
diagnostics: avoid syntactically invalid suggestion in if conditionals

Fixes #101065
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs10
-rw-r--r--src/test/ui/suggestions/issue-101065.fixed14
-rw-r--r--src/test/ui/suggestions/issue-101065.rs14
-rw-r--r--src/test/ui/suggestions/issue-101065.stderr23
4 files changed, 61 insertions, 0 deletions
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index e1d55ff82cb..2c07c333a6f 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -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()),
diff --git a/src/test/ui/suggestions/issue-101065.fixed b/src/test/ui/suggestions/issue-101065.fixed
new file mode 100644
index 00000000000..88c716cc86c
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101065.fixed
@@ -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
+    };
+}
diff --git a/src/test/ui/suggestions/issue-101065.rs b/src/test/ui/suggestions/issue-101065.rs
new file mode 100644
index 00000000000..2715f102708
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101065.rs
@@ -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
+    };
+}
diff --git a/src/test/ui/suggestions/issue-101065.stderr b/src/test/ui/suggestions/issue-101065.stderr
new file mode 100644
index 00000000000..6f7ecd24ca4
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101065.stderr
@@ -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`.