From bdddaebd76cba207b67141e2c362a4fe117bbd34 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Fri, 11 Jun 2021 01:20:00 +0200 Subject: [PATCH 1/7] Fix type checking of return expressions outside fn bodies --- compiler/rustc_typeck/src/check/expr.rs | 34 ++++++++++- compiler/rustc_typeck/src/errors.rs | 4 ++ src/test/ui/issues/issue-51714.rs | 16 +++-- src/test/ui/issues/issue-51714.stderr | 60 +++++++++++++++---- .../issue-86188-return-not-in-fn-body.rs | 22 +++++++ .../issue-86188-return-not-in-fn-body.stderr | 28 +++++++++ .../ui/return/return-match-array-const.rs | 15 ++++- .../ui/return/return-match-array-const.stderr | 55 +++++++++++++---- 8 files changed, 204 insertions(+), 30 deletions(-) create mode 100644 src/test/ui/return/issue-86188-return-not-in-fn-body.rs create mode 100644 src/test/ui/return/issue-86188-return-not-in-fn-body.stderr diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index d0cbb58fb10eb..e9bb2b1c914f2 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -674,7 +674,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { if self.ret_coercion.is_none() { - self.tcx.sess.emit_err(ReturnStmtOutsideOfFnBody { span: expr.span }); + let mut err = ReturnStmtOutsideOfFnBody { + span: expr.span, + encl_body_span: None, + encl_fn_span: None, + }; + + let encl_item_id = self.tcx.hir().get_parent_item(expr.hir_id); + let encl_item = self.tcx.hir().expect_item(encl_item_id); + + if let hir::ItemKind::Fn(..) = encl_item.kind { + // We are inside a function body, so reporting "return statement + // outside of function body" needs an explanation. + + let encl_body_owner_id = self.tcx.hir().enclosing_body_owner(expr.hir_id); + + // If this didn't hold, we would not have to report an error in + // the first place. + assert_ne!(encl_item_id, encl_body_owner_id); + + let encl_body_id = self.tcx.hir().body_owned_by(encl_body_owner_id); + let encl_body = self.tcx.hir().body(encl_body_id); + + err.encl_body_span = Some(encl_body.value.span); + err.encl_fn_span = Some(encl_item.span); + } + + self.tcx.sess.emit_err(err); + + if let Some(e) = expr_opt { + // We still have to type-check `e` (issue #86188), but calling + // `check_return_expr` only works inside fn bodies. + self.check_expr(e); + } } else if let Some(e) = expr_opt { if self.ret_coercion_span.get().is_none() { self.ret_coercion_span.set(Some(e.span)); diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 5068242692ae8..1a21c085d5397 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -147,6 +147,10 @@ pub struct TypeofReservedKeywordUsed { pub struct ReturnStmtOutsideOfFnBody { #[message = "return statement outside of function body"] pub span: Span, + #[label = "the return is part of this body..."] + pub encl_body_span: Option, + #[label = "...not the enclosing function body"] + pub encl_fn_span: Option, } #[derive(SessionDiagnostic)] diff --git a/src/test/ui/issues/issue-51714.rs b/src/test/ui/issues/issue-51714.rs index 0dc588d75c654..8716524d6f4b5 100644 --- a/src/test/ui/issues/issue-51714.rs +++ b/src/test/ui/issues/issue-51714.rs @@ -1,13 +1,21 @@ fn main() { +//~^ NOTE: not the enclosing function body +//~| NOTE: not the enclosing function body +//~| NOTE: not the enclosing function body +//~| NOTE: not the enclosing function body |_: [_; return || {}] | {}; - //~^ ERROR return statement outside of function body + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... [(); return || {}]; - //~^ ERROR return statement outside of function body + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... [(); return |ice| {}]; - //~^ ERROR return statement outside of function body + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... [(); return while let Some(n) = Some(0) {}]; - //~^ ERROR return statement outside of function body + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... } diff --git a/src/test/ui/issues/issue-51714.stderr b/src/test/ui/issues/issue-51714.stderr index 023d9013ab4ed..514d69c1c7d39 100644 --- a/src/test/ui/issues/issue-51714.stderr +++ b/src/test/ui/issues/issue-51714.stderr @@ -1,26 +1,62 @@ error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:2:14 + --> $DIR/issue-51714.rs:6:14 | -LL | |_: [_; return || {}] | {}; - | ^^^^^^^^^^^^ +LL | / fn main() { +LL | | +LL | | +LL | | +LL | | +LL | | |_: [_; return || {}] | {}; + | | ^^^^^^^^^^^^ the return is part of this body... +... | +LL | | +LL | | } + | |_- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:5:10 + --> $DIR/issue-51714.rs:10:10 | -LL | [(); return || {}]; - | ^^^^^^^^^^^^ +LL | / fn main() { +LL | | +LL | | +LL | | +... | +LL | | [(); return || {}]; + | | ^^^^^^^^^^^^ the return is part of this body... +... | +LL | | +LL | | } + | |_- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:8:10 + --> $DIR/issue-51714.rs:14:10 | -LL | [(); return |ice| {}]; - | ^^^^^^^^^^^^^^^ +LL | / fn main() { +LL | | +LL | | +LL | | +... | +LL | | [(); return |ice| {}]; + | | ^^^^^^^^^^^^^^^ the return is part of this body... +... | +LL | | +LL | | } + | |_- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:11:10 + --> $DIR/issue-51714.rs:18:10 | -LL | [(); return while let Some(n) = Some(0) {}]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn main() { +LL | | +LL | | +LL | | +... | +LL | | [(); return while let Some(n) = Some(0) {}]; + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body... +LL | | +LL | | +LL | | } + | |_- ...not the enclosing function body error: aborting due to 4 previous errors diff --git a/src/test/ui/return/issue-86188-return-not-in-fn-body.rs b/src/test/ui/return/issue-86188-return-not-in-fn-body.rs new file mode 100644 index 0000000000000..23cc9f0512ca1 --- /dev/null +++ b/src/test/ui/return/issue-86188-return-not-in-fn-body.rs @@ -0,0 +1,22 @@ +// Due to a compiler bug, if a return occurs outside of a function body +// (e.g. in an AnonConst body), the return value expression would not be +// type-checked, leading to an ICE. This test checks that the ICE no +// longer happens, and that an appropriate error message is issued that +// also explains why the return is considered "outside of a function body" +// if it seems to be inside one, as in the main function below. + +const C: [(); 42] = { + [(); return || { + //~^ ERROR: return statement outside of function body [E0572] + let tx; + }] +}; + +fn main() { +//~^ NOTE: ...not the enclosing function body + [(); return || { + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... + let tx; + }]; +} diff --git a/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr new file mode 100644 index 0000000000000..9275cb91dd356 --- /dev/null +++ b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr @@ -0,0 +1,28 @@ +error[E0572]: return statement outside of function body + --> $DIR/issue-86188-return-not-in-fn-body.rs:9:10 + | +LL | [(); return || { + | __________^ +LL | | +LL | | let tx; +LL | | }] + | |_____^ + +error[E0572]: return statement outside of function body + --> $DIR/issue-86188-return-not-in-fn-body.rs:17:10 + | +LL | / fn main() { +LL | | +LL | | [(); return || { + | |__________^ +LL | || +LL | || +LL | || let tx; +LL | || }]; + | ||_____^ the return is part of this body... +LL | | } + | |_- ...not the enclosing function body + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0572`. diff --git a/src/test/ui/return/return-match-array-const.rs b/src/test/ui/return/return-match-array-const.rs index f21eac37c17b5..b619a4d57f955 100644 --- a/src/test/ui/return/return-match-array-const.rs +++ b/src/test/ui/return/return-match-array-const.rs @@ -1,10 +1,19 @@ fn main() { +//~^ NOTE: not the enclosing function body +//~| NOTE: not the enclosing function body +//~| NOTE: not the enclosing function body [(); return match 0 { n => n }]; - //~^ ERROR: return statement outside of function body + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... [(); return match 0 { 0 => 0 }]; - //~^ ERROR: return statement outside of function body + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... [(); return match () { 'a' => 0, _ => 0 }]; - //~^ ERROR: return statement outside of function body + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... + //~| ERROR: mismatched types [E0308] + //~| NOTE: expected `()`, found `char` + //~| NOTE: this expression has type `()` } diff --git a/src/test/ui/return/return-match-array-const.stderr b/src/test/ui/return/return-match-array-const.stderr index 8e801e3fbb7ab..85a733adfee69 100644 --- a/src/test/ui/return/return-match-array-const.stderr +++ b/src/test/ui/return/return-match-array-const.stderr @@ -1,21 +1,56 @@ error[E0572]: return statement outside of function body - --> $DIR/return-match-array-const.rs:2:10 + --> $DIR/return-match-array-const.rs:5:10 | -LL | [(); return match 0 { n => n }]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn main() { +LL | | +LL | | +LL | | +LL | | [(); return match 0 { n => n }]; + | | ^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body... +... | +LL | | +LL | | } + | |_- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/return-match-array-const.rs:5:10 + --> $DIR/return-match-array-const.rs:9:10 | -LL | [(); return match 0 { 0 => 0 }]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn main() { +LL | | +LL | | +LL | | +... | +LL | | [(); return match 0 { 0 => 0 }]; + | | ^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body... +... | +LL | | +LL | | } + | |_- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/return-match-array-const.rs:8:10 + --> $DIR/return-match-array-const.rs:13:10 + | +LL | / fn main() { +LL | | +LL | | +LL | | +... | +LL | | [(); return match () { 'a' => 0, _ => 0 }]; + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body... +... | +LL | | +LL | | } + | |_- ...not the enclosing function body + +error[E0308]: mismatched types + --> $DIR/return-match-array-const.rs:13:28 | LL | [(); return match () { 'a' => 0, _ => 0 }]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | -- ^^^ expected `()`, found `char` + | | + | this expression has type `()` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0572`. +Some errors have detailed explanations: E0308, E0572. +For more information about an error, try `rustc --explain E0308`. From 601d24810e89efd42f7cd69d4a7ccecd4e35364d Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 22 Jun 2021 22:10:25 -0700 Subject: [PATCH 2/7] Don't dist miri on stable or beta. --- src/bootstrap/dist.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 71ed0af4a7c04..e0c33f7357741 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1171,6 +1171,9 @@ impl Step for Miri { } fn run(self, builder: &Builder<'_>) -> Option { + if !builder.build.unstable_features() { + return None; + } let compiler = self.compiler; let target = self.target; assert!(builder.config.extended); From ac727732150ea338ea38727263b69a5cbadf13a9 Mon Sep 17 00:00:00 2001 From: klensy Date: Wed, 16 Jun 2021 13:25:00 +0300 Subject: [PATCH 3/7] fix pretty print for `loop` in mir and hir --- compiler/rustc_ast_pretty/src/pprust/state.rs | 1 - compiler/rustc_hir_pretty/src/lib.rs | 1 - src/test/pretty/ast-stmt-expr-attr.rs | 2 +- src/test/pretty/hir-pretty-loop.pp | 9 +++++++++ src/test/pretty/hir-pretty-loop.rs | 9 +++++++++ src/test/pretty/stmt_expr_attributes.rs | 3 +-- 6 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 src/test/pretty/hir-pretty-loop.pp create mode 100644 src/test/pretty/hir-pretty-loop.rs diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 93facd255df5e..7e58a599e2c5c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1950,7 +1950,6 @@ impl<'a> State<'a> { self.word_space(":"); } self.head("loop"); - self.s.space(); self.print_block_with_attrs(blk, attrs); } ast::ExprKind::Match(ref expr, ref arms) => { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2b932b7c9537e..9b1aca13a6f7a 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1538,7 +1538,6 @@ impl<'a> State<'a> { self.word_space(":"); } self.head("loop"); - self.s.space(); self.print_block(&blk); } hir::ExprKind::Match(ref expr, arms, _) => { diff --git a/src/test/pretty/ast-stmt-expr-attr.rs b/src/test/pretty/ast-stmt-expr-attr.rs index fb406514f4b5e..0c9ccfcf278ef 100644 --- a/src/test/pretty/ast-stmt-expr-attr.rs +++ b/src/test/pretty/ast-stmt-expr-attr.rs @@ -39,7 +39,7 @@ fn syntax() { #![attr] }; let _ = - #[attr] loop { + #[attr] loop { #![attr] }; let _ = diff --git a/src/test/pretty/hir-pretty-loop.pp b/src/test/pretty/hir-pretty-loop.pp new file mode 100644 index 0000000000000..19b3a1775cf36 --- /dev/null +++ b/src/test/pretty/hir-pretty-loop.pp @@ -0,0 +1,9 @@ +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +// pretty-compare-only +// pretty-mode:hir +// pp-exact:hir-pretty-loop.pp + +pub fn foo() { loop { break ; } } diff --git a/src/test/pretty/hir-pretty-loop.rs b/src/test/pretty/hir-pretty-loop.rs new file mode 100644 index 0000000000000..87a3ef8b8f912 --- /dev/null +++ b/src/test/pretty/hir-pretty-loop.rs @@ -0,0 +1,9 @@ +// pretty-compare-only +// pretty-mode:hir +// pp-exact:hir-pretty-loop.pp + +pub fn foo(){ + loop{ + break; + } +} diff --git a/src/test/pretty/stmt_expr_attributes.rs b/src/test/pretty/stmt_expr_attributes.rs index 54a8438f1d041..87692905f51e5 100644 --- a/src/test/pretty/stmt_expr_attributes.rs +++ b/src/test/pretty/stmt_expr_attributes.rs @@ -159,9 +159,8 @@ fn _11() { #[rustc_dummy] for _ in 0..0 { #![rustc_dummy] }; - // FIXME: pp bug, two spaces after the loop let _ = - #[rustc_dummy] loop { + #[rustc_dummy] loop { #![rustc_dummy] }; let _ = #[rustc_dummy] match false { _ => (), }; From 6aa79a34d87252deaae11e75663e5740a22f14ea Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 23 Jun 2021 07:03:42 -0700 Subject: [PATCH 4/7] Comment and include rust-analyzer. --- src/bootstrap/dist.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e0c33f7357741..19895baf08f16 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1072,6 +1072,12 @@ impl Step for RustAnalyzer { } fn run(self, builder: &Builder<'_>) -> Option { + // This prevents rust-analyzer from being built for "dist" or "install" + // on the stable/beta channels. It is a nightly-only tool and should + // not be included. + if !builder.build.unstable_features() { + return None; + } let compiler = self.compiler; let target = self.target; assert!(builder.config.extended); @@ -1171,6 +1177,9 @@ impl Step for Miri { } fn run(self, builder: &Builder<'_>) -> Option { + // This prevents miri from being built for "dist" or "install" + // on the stable/beta channels. It is a nightly-only tool and should + // not be included. if !builder.build.unstable_features() { return None; } From 76a2580a2acf0489e3699078450bd7e28dc56743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 28 Jun 2021 09:09:55 +0300 Subject: [PATCH 5/7] :arrow_up: rust-analyzer --- src/tools/rust-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 13da28cc2bc1b..1fa82adfdca50 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 13da28cc2bc1b59f7af817eca36927a71edb023c +Subproject commit 1fa82adfdca502a13f4dd952f9a50574870f5b7b From edf9375c0204b9d4131a32ec3feb53208c5368b4 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 28 Jun 2021 18:15:26 +0900 Subject: [PATCH 6/7] Allow anyone to set `perf-regression` label --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index c97f63f1cfd9a..4621adb2ba837 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -4,6 +4,7 @@ allow-unauthenticated = [ "D-*", "requires-nightly", "regression-*", + "perf-regression", # I-* without I-nominated "I-*", "!I-nominated", "AsyncAwait-OnDeck", From 16201597da9a5dc87e93f0cea9ab7ebf514295aa Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 28 Jun 2021 18:39:51 +0900 Subject: [PATCH 7/7] Add a regression test for issue-65384 --- src/test/ui/type-alias-impl-trait/issue-65384.rs | 16 ++++++++++++++++ .../ui/type-alias-impl-trait/issue-65384.stderr | 14 ++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/test/ui/type-alias-impl-trait/issue-65384.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-65384.stderr diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.rs b/src/test/ui/type-alias-impl-trait/issue-65384.rs new file mode 100644 index 0000000000000..63666c497c669 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-65384.rs @@ -0,0 +1,16 @@ +#![feature(min_type_alias_impl_trait)] +#![feature(type_alias_impl_trait)] +#![allow(incomplete_features)] + +trait MyTrait {} + +impl MyTrait for () {} + +type Bar = impl MyTrait; + +impl MyTrait for Bar {} +//~^ ERROR: cannot implement trait on type alias impl trait + +fn bazr() -> Bar { } + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.stderr b/src/test/ui/type-alias-impl-trait/issue-65384.stderr new file mode 100644 index 0000000000000..01d037266ec60 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-65384.stderr @@ -0,0 +1,14 @@ +error: cannot implement trait on type alias impl trait + --> $DIR/issue-65384.rs:11:1 + | +LL | impl MyTrait for Bar {} + | ^^^^^^^^^^^^^^^^^^^^ + | +note: type alias impl trait defined here + --> $DIR/issue-65384.rs:9:12 + | +LL | type Bar = impl MyTrait; + | ^^^^^^^^^^^^ + +error: aborting due to previous error +