From 796ce9fcb7e35767e6e57ad79099dcf730a0a94b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 4 Feb 2021 12:22:01 -0800 Subject: [PATCH 1/5] Suggest `return`ing tail expressions that match return type Some newcomers are confused by the behavior of tail expressions, interpreting that "leaving out the `;` makes it the return value". To help them go in the right direction, suggest using `return` instead when applicable. --- compiler/rustc_typeck/src/check/coercion.rs | 12 +++++++- .../src/check/fn_ctxt/suggestions.rs | 28 +++++++++++++++++++ src/test/ui/macros/empty-trailing-stmt.stderr | 5 ++++ src/test/ui/parser/expr-as-stmt-2.stderr | 22 +++++++++++++-- src/test/ui/parser/expr-as-stmt.stderr | 20 +++++++++++++ .../return/tail-expr-as-potential-return.rs | 11 ++++++++ .../tail-expr-as-potential-return.stderr | 27 ++++++++++++++++++ 7 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/return/tail-expr-as-potential-return.rs create mode 100644 src/test/ui/return/tail-expr-as-potential-return.stderr diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index b2395b7bb2502..f95627cfdee83 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1458,7 +1458,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx.get_fn_decl(parent_id) }; - if let (Some((fn_decl, can_suggest)), _) = (fn_decl, pointing_at_return_type) { + if let Some((fn_decl, can_suggest)) = fn_decl { if expression.is_none() { pointing_at_return_type |= fcx.suggest_missing_return_type( &mut err, @@ -1472,6 +1472,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fn_output = Some(&fn_decl.output); // `impl Trait` return type } } + + let parent_id = fcx.tcx.hir().get_parent_item(id); + let parent_item = fcx.tcx.hir().get(parent_id); + + if let (Some((expr, _)), Some((fn_decl, _, _))) = + (expression, fcx.get_node_fn_decl(parent_item)) + { + fcx.suggest_missing_return_expr(&mut err, expr, fn_decl, expected, found); + } + if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) { self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output); } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index a0465ca6aef07..9d816e76c0020 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -464,6 +464,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + pub(in super::super) fn suggest_missing_return_expr( + &self, + err: &mut DiagnosticBuilder<'_>, + expr: &'tcx hir::Expr<'tcx>, + fn_decl: &hir::FnDecl<'_>, + expected: Ty<'tcx>, + found: Ty<'tcx>, + ) { + if !expected.is_unit() { + return; + } + let found = self.resolve_vars_with_obligations(found); + if let hir::FnRetTy::Return(ty) = fn_decl.output { + let ty = AstConv::ast_ty_to_ty(self, ty); + let ty = self.normalize_associated_types_in(expr.span, ty); + if self.can_coerce(found, ty) { + err.multipart_suggestion( + "you might have meant to return this value", + vec![ + (expr.span.shrink_to_lo(), "return ".to_string()), + (expr.span.shrink_to_hi(), ";".to_string()), + ], + Applicability::MaybeIncorrect, + ); + } + } + } + pub(in super::super) fn suggest_missing_parentheses( &self, err: &mut DiagnosticBuilder<'_>, diff --git a/src/test/ui/macros/empty-trailing-stmt.stderr b/src/test/ui/macros/empty-trailing-stmt.stderr index e88b12712fb8c..1db759a2181d5 100644 --- a/src/test/ui/macros/empty-trailing-stmt.stderr +++ b/src/test/ui/macros/empty-trailing-stmt.stderr @@ -3,6 +3,11 @@ error[E0308]: mismatched types | LL | { true } | ^^^^ expected `()`, found `bool` + | +help: you might have meant to return this value + | +LL | { return true; } + | ^^^^^^ ^ error[E0308]: mismatched types --> $DIR/empty-trailing-stmt.rs:5:13 diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr index ee07c36763356..75c0e7bb47560 100644 --- a/src/test/ui/parser/expr-as-stmt-2.stderr +++ b/src/test/ui/parser/expr-as-stmt-2.stderr @@ -2,19 +2,37 @@ error[E0308]: mismatched types --> $DIR/expr-as-stmt-2.rs:3:26 | LL | if let Some(x) = a { true } else { false } - | ---------------------^^^^------------------ help: consider using a semicolon here + | ---------------------^^^^----------------- | | | | | expected `()`, found `bool` | expected this to be `()` + | +help: consider using a semicolon here + | +LL | if let Some(x) = a { true } else { false }; + | ^ +help: you might have meant to return this value + | +LL | if let Some(x) = a { return true; } else { false } + | ^^^^^^ ^ error[E0308]: mismatched types --> $DIR/expr-as-stmt-2.rs:3:40 | LL | if let Some(x) = a { true } else { false } - | -----------------------------------^^^^^--- help: consider using a semicolon here + | -----------------------------------^^^^^-- | | | | | expected `()`, found `bool` | expected this to be `()` + | +help: consider using a semicolon here + | +LL | if let Some(x) = a { true } else { false }; + | ^ +help: you might have meant to return this value + | +LL | if let Some(x) = a { true } else { return false; } + | ^^^^^^ ^ error[E0308]: mismatched types --> $DIR/expr-as-stmt-2.rs:6:5 diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr index 324aed0ad7cf6..09a6d7cbeb176 100644 --- a/src/test/ui/parser/expr-as-stmt.stderr +++ b/src/test/ui/parser/expr-as-stmt.stderr @@ -40,24 +40,44 @@ error[E0308]: mismatched types | LL | {2} + {2} | ^ expected `()`, found integer + | +help: you might have meant to return this value + | +LL | {return 2;} + {2} + | ^^^^^^ ^ error[E0308]: mismatched types --> $DIR/expr-as-stmt.rs:12:6 | LL | {2} + 2 | ^ expected `()`, found integer + | +help: you might have meant to return this value + | +LL | {return 2;} + 2 + | ^^^^^^ ^ error[E0308]: mismatched types --> $DIR/expr-as-stmt.rs:18:7 | LL | { 42 } + foo; | ^^ expected `()`, found integer + | +help: you might have meant to return this value + | +LL | { return 42; } + foo; + | ^^^^^^ ^ error[E0308]: mismatched types --> $DIR/expr-as-stmt.rs:24:7 | LL | { 3 } * 3 | ^ expected `()`, found integer + | +help: you might have meant to return this value + | +LL | { return 3; } * 3 + | ^^^^^^ ^ error[E0614]: type `{integer}` cannot be dereferenced --> $DIR/expr-as-stmt.rs:24:11 diff --git a/src/test/ui/return/tail-expr-as-potential-return.rs b/src/test/ui/return/tail-expr-as-potential-return.rs new file mode 100644 index 0000000000000..72798c720f3a1 --- /dev/null +++ b/src/test/ui/return/tail-expr-as-potential-return.rs @@ -0,0 +1,11 @@ +fn main() { + let _ = foo(true); +} + +fn foo(x: bool) -> Result { + if x { + Err(42) //~ ERROR mismatched types + } + Ok(42.0) +} + diff --git a/src/test/ui/return/tail-expr-as-potential-return.stderr b/src/test/ui/return/tail-expr-as-potential-return.stderr new file mode 100644 index 0000000000000..d079e0b080d10 --- /dev/null +++ b/src/test/ui/return/tail-expr-as-potential-return.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/tail-expr-as-potential-return.rs:7:9 + | +LL | / if x { +LL | | Err(42) + | | ^^^^^^^ expected `()`, found enum `std::result::Result` +LL | | } + | |_____- expected this to be `()` + | + = note: expected unit type `()` + found enum `std::result::Result<_, {integer}>` +help: try adding a semicolon + | +LL | Err(42); + | ^ +help: consider using a semicolon here + | +LL | }; + | ^ +help: you might have meant to return this value + | +LL | return Err(42); + | ^^^^^^ ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 020edd91a911cebf8aeada9f04dff047dc76171e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 4 Feb 2021 13:59:23 -0800 Subject: [PATCH 2/5] reword `;` suggestions to have consistent wording --- compiler/rustc_typeck/src/check/callee.rs | 2 +- compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs | 2 +- src/test/ui/async-await/suggest-missing-await.rs | 2 +- src/test/ui/async-await/suggest-missing-await.stderr | 2 +- src/test/ui/block-result/unexpected-return-on-unit.stderr | 2 +- src/test/ui/proc-macro/issue-37788.stderr | 2 +- src/test/ui/return/return-type.stderr | 2 +- src/test/ui/return/tail-expr-as-potential-return.stderr | 2 +- .../ui/specialization/specialization-default-projection.stderr | 2 +- .../issue-51055-missing-semicolon-between-call-and-tuple.stderr | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index 4836418b3c210..f2fbb95fc021c 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -346,7 +346,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if call_is_multiline { err.span_suggestion( callee.span.shrink_to_hi(), - "try adding a semicolon", + "consider using a semicolon here", ";".to_owned(), Applicability::MaybeIncorrect, ); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 9d816e76c0020..e5a2e1398178d 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -395,7 +395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ExprKind::Block(..) => { err.span_suggestion( cause_span.shrink_to_hi(), - "try adding a semicolon", + "consider using a semicolon here", ";".to_string(), Applicability::MachineApplicable, ); diff --git a/src/test/ui/async-await/suggest-missing-await.rs b/src/test/ui/async-await/suggest-missing-await.rs index d629054911dac..352a88ac10cd5 100644 --- a/src/test/ui/async-await/suggest-missing-await.rs +++ b/src/test/ui/async-await/suggest-missing-await.rs @@ -21,7 +21,7 @@ async fn dummy() {} async fn suggest_await_in_async_fn_return() { dummy() //~^ ERROR mismatched types [E0308] - //~| HELP try adding a semicolon + //~| HELP consider using a semicolon here //~| HELP consider `await`ing on the `Future` //~| SUGGESTION .await } diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 46615dae7e2ba..26e81a52c2141 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -29,7 +29,7 @@ help: consider `await`ing on the `Future` | LL | dummy().await | ^^^^^^ -help: try adding a semicolon +help: consider using a semicolon here | LL | dummy(); | ^ diff --git a/src/test/ui/block-result/unexpected-return-on-unit.stderr b/src/test/ui/block-result/unexpected-return-on-unit.stderr index 3dce459ddbdae..4fcd0ee2c48e2 100644 --- a/src/test/ui/block-result/unexpected-return-on-unit.stderr +++ b/src/test/ui/block-result/unexpected-return-on-unit.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | foo() | ^^^^^ expected `()`, found `usize` | -help: try adding a semicolon +help: consider using a semicolon here | LL | foo(); | ^ diff --git a/src/test/ui/proc-macro/issue-37788.stderr b/src/test/ui/proc-macro/issue-37788.stderr index 0538701290297..345520d4852ae 100644 --- a/src/test/ui/proc-macro/issue-37788.stderr +++ b/src/test/ui/proc-macro/issue-37788.stderr @@ -5,7 +5,7 @@ LL | fn main() { | - expected `()` because of default return type LL | // Test that constructing the `visible_parent_map` (in `cstore_impl.rs`) does not ICE. LL | std::cell::Cell::new(0) - | ^^^^^^^^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;` + | ^^^^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;` | | | expected `()`, found struct `Cell` | diff --git a/src/test/ui/return/return-type.stderr b/src/test/ui/return/return-type.stderr index 535428f1c91f7..6ef921bef3d7a 100644 --- a/src/test/ui/return/return-type.stderr +++ b/src/test/ui/return/return-type.stderr @@ -6,7 +6,7 @@ LL | foo(4 as usize) | = note: expected unit type `()` found struct `S` -help: try adding a semicolon +help: consider using a semicolon here | LL | foo(4 as usize); | ^ diff --git a/src/test/ui/return/tail-expr-as-potential-return.stderr b/src/test/ui/return/tail-expr-as-potential-return.stderr index d079e0b080d10..6eeaf5b3412e7 100644 --- a/src/test/ui/return/tail-expr-as-potential-return.stderr +++ b/src/test/ui/return/tail-expr-as-potential-return.stderr @@ -9,7 +9,7 @@ LL | | } | = note: expected unit type `()` found enum `std::result::Result<_, {integer}>` -help: try adding a semicolon +help: consider using a semicolon here | LL | Err(42); | ^ diff --git a/src/test/ui/specialization/specialization-default-projection.stderr b/src/test/ui/specialization/specialization-default-projection.stderr index 445bc1646f04e..7a2b75a1c1f0a 100644 --- a/src/test/ui/specialization/specialization-default-projection.stderr +++ b/src/test/ui/specialization/specialization-default-projection.stderr @@ -29,7 +29,7 @@ LL | fn monomorphic() -> () { | -- expected `()` because of return type ... LL | generic::<()>() - | ^^^^^^^^^^^^^^^- help: try adding a semicolon: `;` + | ^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;` | | | expected `()`, found associated type | diff --git a/src/test/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.stderr b/src/test/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.stderr index 6e4cee18c1603..438075083d370 100644 --- a/src/test/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.stderr +++ b/src/test/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.stderr @@ -5,7 +5,7 @@ LL | fn vindictive() -> bool { true } | ----------------------- `vindictive` defined here returns `bool` ... LL | vindictive() - | -^^^^^^^^^^^- help: try adding a semicolon: `;` + | -^^^^^^^^^^^- help: consider using a semicolon here: `;` | _____| | | LL | | (1, 2) From d669882f386e26d214284fbe8f7696519b802778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 4 Feb 2021 17:36:06 -0800 Subject: [PATCH 3/5] Do not suggest `;` if expression is side effect free When a tail expression isn't unit, we previously always suggested adding a trailing `;` to turn it into a statement. This suggestion isn't appropriate for any expression that doesn't have side-effects, as the user will have likely wanted to call something else or do something with the resulting value, instead of just discarding it. --- compiler/rustc_hir/src/hir.rs | 58 +++++++++++++++++++ compiler/rustc_typeck/src/check/coercion.rs | 4 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 4 +- .../src/check/fn_ctxt/suggestions.rs | 9 ++- .../block-must-not-have-result-while.stderr | 4 +- src/test/ui/parser/expr-as-stmt-2.stderr | 8 --- .../struct-literal-variant-in-if.stderr | 2 +- .../tail-expr-as-potential-return.stderr | 8 --- .../ui/suggestions/match-needing-semi.fixed | 18 ------ src/test/ui/suggestions/match-needing-semi.rs | 7 ++- .../ui/suggestions/match-needing-semi.stderr | 21 ++++--- 11 files changed, 92 insertions(+), 51 deletions(-) delete mode 100644 src/test/ui/suggestions/match-needing-semi.fixed diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4df8c44e62b38..840099841839a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,5 +1,6 @@ // ignore-tidy-filelength use crate::def::{DefKind, Namespace, Res}; +use crate::def::{CtorKind, DefKind, Namespace, Res}; use crate::def_id::DefId; crate use crate::hir_id::HirId; use crate::{itemlikevisit, LangItem}; @@ -1554,6 +1555,63 @@ impl Expr<'_> { } expr } + + pub fn can_have_side_effects(&self) -> bool { + match self.peel_drop_temps().kind { + ExprKind::Path(_) | ExprKind::Lit(_) => false, + ExprKind::Type(base, _) + | ExprKind::Unary(_, base) + | ExprKind::Field(base, _) + | ExprKind::Index(base, _) + | ExprKind::AddrOf(.., base) + | ExprKind::Cast(base, _) => { + // This isn't exactly true for `Index` and all `Unnary`, but we are using this + // method exclusively for diagnostics and there's a *cultural* pressure against + // them being used only for its side-effects. + base.can_have_side_effects() + } + ExprKind::Struct(_, fields, init) => fields + .iter() + .map(|field| field.expr) + .chain(init.into_iter()) + .all(|e| e.can_have_side_effects()), + + ExprKind::Array(args) + | ExprKind::Tup(args) + | ExprKind::Call( + Expr { + kind: + ExprKind::Path(QPath::Resolved( + None, + Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. }, + )), + .. + }, + args, + ) => args.iter().all(|arg| arg.can_have_side_effects()), + ExprKind::If(..) + | ExprKind::Match(..) + | ExprKind::MethodCall(..) + | ExprKind::Call(..) + | ExprKind::Closure(..) + | ExprKind::Block(..) + | ExprKind::Repeat(..) + | ExprKind::Break(..) + | ExprKind::Continue(..) + | ExprKind::Ret(..) + | ExprKind::Loop(..) + | ExprKind::Assign(..) + | ExprKind::InlineAsm(..) + | ExprKind::LlvmInlineAsm(..) + | ExprKind::AssignOp(..) + | ExprKind::ConstBlock(..) + | ExprKind::Box(..) + | ExprKind::Binary(..) + | ExprKind::Yield(..) + | ExprKind::DropTemps(..) + | ExprKind::Err => true, + } + } } /// Checks if the specified expression is a built-in range literal. diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index f95627cfdee83..159c97d8bfaa9 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1450,7 +1450,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ) { if cond_expr.span.desugaring_kind().is_none() { err.span_label(cond_expr.span, "expected this to be `()`"); - fcx.suggest_semicolon_at_end(cond_expr.span, &mut err); + if expr.can_have_side_effects() { + fcx.suggest_semicolon_at_end(cond_expr.span, &mut err); + } } } fcx.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main)) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 3326be796cee3..155c10e891652 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -561,7 +561,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::StmtKind::Expr(ref expr) => { // Check with expected type of `()`. self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| { - self.suggest_semicolon_at_end(expr.span, err); + if expr.can_have_side_effects() { + self.suggest_semicolon_at_end(expr.span, err); + } }); } hir::StmtKind::Semi(ref expr) => { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index e5a2e1398178d..416b75d9e2e0c 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -44,11 +44,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { blk_id: hir::HirId, ) -> bool { let expr = expr.peel_drop_temps(); - self.suggest_missing_semicolon(err, expr, expected, cause_span); + if expr.can_have_side_effects() { + self.suggest_missing_semicolon(err, expr, expected, cause_span); + } let mut pointing_at_return_type = false; if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) { pointing_at_return_type = self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest); + self.suggest_missing_return_expr(err, expr, &fn_decl, expected, found); } pointing_at_return_type } @@ -392,7 +395,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ExprKind::Loop(..) | ExprKind::If(..) | ExprKind::Match(..) - | ExprKind::Block(..) => { + | ExprKind::Block(..) + if expression.can_have_side_effects() => + { err.span_suggestion( cause_span.shrink_to_hi(), "consider using a semicolon here", diff --git a/src/test/ui/block-result/block-must-not-have-result-while.stderr b/src/test/ui/block-result/block-must-not-have-result-while.stderr index d4845290d8a90..7f96aa289d0ab 100644 --- a/src/test/ui/block-result/block-must-not-have-result-while.stderr +++ b/src/test/ui/block-result/block-must-not-have-result-while.stderr @@ -14,9 +14,7 @@ LL | | true | | ^^^^ expected `()`, found `bool` LL | | LL | | } - | | -- help: consider using a semicolon here - | |_____| - | expected this to be `()` + | |_____- expected this to be `()` error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr index 75c0e7bb47560..2a70127485785 100644 --- a/src/test/ui/parser/expr-as-stmt-2.stderr +++ b/src/test/ui/parser/expr-as-stmt-2.stderr @@ -7,10 +7,6 @@ LL | if let Some(x) = a { true } else { false } | | expected `()`, found `bool` | expected this to be `()` | -help: consider using a semicolon here - | -LL | if let Some(x) = a { true } else { false }; - | ^ help: you might have meant to return this value | LL | if let Some(x) = a { return true; } else { false } @@ -25,10 +21,6 @@ LL | if let Some(x) = a { true } else { false } | | expected `()`, found `bool` | expected this to be `()` | -help: consider using a semicolon here - | -LL | if let Some(x) = a { true } else { false }; - | ^ help: you might have meant to return this value | LL | if let Some(x) = a { true } else { return false; } diff --git a/src/test/ui/parser/struct-literal-variant-in-if.stderr b/src/test/ui/parser/struct-literal-variant-in-if.stderr index a2252d4e4d282..3ea5ca565c5e5 100644 --- a/src/test/ui/parser/struct-literal-variant-in-if.stderr +++ b/src/test/ui/parser/struct-literal-variant-in-if.stderr @@ -57,7 +57,7 @@ error[E0308]: mismatched types --> $DIR/struct-literal-variant-in-if.rs:10:20 | LL | if x == E::V { field } {} - | ---------------^^^^^--- help: consider using a semicolon here + | ---------------^^^^^-- | | | | | expected `()`, found `bool` | expected this to be `()` diff --git a/src/test/ui/return/tail-expr-as-potential-return.stderr b/src/test/ui/return/tail-expr-as-potential-return.stderr index 6eeaf5b3412e7..52c63c8e223e4 100644 --- a/src/test/ui/return/tail-expr-as-potential-return.stderr +++ b/src/test/ui/return/tail-expr-as-potential-return.stderr @@ -9,14 +9,6 @@ LL | | } | = note: expected unit type `()` found enum `std::result::Result<_, {integer}>` -help: consider using a semicolon here - | -LL | Err(42); - | ^ -help: consider using a semicolon here - | -LL | }; - | ^ help: you might have meant to return this value | LL | return Err(42); diff --git a/src/test/ui/suggestions/match-needing-semi.fixed b/src/test/ui/suggestions/match-needing-semi.fixed deleted file mode 100644 index 03cbed1376ea3..0000000000000 --- a/src/test/ui/suggestions/match-needing-semi.fixed +++ /dev/null @@ -1,18 +0,0 @@ -// check-only -// run-rustfix - -fn main() { - match 3 { - 4 => 1, - 3 => { - 2 //~ ERROR mismatched types - } - _ => 2 - }; - match 3 { //~ ERROR mismatched types - 4 => 1, - 3 => 2, - _ => 2 - }; - let _ = (); -} diff --git a/src/test/ui/suggestions/match-needing-semi.rs b/src/test/ui/suggestions/match-needing-semi.rs index f34071ac75886..833555d0e406e 100644 --- a/src/test/ui/suggestions/match-needing-semi.rs +++ b/src/test/ui/suggestions/match-needing-semi.rs @@ -1,11 +1,10 @@ // check-only -// run-rustfix fn main() { match 3 { 4 => 1, 3 => { - 2 //~ ERROR mismatched types + foo() //~ ERROR mismatched types } _ => 2 } @@ -16,3 +15,7 @@ fn main() { } let _ = (); } + +fn foo() -> i32 { + 42 +} diff --git a/src/test/ui/suggestions/match-needing-semi.stderr b/src/test/ui/suggestions/match-needing-semi.stderr index 28abd089525df..3739c9940f0cc 100644 --- a/src/test/ui/suggestions/match-needing-semi.stderr +++ b/src/test/ui/suggestions/match-needing-semi.stderr @@ -1,20 +1,27 @@ error[E0308]: mismatched types - --> $DIR/match-needing-semi.rs:8:13 + --> $DIR/match-needing-semi.rs:7:13 | LL | / match 3 { LL | | 4 => 1, LL | | 3 => { -LL | | 2 - | | ^ expected `()`, found integer +LL | | foo() + | | ^^^^^ expected `()`, found `i32` LL | | } LL | | _ => 2 LL | | } - | | -- help: consider using a semicolon here - | |_____| - | expected this to be `()` + | |_____- expected this to be `()` + | +help: consider using a semicolon here + | +LL | foo(); + | ^ +help: consider using a semicolon here + | +LL | }; + | ^ error[E0308]: mismatched types - --> $DIR/match-needing-semi.rs:12:5 + --> $DIR/match-needing-semi.rs:11:5 | LL | / match 3 { LL | | 4 => 1, From 86b3f3f2b39726e489df7f550c92f32515cee56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 5 Feb 2021 11:34:55 -0800 Subject: [PATCH 4/5] tidy --- src/test/ui/return/tail-expr-as-potential-return.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/return/tail-expr-as-potential-return.rs b/src/test/ui/return/tail-expr-as-potential-return.rs index 72798c720f3a1..83266abfa06e6 100644 --- a/src/test/ui/return/tail-expr-as-potential-return.rs +++ b/src/test/ui/return/tail-expr-as-potential-return.rs @@ -8,4 +8,3 @@ fn foo(x: bool) -> Result { } Ok(42.0) } - From fc6c19e2dcbb3039a380755699669d317a6a3fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 21 Feb 2021 16:54:42 -0800 Subject: [PATCH 5/5] fix rebase --- compiler/rustc_hir/src/hir.rs | 3 +-- src/test/ui/return/tail-expr-as-potential-return.stderr | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 840099841839a..9b2077f0039bb 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,5 +1,4 @@ // ignore-tidy-filelength -use crate::def::{DefKind, Namespace, Res}; use crate::def::{CtorKind, DefKind, Namespace, Res}; use crate::def_id::DefId; crate use crate::hir_id::HirId; @@ -1562,7 +1561,7 @@ impl Expr<'_> { ExprKind::Type(base, _) | ExprKind::Unary(_, base) | ExprKind::Field(base, _) - | ExprKind::Index(base, _) + | ExprKind::Index(base, _) | ExprKind::AddrOf(.., base) | ExprKind::Cast(base, _) => { // This isn't exactly true for `Index` and all `Unnary`, but we are using this diff --git a/src/test/ui/return/tail-expr-as-potential-return.stderr b/src/test/ui/return/tail-expr-as-potential-return.stderr index 52c63c8e223e4..f8527961374dd 100644 --- a/src/test/ui/return/tail-expr-as-potential-return.stderr +++ b/src/test/ui/return/tail-expr-as-potential-return.stderr @@ -3,12 +3,12 @@ error[E0308]: mismatched types | LL | / if x { LL | | Err(42) - | | ^^^^^^^ expected `()`, found enum `std::result::Result` + | | ^^^^^^^ expected `()`, found enum `Result` LL | | } | |_____- expected this to be `()` | = note: expected unit type `()` - found enum `std::result::Result<_, {integer}>` + found enum `Result<_, {integer}>` help: you might have meant to return this value | LL | return Err(42);