about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-06-11 00:19:56 +0000
committerMichael Goulet <michael@errs.io>2023-06-11 00:19:56 +0000
commitd80440263c3eb083a91335ab14bee76bcb9988d1 (patch)
tree5d53d8120775a6cbdd4339e29911504f9b220779
parent5dfc17f045aca52ad37a768d0f6704ea5b4fd4dd (diff)
downloadrust-d80440263c3eb083a91335ab14bee76bcb9988d1.tar.gz
rust-d80440263c3eb083a91335ab14bee76bcb9988d1.zip
Don't suggest boxing an empty if/else arm
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs20
-rw-r--r--tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.rs9
-rw-r--r--tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.stderr16
3 files changed, 44 insertions, 1 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index ce5b5882e3b..3e4812e7ca9 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -847,7 +847,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 ) {
                     err.subdiagnostic(subdiag);
                 }
-                if let Some(ret_sp) = opt_suggest_box_span {
+                // don't suggest wrapping either blocks in `if .. {} else {}`
+                let is_empty_arm = |id| {
+                    let hir::Node::Block(blk) = self.tcx.hir().get(id)
+                    else {
+                        return false;
+                    };
+                    if blk.expr.is_some() || !blk.stmts.is_empty() {
+                        return false;
+                    }
+                    let Some((_, hir::Node::Expr(expr))) = self.tcx.hir().parent_iter(id).nth(1)
+                    else {
+                        return false;
+                    };
+                    matches!(expr.kind, hir::ExprKind::If(..))
+                };
+                if let Some(ret_sp) = opt_suggest_box_span
+                    && !is_empty_arm(then_id)
+                    && !is_empty_arm(else_id)
+                {
                     self.suggest_boxing_for_return_impl_trait(
                         err,
                         ret_sp,
diff --git a/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.rs b/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.rs
new file mode 100644
index 00000000000..befd768b181
--- /dev/null
+++ b/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.rs
@@ -0,0 +1,9 @@
+fn test() -> impl std::fmt::Debug {
+    if true {
+        "boo2"
+    } else {
+        //~^ ERROR `if` and `else` have incompatible types
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.stderr b/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.stderr
new file mode 100644
index 00000000000..9b63911da7a
--- /dev/null
+++ b/tests/ui/impl-trait/dont-suggest-box-on-empty-else-arm.stderr
@@ -0,0 +1,16 @@
+error[E0308]: `if` and `else` have incompatible types
+  --> $DIR/dont-suggest-box-on-empty-else-arm.rs:4:12
+   |
+LL |       if true {
+   |       ------- `if` and `else` have incompatible types
+LL |           "boo2"
+   |           ------ expected because of this
+LL |       } else {
+   |  ____________^
+LL | |
+LL | |     }
+   | |_____^ expected `&str`, found `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.