about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs1
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs1
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs34
-rw-r--r--compiler/rustc_typeck/src/errors.rs4
-rw-r--r--src/bootstrap/dist.rs12
-rw-r--r--src/test/pretty/ast-stmt-expr-attr.rs2
-rw-r--r--src/test/pretty/hir-pretty-loop.pp9
-rw-r--r--src/test/pretty/hir-pretty-loop.rs9
-rw-r--r--src/test/pretty/stmt_expr_attributes.rs3
-rw-r--r--src/test/ui/issues/issue-51714.rs16
-rw-r--r--src/test/ui/issues/issue-51714.stderr60
-rw-r--r--src/test/ui/return/issue-86188-return-not-in-fn-body.rs22
-rw-r--r--src/test/ui/return/issue-86188-return-not-in-fn-body.stderr28
-rw-r--r--src/test/ui/return/return-match-array-const.rs15
-rw-r--r--src/test/ui/return/return-match-array-const.stderr55
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65384.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65384.stderr14
m---------src/tools/rust-analyzer36
-rw-r--r--triagebot.toml1
19 files changed, 283 insertions, 55 deletions
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index ffee5cdc331..f14d8a693fd 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1954,7 +1954,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 3211c7c5621..5c1739b1ab9 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1539,7 +1539,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/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 28ab6b15133..f69839bf859 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -675,7 +675,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 5068242692a..1a21c085d53 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<Span>,
+    #[label = "...not the enclosing function body"]
+    pub encl_fn_span: Option<Span>,
 }
 
 #[derive(SessionDiagnostic)]
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 71ed0af4a7c..19895baf08f 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<GeneratedTarball> {
+        // 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,12 @@ impl Step for Miri {
     }
 
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
+        // 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;
+        }
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
diff --git a/src/test/pretty/ast-stmt-expr-attr.rs b/src/test/pretty/ast-stmt-expr-attr.rs
index a32903a6409..32d1da390c5 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 00000000000..19b3a1775cf
--- /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 00000000000..87a3ef8b8f9
--- /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 231351433c8..e4a3acade87 100644
--- a/src/test/pretty/stmt_expr_attributes.rs
+++ b/src/test/pretty/stmt_expr_attributes.rs
@@ -166,9 +166,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 _ =
diff --git a/src/test/ui/issues/issue-51714.rs b/src/test/ui/issues/issue-51714.rs
index 0dc588d75c6..8716524d6f4 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 023d9013ab4..514d69c1c7d 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 00000000000..23cc9f0512c
--- /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 00000000000..9275cb91dd3
--- /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 f21eac37c17..b619a4d57f9 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 8e801e3fbb7..85a733adfee 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`.
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 00000000000..63666c497c6
--- /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 00000000000..01d037266ec
--- /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
+
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
-Subproject 13da28cc2bc1b59f7af817eca36927a71edb023
+Subproject 1fa82adfdca502a13f4dd952f9a50574870f5b7
diff --git a/triagebot.toml b/triagebot.toml
index c97f63f1cfd..4621adb2ba8 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",