From 6ccb8447e78ed5cbeffdcbd962ad61e3ad7b5696 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 7 Apr 2024 10:38:57 +0000 Subject: [PATCH] Make "remove semicolon" suggestion work with `!` --- .../src/infer/error_reporting/suggest.rs | 1 + tests/ui/editions/diverging-block.e2024.fixed | 31 +++++++++++++++++++ .../ui/editions/diverging-block.e2024.stderr | 10 ++++-- tests/ui/editions/diverging-block.rs | 4 +++ 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 tests/ui/editions/diverging-block.e2024.fixed diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 9a05fb1c30f8e..85b495982d92b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -714,6 +714,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let last_expr_ty = self.typeck_results.as_ref()?.expr_ty_opt(last_expr)?; let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) { _ if last_expr_ty.references_error() => return None, + (ty::Never, _) => StatementAsExpression::CorrectType, _ if self.same_type_modulo_infer(last_expr_ty, expected_ty) => { StatementAsExpression::CorrectType } diff --git a/tests/ui/editions/diverging-block.e2024.fixed b/tests/ui/editions/diverging-block.e2024.fixed new file mode 100644 index 0000000000000..2f184fb4ee7cf --- /dev/null +++ b/tests/ui/editions/diverging-block.e2024.fixed @@ -0,0 +1,31 @@ +//@ revisions: e2021 e2024 +// +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +// +//@[e2021] check-pass +//@[e2024] check-fail +// +//@[e2024] run-rustfix +#![crate_name = "diverging_block"] // or else rustfix dies because of dots in the crate name + + +fn main() { + // a diverging block, with no tail expression. + // + // edition <= 2021: the block has type `!`, which then can be coerced. + // edition >= 2024: the block has type `()`, as with any block with no tail. + let _: u32 = { //[e2024]~ error: mismatched types + return + }; +} + +fn _f() { + // Same as the above, but with an if + if true { + return + } else { + 0_u32 //[e2024]~ error: `if` and `else` have incompatible types + }; +} diff --git a/tests/ui/editions/diverging-block.e2024.stderr b/tests/ui/editions/diverging-block.e2024.stderr index 2ed73f4ccabfe..bd65d83a9d525 100644 --- a/tests/ui/editions/diverging-block.e2024.stderr +++ b/tests/ui/editions/diverging-block.e2024.stderr @@ -1,18 +1,22 @@ error[E0308]: mismatched types - --> $DIR/diverging-block.rs:15:18 + --> $DIR/diverging-block.rs:19:18 | LL | let _: u32 = { | __________________^ LL | | return; + | | - help: remove this semicolon to return this value LL | | }; | |_____^ expected `u32`, found `()` error[E0308]: `if` and `else` have incompatible types - --> $DIR/diverging-block.rs:25:9 + --> $DIR/diverging-block.rs:29:9 | LL | / if true { LL | | return; - | | ------- expected because of this + | | ------- + | | | | + | | | help: consider removing this semicolon + | | expected because of this LL | | } else { LL | | 0_u32 | | ^^^^^ expected `()`, found `u32` diff --git a/tests/ui/editions/diverging-block.rs b/tests/ui/editions/diverging-block.rs index 6b12a5d2ff643..525f26efb20cc 100644 --- a/tests/ui/editions/diverging-block.rs +++ b/tests/ui/editions/diverging-block.rs @@ -6,6 +6,10 @@ // //@[e2021] check-pass //@[e2024] check-fail +// +//@[e2024] run-rustfix +#![crate_name = "diverging_block"] // or else rustfix dies because of dots in the crate name + fn main() { // a diverging block, with no tail expression.