about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock16
-rw-r--r--compiler/rustc/Cargo.toml3
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs14
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs30
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs26
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs16
-rw-r--r--compiler/rustc_parse/src/parser/path.rs20
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs5
-rw-r--r--compiler/rustc_smir/.gitignore1
-rw-r--r--compiler/rustc_smir/Cargo.toml28
-rw-r--r--compiler/rustc_smir/README.md75
-rw-r--r--compiler/rustc_smir/rust-toolchain.toml3
-rw-r--r--compiler/rustc_smir/src/lib.rs17
-rw-r--r--compiler/rustc_smir/src/mir.rs10
-rw-r--r--compiler/rustc_smir/src/very_unstable.rs27
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs38
-rw-r--r--compiler/rustc_target/src/spec/apple_base.rs9
-rw-r--r--compiler/rustc_target/src/spec/apple_sdk_base.rs8
-rw-r--r--compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs28
-rw-r--r--compiler/rustc_target/src/spec/armv7k_apple_watchos.rs28
-rw-r--r--compiler/rustc_target/src/spec/mod.rs5
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs35
-rw-r--r--compiler/rustc_typeck/src/collect.rs3
-rw-r--r--src/bootstrap/native.rs7
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md4
-rw-r--r--src/doc/rustc/src/platform-support/apple-watchos.md55
-rw-r--r--src/test/ui/check-cfg/well-known-values.stderr2
-rw-r--r--src/test/ui/parser/can-begin-expr-check.rs2
-rw-r--r--src/test/ui/parser/can-begin-expr-check.stderr4
-rw-r--r--src/test/ui/parser/duplicate-visibility.rs4
-rw-r--r--src/test/ui/parser/duplicate-visibility.stderr4
-rw-r--r--src/test/ui/parser/issues/issue-20616-2.rs2
-rw-r--r--src/test/ui/parser/issues/issue-20616-2.stderr4
-rw-r--r--src/test/ui/parser/issues/issue-62660.rs2
-rw-r--r--src/test/ui/parser/issues/issue-62660.stderr4
-rw-r--r--src/test/ui/parser/issues/issue-84117.rs2
-rw-r--r--src/test/ui/parser/issues/issue-84117.stderr4
-rw-r--r--src/test/ui/parser/issues/issue-93282.stderr4
-rw-r--r--src/test/ui/parser/issues/issue-93867.rs10
-rw-r--r--src/test/ui/parser/issues/issue-93867.stderr13
-rw-r--r--src/test/ui/parser/lifetime-semicolon.fixed2
-rw-r--r--src/test/ui/parser/lifetime-semicolon.rs2
-rw-r--r--src/test/ui/parser/lifetime-semicolon.stderr4
-rw-r--r--src/test/ui/parser/require-parens-for-chained-comparison.stderr4
-rw-r--r--src/test/ui/typeck/issue-74086.rs1
-rw-r--r--src/test/ui/typeck/issue-74086.stderr8
-rw-r--r--src/test/ui/typeck/issue-81885.rs3
-rw-r--r--src/test/ui/typeck/issue-81885.stderr16
-rw-r--r--src/test/ui/typeck/issue-88643.rs19
-rw-r--r--src/test/ui/typeck/issue-88643.stderr21
-rw-r--r--src/test/ui/typeck/typeck_type_placeholder_item_help.rs1
-rw-r--r--src/test/ui/typeck/typeck_type_placeholder_item_help.stderr12
-rw-r--r--src/tools/compiletest/src/raise_fd_limit.rs2
-rw-r--r--src/tools/compiletest/src/util.rs1
56 files changed, 621 insertions, 51 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 51b0da65b31..e5df61d61ce 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3440,6 +3440,7 @@ dependencies = [
  "jemalloc-sys",
  "rustc_codegen_ssa",
  "rustc_driver",
+ "rustc_smir",
 ]
 
 [[package]]
@@ -4438,6 +4439,21 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustc_smir"
+version = "0.0.0"
+dependencies = [
+ "rustc_borrowck",
+ "rustc_driver",
+ "rustc_hir",
+ "rustc_interface",
+ "rustc_middle",
+ "rustc_mir_dataflow",
+ "rustc_mir_transform",
+ "rustc_serialize",
+ "rustc_trait_selection",
+]
+
+[[package]]
 name = "rustc_span"
 version = "0.0.0"
 dependencies = [
diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml
index 5e0bb1a7f95..27ee3dd2aea 100644
--- a/compiler/rustc/Cargo.toml
+++ b/compiler/rustc/Cargo.toml
@@ -9,6 +9,9 @@ rustc_driver = { path = "../rustc_driver" }
 # Make sure rustc_codegen_ssa ends up in the sysroot, because this
 # crate is intended to be used by codegen backends, which may not be in-tree.
 rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
+# Make sure rustc_smir ends up in the sysroot, because this
+# crate is intended to be used by stable MIR consumers, which are not in-tree
+rustc_smir = { path = "../rustc_smir" }
 
 [dependencies.jemalloc-sys]
 version = "0.5.0"
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 3864db9ffc1..d05d09a11ea 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -1036,7 +1036,8 @@ unsafe fn embed_bitcode(
     // reason (see issue #90326 for historical background).
     let is_apple = cgcx.opts.target_triple.triple().contains("-ios")
         || cgcx.opts.target_triple.triple().contains("-darwin")
-        || cgcx.opts.target_triple.triple().contains("-tvos");
+        || cgcx.opts.target_triple.triple().contains("-tvos")
+        || cgcx.opts.target_triple.triple().contains("-watchos");
     if is_apple
         || cgcx.opts.target_triple.triple().starts_with("wasm")
         || cgcx.opts.target_triple.triple().starts_with("asmjs")
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 82213e7d748..e70509f3ecc 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2606,7 +2606,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
     let os = &sess.target.os;
     let llvm_target = &sess.target.llvm_target;
     if sess.target.vendor != "apple"
-        || !matches!(os.as_ref(), "ios" | "tvos")
+        || !matches!(os.as_ref(), "ios" | "tvos" | "watchos")
         || flavor != LinkerFlavor::Gcc
     {
         return;
@@ -2616,11 +2616,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
         ("x86_64", "tvos") => "appletvsimulator",
         ("arm", "ios") => "iphoneos",
         ("aarch64", "ios") if llvm_target.contains("macabi") => "macosx",
-        ("aarch64", "ios") if llvm_target.contains("sim") => "iphonesimulator",
+        ("aarch64", "ios") if llvm_target.ends_with("-simulator") => "iphonesimulator",
         ("aarch64", "ios") => "iphoneos",
         ("x86", "ios") => "iphonesimulator",
         ("x86_64", "ios") if llvm_target.contains("macabi") => "macosx",
         ("x86_64", "ios") => "iphonesimulator",
+        ("x86_64", "watchos") => "watchsimulator",
+        ("arm64_32", "watchos") => "watchos",
+        ("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator",
+        ("aarch64", "watchos") => "watchos",
+        ("arm", "watchos") => "watchos",
         _ => {
             sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
             return;
@@ -2667,6 +2672,11 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
             "macosx10.15"
                 if sdkroot.contains("iPhoneOS.platform")
                     || sdkroot.contains("iPhoneSimulator.platform") => {}
+            "watchos"
+                if sdkroot.contains("WatchSimulator.platform")
+                    || sdkroot.contains("MacOSX.platform") => {}
+            "watchsimulator"
+                if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {}
             // Ignore `SDKROOT` if it's not a valid path.
             _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
             _ => return Ok(sdkroot),
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 7bc8175195f..c56f70e853d 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -28,6 +28,7 @@ use std::ops::{Deref, DerefMut};
 
 use std::mem::take;
 
+use crate::parser;
 use tracing::{debug, trace};
 
 const TURBOFISH_SUGGESTION_STR: &str =
@@ -481,6 +482,35 @@ impl<'a> Parser<'a> {
             .map(|x| TokenType::Token(x.clone()))
             .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
             .chain(self.expected_tokens.iter().cloned())
+            .filter_map(|token| {
+                // filter out suggestions which suggest the same token which was found and deemed incorrect
+                fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
+                    if let TokenKind::Ident(current_sym, _) = found {
+                        if let TokenType::Keyword(suggested_sym) = expected {
+                            return current_sym == suggested_sym;
+                        }
+                    }
+                    false
+                }
+                if token != parser::TokenType::Token(self.token.kind.clone()) {
+                    let eq = is_ident_eq_keyword(&self.token.kind, &token);
+                    // if the suggestion is a keyword and the found token is an ident,
+                    // the content of which are equal to the suggestion's content,
+                    // we can remove that suggestion (see the return None statement below)
+
+                    // if this isn't the case however, and the suggestion is a token the
+                    // content of which is the same as the found token's, we remove it as well
+                    if !eq {
+                        if let TokenType::Token(kind) = &token {
+                            if kind == &self.token.kind {
+                                return None;
+                            }
+                        }
+                        return Some(token);
+                    }
+                }
+                return None;
+            })
             .collect::<Vec<_>>();
         expected.sort_by_cached_key(|x| x.to_string());
         expected.dedup();
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 236ccef1d03..b224fa9596e 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -980,12 +980,26 @@ impl<'a> Parser<'a> {
 
     fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
         loop {
-            if self.eat(&token::Question) {
+            let has_question = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
+                // we are using noexpect here because we don't expect a `?` directly after a `return`
+                // which could be suggested otherwise
+                self.eat_noexpect(&token::Question)
+            } else {
+                self.eat(&token::Question)
+            };
+            if has_question {
                 // `expr?`
                 e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e), AttrVec::new());
                 continue;
             }
-            if self.eat(&token::Dot) {
+            let has_dot = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
+                // we are using noexpect here because we don't expect a `.` directly after a `return`
+                // which could be suggested otherwise
+                self.eat_noexpect(&token::Dot)
+            } else {
+                self.eat(&token::Dot)
+            };
+            if has_dot {
                 // expr.f
                 e = self.parse_dot_suffix_expr(lo, e)?;
                 continue;
@@ -1541,9 +1555,13 @@ impl<'a> Parser<'a> {
             self.parse_for_expr(label, lo, attrs)
         } else if self.eat_keyword(kw::Loop) {
             self.parse_loop_expr(label, lo, attrs)
-        } else if self.check(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() {
+        } else if self.check_noexpect(&token::OpenDelim(Delimiter::Brace))
+            || self.token.is_whole_block()
+        {
             self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
-        } else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) {
+        } else if !ate_colon
+            && (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt))
+        {
             // We're probably inside of a `Path<'a>` that needs a turbofish
             let msg = "expected `while`, `for`, `loop` or `{` after a label";
             self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 4df9ad26a58..6d6667717f0 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -547,6 +547,22 @@ impl<'a> Parser<'a> {
         is_present
     }
 
+    fn check_noexpect(&self, tok: &TokenKind) -> bool {
+        self.token == *tok
+    }
+
+    /// Consumes a token 'tok' if it exists. Returns whether the given token was present.
+    ///
+    /// the main purpose of this function is to reduce the cluttering of the suggestions list
+    /// which using the normal eat method could introduce in some cases.
+    pub fn eat_noexpect(&mut self, tok: &TokenKind) -> bool {
+        let is_present = self.check_noexpect(tok);
+        if is_present {
+            self.bump()
+        }
+        is_present
+    }
+
     /// Consumes a token 'tok' if it exists. Returns whether the given token was present.
     pub fn eat(&mut self, tok: &TokenKind) -> bool {
         let is_present = self.check(tok);
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index da46af60f72..5cf1758c31f 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -2,7 +2,7 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
 use super::{Parser, Restrictions, TokenType};
 use crate::maybe_whole;
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Delimiter, Token};
+use rustc_ast::token::{self, Delimiter, Token, TokenKind};
 use rustc_ast::{
     self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocConstraint,
     AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
@@ -96,7 +96,7 @@ impl<'a> Parser<'a> {
     ///                ^ help: use double colon
     /// ```
     fn recover_colon_before_qpath_proj(&mut self) -> bool {
-        if self.token.kind != token::Colon
+        if !self.check_noexpect(&TokenKind::Colon)
             || self.look_ahead(1, |t| !t.is_ident() || t.is_reserved_ident())
         {
             return false;
@@ -478,7 +478,7 @@ impl<'a> Parser<'a> {
         while let Some(arg) = self.parse_angle_arg(ty_generics)? {
             args.push(arg);
             if !self.eat(&token::Comma) {
-                if self.token.kind == token::Semi
+                if self.check_noexpect(&TokenKind::Semi)
                     && self.look_ahead(1, |t| t.is_ident() || t.is_lifetime())
                 {
                     // Add `>` to the list of expected tokens.
@@ -517,7 +517,11 @@ impl<'a> Parser<'a> {
         let arg = self.parse_generic_arg(ty_generics)?;
         match arg {
             Some(arg) => {
-                if self.check(&token::Colon) | self.check(&token::Eq) {
+                // we are using noexpect here because we first want to find out if either `=` or `:`
+                // is present and then use that info to push the other token onto the tokens list
+                let separated =
+                    self.check_noexpect(&token::Colon) || self.check_noexpect(&token::Eq);
+                if separated && (self.check(&token::Colon) | self.check(&token::Eq)) {
                     let arg_span = arg.span();
                     let (binder, ident, gen_args) = match self.get_ident_from_generic_arg(&arg) {
                         Ok(ident_gen_args) => ident_gen_args,
@@ -553,6 +557,14 @@ impl<'a> Parser<'a> {
                         AssocConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span };
                     Ok(Some(AngleBracketedArg::Constraint(constraint)))
                 } else {
+                    // we only want to suggest `:` and `=` in contexts where the previous token
+                    // is an ident and the current token or the next token is an ident
+                    if self.prev_token.is_ident()
+                        && (self.token.is_ident() || self.look_ahead(1, |token| token.is_ident()))
+                    {
+                        self.check(&token::Colon);
+                        self.check(&token::Eq);
+                    }
                     Ok(Some(AngleBracketedArg::Arg(arg)))
                 }
             }
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index ad0128cd9ed..42355dd93a7 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -260,7 +260,10 @@ impl<'a> Parser<'a> {
                     if let Ok(snip) = self.span_to_snippet(pat.span) {
                         err.span_label(pat.span, format!("while parsing the type for `{}`", snip));
                     }
-                    let err = if self.check(&token::Eq) {
+                    // we use noexpect here because we don't actually expect Eq to be here
+                    // but we are still checking for it in order to be able to handle it if
+                    // it is there
+                    let err = if self.check_noexpect(&token::Eq) {
                         err.emit();
                         None
                     } else {
diff --git a/compiler/rustc_smir/.gitignore b/compiler/rustc_smir/.gitignore
new file mode 100644
index 00000000000..eb5a316cbd1
--- /dev/null
+++ b/compiler/rustc_smir/.gitignore
@@ -0,0 +1 @@
+target
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
new file mode 100644
index 00000000000..5e0d1f369a6
--- /dev/null
+++ b/compiler/rustc_smir/Cargo.toml
@@ -0,0 +1,28 @@
+[package]
+name = "rustc_smir"
+version = "0.0.0"
+edition = "2021"
+
+[dependencies]
+rustc_borrowck = { path = "../rustc_borrowck", optional = true }
+rustc_driver = { path = "../rustc_driver", optional = true }
+rustc_hir = { path = "../rustc_hir", optional = true }
+rustc_interface = { path = "../rustc_interface", optional = true }
+rustc_middle = { path = "../rustc_middle", optional = true }
+rustc_mir_dataflow = { path = "../rustc_mir_dataflow", optional = true }
+rustc_mir_transform = { path = "../rustc_mir_transform", optional = true }
+rustc_serialize = { path = "../rustc_serialize", optional = true }
+rustc_trait_selection = { path = "../rustc_trait_selection", optional = true }
+
+[features]
+default = [
+    "rustc_borrowck",
+    "rustc_driver",
+    "rustc_hir",
+    "rustc_interface",
+    "rustc_middle",
+    "rustc_mir_dataflow",
+    "rustc_mir_transform",
+    "rustc_serialize",
+    "rustc_trait_selection",
+]
diff --git a/compiler/rustc_smir/README.md b/compiler/rustc_smir/README.md
new file mode 100644
index 00000000000..ae49098dd0c
--- /dev/null
+++ b/compiler/rustc_smir/README.md
@@ -0,0 +1,75 @@
+This crate is regularly synced with its mirror in the rustc repo at `compiler/rustc_smir`.
+
+We use `git subtree` for this to preserve commits and allow the rustc repo to
+edit these crates without having to touch this repo. This keeps the crates compiling
+while allowing us to independently work on them here. The effort of keeping them in
+sync is pushed entirely onto us, without affecting rustc workflows negatively.
+This may change in the future, but changes to policy should only be done via a
+compiler team MCP.
+
+## Instructions for working on this crate locally
+
+Since the crate is the same in the rustc repo and here, the dependencies on rustc_* crates
+will only either work here or there, but never in both places at the same time. Thus we use
+optional dependencies on the rustc_* crates, requiring local development to use
+
+```
+cargo build --no-default-features -Zavoid-dev-deps
+```
+
+in order to compile successfully.
+
+## Instructions for syncing
+
+### Updating this repository
+
+In the rustc repo, execute
+
+```
+git subtree push --prefix=compiler/rustc_smir url_to_your_fork_of_project_stable_mir some_feature_branch
+```
+
+and then open a PR of your `some_feature_branch` against https://github.com/rust-lang/project-stable-mir
+
+### Updating the rustc library
+
+First we need to bump our stack limit, as the rustc repo otherwise quickly hits that:
+
+```
+ulimit -s 60000
+```
+
+#### Maximum function recursion depth (1000) reached
+
+Then we need to disable `dash` as the default shell for sh scripts, as otherwise we run into a
+hard limit of a recursion depth of 1000:
+
+```
+sudo dpkg-reconfigure dash
+```
+
+and then select `No` to disable dash.
+
+
+#### Patching your `git worktree`
+
+The regular git worktree does not scale to repos of the size of the rustc repo.
+So download the `git-subtree.sh` from https://github.com/gitgitgadget/git/pull/493/files and run
+
+```
+sudo cp --backup /path/to/patched/git-subtree.sh /usr/lib/git-core/git-subtree
+sudo chmod --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
+sudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
+```
+
+#### Actually doing a sync
+
+In the rustc repo, execute
+
+```
+git subtree pull --prefix=compiler/rustc_smir https://github.com/rust-lang/project-stable-mir smir
+```
+
+Note: only ever sync to rustc from the project-stable-mir's `smir` branch. Do not sync with your own forks.
+
+Then open a PR against rustc just like a regular PR.
diff --git a/compiler/rustc_smir/rust-toolchain.toml b/compiler/rustc_smir/rust-toolchain.toml
new file mode 100644
index 00000000000..7b696fc1f5c
--- /dev/null
+++ b/compiler/rustc_smir/rust-toolchain.toml
@@ -0,0 +1,3 @@
+[toolchain]
+channel = "nightly-2022-06-01"
+components = [ "rustfmt", "rustc-dev" ]
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
new file mode 100644
index 00000000000..5c7aaf35b90
--- /dev/null
+++ b/compiler/rustc_smir/src/lib.rs
@@ -0,0 +1,17 @@
+//! The WIP stable interface to rustc internals.
+//!
+//! For more information see https://github.com/rust-lang/project-stable-mir
+//!
+//! # Note
+//!
+//! This API is still completely unstable and subject to change.
+
+#![doc(
+    html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
+    test(attr(allow(unused_variables), deny(warnings)))
+)]
+#![cfg_attr(not(feature = "default"), feature(rustc_private))]
+
+pub mod mir;
+
+pub mod very_unstable;
diff --git a/compiler/rustc_smir/src/mir.rs b/compiler/rustc_smir/src/mir.rs
new file mode 100644
index 00000000000..855605b1a4f
--- /dev/null
+++ b/compiler/rustc_smir/src/mir.rs
@@ -0,0 +1,10 @@
+pub use crate::very_unstable::middle::mir::{
+    visit::MutVisitor, AggregateKind, AssertKind, BasicBlock, BasicBlockData, BinOp, BindingForm,
+    BlockTailInfo, Body, BorrowKind, CastKind, ClearCrossCrate, Constant, ConstantKind,
+    CopyNonOverlapping, Coverage, FakeReadCause, Field, GeneratorInfo, ImplicitSelfKind,
+    InlineAsmOperand, Local, LocalDecl, LocalInfo, LocalKind, Location, MirPhase, MirSource,
+    NullOp, Operand, Place, PlaceRef, ProjectionElem, ProjectionKind, Promoted, RetagKind, Rvalue,
+    Safety, SourceInfo, SourceScope, SourceScopeData, SourceScopeLocalData, Statement,
+    StatementKind, UnOp, UserTypeProjection, UserTypeProjections, VarBindingForm, VarDebugInfo,
+    VarDebugInfoContents,
+};
diff --git a/compiler/rustc_smir/src/very_unstable.rs b/compiler/rustc_smir/src/very_unstable.rs
new file mode 100644
index 00000000000..12ba133dbb1
--- /dev/null
+++ b/compiler/rustc_smir/src/very_unstable.rs
@@ -0,0 +1,27 @@
+//! This module reexports various crates and modules from unstable rustc APIs.
+//! Add anything you need here and it will get slowly transferred to a stable API.
+//! Only use rustc_smir in your dependencies and use the reexports here instead of
+//! directly referring to the unstable crates.
+
+macro_rules! crates {
+    ($($rustc_name:ident -> $name:ident,)*) => {
+        $(
+            #[cfg(not(feature = "default"))]
+            pub extern crate $rustc_name as $name;
+            #[cfg(feature = "default")]
+            pub use $rustc_name as $name;
+        )*
+    }
+}
+
+crates! {
+    rustc_borrowck -> borrowck,
+    rustc_driver -> driver,
+    rustc_hir -> hir,
+    rustc_interface -> interface,
+    rustc_middle -> middle,
+    rustc_mir_dataflow -> dataflow,
+    rustc_mir_transform -> transform,
+    rustc_serialize -> serialize,
+    rustc_trait_selection -> trait_selection,
+}
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs
new file mode 100644
index 00000000000..3059f42140b
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_apple_watchos_sim.rs
@@ -0,0 +1,38 @@
+use super::apple_sdk_base::{opts, Arch};
+use crate::spec::{FramePointer, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let base = opts("watchos", Arch::Arm64_sim);
+
+    // Clang automatically chooses a more specific target based on
+    // WATCHOS_DEPLOYMENT_TARGET.
+    // This is required for the simulator target to pick the right
+    // MACH-O commands, so we do too.
+    let arch = "arm64";
+    let llvm_target = super::apple_base::watchos_sim_llvm_target(arch);
+
+    Target {
+        llvm_target: llvm_target.into(),
+        pointer_width: 64,
+        data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(),
+        arch: "aarch64".into(),
+        options: TargetOptions {
+            features: "+neon,+fp-armv8,+apple-a7".into(),
+            max_atomic_width: Some(128),
+            forces_embed_bitcode: true,
+            frame_pointer: FramePointer::NonLeaf,
+            // Taken from a clang build on Xcode 11.4.1.
+            // These arguments are not actually invoked - they just have
+            // to look right to pass App Store validation.
+            bitcode_llvm_cmdline: "-triple\0\
+                arm64-apple-watchos5.0-simulator\0\
+                -emit-obj\0\
+                -disable-llvm-passes\0\
+                -target-abi\0\
+                darwinpcs\0\
+                -Os\0"
+                .into(),
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index 238d3f8bda5..e8460a509e2 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -114,3 +114,12 @@ pub fn ios_sim_llvm_target(arch: &str) -> String {
     let (major, minor) = ios_deployment_target();
     format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor)
 }
+
+fn watchos_deployment_target() -> (u32, u32) {
+    deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
+}
+
+pub fn watchos_sim_llvm_target(arch: &str) -> String {
+    let (major, minor) = watchos_deployment_target();
+    format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor)
+}
diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs
index e2d08955c08..ecb6cbd9f8a 100644
--- a/compiler/rustc_target/src/spec/apple_sdk_base.rs
+++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs
@@ -6,8 +6,10 @@ use Arch::*;
 #[derive(Copy, Clone)]
 pub enum Arch {
     Armv7,
+    Armv7k,
     Armv7s,
     Arm64,
+    Arm64_32,
     I386,
     X86_64,
     X86_64_macabi,
@@ -17,7 +19,7 @@ pub enum Arch {
 
 fn target_abi(arch: Arch) -> &'static str {
     match arch {
-        Armv7 | Armv7s | Arm64 | I386 | X86_64 => "",
+        Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "",
         X86_64_macabi | Arm64_macabi => "macabi",
         Arm64_sim => "sim",
     }
@@ -26,8 +28,10 @@ fn target_abi(arch: Arch) -> &'static str {
 fn target_cpu(arch: Arch) -> &'static str {
     match arch {
         Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
+        Armv7k => "cortex-a8",
         Armv7s => "cortex-a9",
         Arm64 => "apple-a7",
+        Arm64_32 => "apple-s4",
         I386 => "yonah",
         X86_64 => "core2",
         X86_64_macabi => "core2",
@@ -38,7 +42,7 @@ fn target_cpu(arch: Arch) -> &'static str {
 
 fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> {
     match arch {
-        Armv7 | Armv7s | Arm64 | I386 | X86_64 | Arm64_sim => {
+        Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 | Arm64_sim => {
             cvs!["MACOSX_DEPLOYMENT_TARGET"]
         }
         X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"],
diff --git a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
new file mode 100644
index 00000000000..7b23fe1c482
--- /dev/null
+++ b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
@@ -0,0 +1,28 @@
+use super::apple_sdk_base::{opts, Arch};
+use crate::spec::{Target, TargetOptions};
+
+pub fn target() -> Target {
+    let base = opts("watchos", Arch::Arm64_32);
+    Target {
+        llvm_target: "arm64_32-apple-watchos".into(),
+        pointer_width: 32,
+        data_layout: "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128".into(),
+        arch: "aarch64".into(),
+        options: TargetOptions {
+            features: "+neon,+fp-armv8,+apple-a7".into(),
+            max_atomic_width: Some(64),
+            forces_embed_bitcode: true,
+            // These arguments are not actually invoked - they just have
+            // to look right to pass App Store validation.
+            bitcode_llvm_cmdline: "-triple\0\
+                arm64_32-apple-watchos5.0.0\0\
+                -emit-obj\0\
+                -disable-llvm-passes\0\
+                -target-abi\0\
+                darwinpcs\0\
+                -Os\0"
+                .into(),
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs
new file mode 100644
index 00000000000..af5d1c2ff45
--- /dev/null
+++ b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs
@@ -0,0 +1,28 @@
+use super::apple_sdk_base::{opts, Arch};
+use crate::spec::{Target, TargetOptions};
+
+pub fn target() -> Target {
+    let base = opts("watchos", Arch::Armv7k);
+    Target {
+        llvm_target: "armv7k-apple-watchos".into(),
+        pointer_width: 32,
+        data_layout: "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128".into(),
+        arch: "arm".into(),
+        options: TargetOptions {
+            features: "+v7,+vfp4,+neon".into(),
+            max_atomic_width: Some(64),
+            forces_embed_bitcode: true,
+            // These arguments are not actually invoked - they just have
+            // to look right to pass App Store validation.
+            bitcode_llvm_cmdline: "-triple\0\
+                armv7k-apple-watchos3.0.0\0\
+                -emit-obj\0\
+                -disable-llvm-passes\0\
+                -target-abi\0\
+                darwinpcs\0\
+                -Os\0"
+                .into(),
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 4ede0677ab3..422af667875 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -928,6 +928,11 @@ supported_targets! {
     ("aarch64-apple-tvos", aarch64_apple_tvos),
     ("x86_64-apple-tvos", x86_64_apple_tvos),
 
+    ("armv7k-apple-watchos", armv7k_apple_watchos),
+    ("arm64_32-apple-watchos", arm64_32_apple_watchos),
+    ("x86_64-apple-watchos-sim", x86_64_apple_watchos_sim),
+    ("aarch64-apple-watchos-sim", aarch64_apple_watchos_sim),
+
     ("armebv7r-none-eabi", armebv7r_none_eabi),
     ("armebv7r-none-eabihf", armebv7r_none_eabihf),
     ("armv7r-none-eabi", armv7r_none_eabi),
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs
new file mode 100644
index 00000000000..4dff3c2f209
--- /dev/null
+++ b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs
@@ -0,0 +1,35 @@
+use super::apple_sdk_base::{opts, Arch};
+use crate::spec::{StackProbeType, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let base = opts("watchos", Arch::X86_64);
+
+    let arch = "x86_64";
+    let llvm_target = super::apple_base::watchos_sim_llvm_target(arch);
+
+    Target {
+        llvm_target: llvm_target.into(),
+        pointer_width: 64,
+        data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+            .into(),
+        arch: "x86_64".into(),
+        options: TargetOptions {
+            max_atomic_width: Some(64),
+            // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
+            stack_probes: StackProbeType::Call,
+            forces_embed_bitcode: true,
+            // Taken from a clang build on Xcode 11.4.1.
+            // These arguments are not actually invoked - they just have
+            // to look right to pass App Store validation.
+            bitcode_llvm_cmdline: "-triple\0\
+                x86_64-apple-watchos5.0-simulator\0\
+                -emit-obj\0\
+                -disable-llvm-passes\0\
+                -target-abi\0\
+                darwinpcs\0\
+                -Os\0"
+                .into(),
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 82f2adda3b0..a74cce5d13e 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -806,8 +806,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
                 hir::ItemKind::Fn(..) => tcx.ensure().fn_sig(def_id),
                 hir::ItemKind::OpaqueTy(..) => tcx.ensure().item_bounds(def_id),
                 hir::ItemKind::Const(ty, ..) | hir::ItemKind::Static(ty, ..) => {
-                    // (#75889): Account for `const C: dyn Fn() -> _ = "";`
-                    if let hir::TyKind::TraitObject(..) = ty.kind {
+                    if !is_suggestable_infer_ty(ty) {
                         let mut visitor = HirPlaceholderCollector::default();
                         visitor.visit_item(it);
                         placeholder_type_error(tcx, None, visitor.0, false, None, it.kind.descr());
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 2b0b7f65b07..e23498873f3 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -315,8 +315,11 @@ impl Step for Llvm {
             cfg.define("LLVM_ENABLE_ZLIB", "OFF");
         }
 
-        // Are we compiling for iOS/tvOS?
-        if target.contains("apple-ios") || target.contains("apple-tvos") {
+        // Are we compiling for iOS/tvOS/watchOS?
+        if target.contains("apple-ios")
+            || target.contains("apple-tvos")
+            || target.contains("apple-watchos")
+        {
             // These two defines prevent CMake from automatically trying to add a MacOSX sysroot, which leads to a compiler error.
             cfg.define("CMAKE_OSX_SYSROOT", "/");
             cfg.define("CMAKE_OSX_DEPLOYMENT_TARGET", "");
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 8e2d44c1812..e464564c120 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -16,6 +16,7 @@
     - [Target Tier Policy](target-tier-policy.md)
     - [Template for Target-specific Documentation](platform-support/TEMPLATE.md)
     - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
+    - [\*-apple-watchos\*](platform-support/apple-watchos.md)
     - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
     - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 4ac09711b0a..ec93bdd3fd3 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -207,6 +207,7 @@ target | std | host | notes
 -------|:---:|:----:|-------
 `aarch64-apple-ios-macabi` | ? |  | Apple Catalyst on ARM64
 `aarch64-apple-tvos` | * |  | ARM64 tvOS
+[`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ |  | ARM64 Apple WatchOS Simulator
 [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ |  | ARM64 SOLID with TOPPERS/ASP3
 [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
 `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
@@ -220,6 +221,7 @@ target | std | host | notes
 `aarch64-wrs-vxworks` | ? |  |
 `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
 `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
+[`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM Apple WatchOS 64-bit with 32-bit pointers
 `armv4t-unknown-linux-gnueabi` | ? |  |
 `armv5te-unknown-linux-uclibceabi` | ? |  | ARMv5TE Linux with uClibc
 `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
@@ -234,6 +236,7 @@ target | std | host | notes
 [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ |  | ARM SOLID with TOPPERS/ASP3
 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ |  | ARM SOLID with TOPPERS/ASP3, hardfloat
 `armv7a-none-eabihf` | * | | ARM Cortex-A, hardfloat
+[`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM Apple WatchOS
 `armv7s-apple-ios` | ✓ |  |
 `avr-unknown-gnu-atmega328` | * |  | AVR. Requires `-Z build-std=core`
 `bpfeb-unknown-none` | * |  | BPF (big endian)
@@ -290,6 +293,7 @@ target | std | host | notes
 [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? |  | WebAssembly
 `x86_64-apple-ios-macabi` | ✓ |  | Apple Catalyst on x86_64
 `x86_64-apple-tvos` | * | | x86 64-bit tvOS
+[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator
 [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
 `x86_64-pc-windows-msvc` | * |  | 64-bit Windows XP support
 `x86_64-sun-solaris` | ? |  | Deprecated target for 64-bit Solaris 10/11, illumos
diff --git a/src/doc/rustc/src/platform-support/apple-watchos.md b/src/doc/rustc/src/platform-support/apple-watchos.md
new file mode 100644
index 00000000000..fe4c7c0c88f
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/apple-watchos.md
@@ -0,0 +1,55 @@
+# *-apple-watchos
+- arm64_32-apple-watchos
+- armv7k-apple-watchos
+- aarch64-apple-watchos-sim
+- x86_64-apple-watchos-sim
+
+**Tier: 3**
+
+Apple WatchOS targets:
+- Apple WatchOS on Arm 64_32
+- Apple WatchOS on Arm v7k
+- Apple WatchOS Simulator on arm64
+- Apple WatchOS Simulator on x86_64
+
+## Target maintainers
+
+* [@deg4uss3r](https://github.com/deg4uss3r)
+* [@vladimir-ea](https://github.com/vladimir-ea)
+
+## Requirements
+
+These targets are cross-compiled.
+To build these targets Xcode 12 or higher on macOS is required.
+
+## Building the target
+
+The targets can be built by enabling them for a `rustc` build, for example:
+
+```toml
+[build]
+build-stage = 1
+target = ["aarch64-apple-watchos-sim"]
+```
+
+## Building Rust programs
+
+*Note: Building for this target requires the corresponding WatchOS SDK, as provided by Xcode 12+.*
+
+Rust programs can be built for these targets, if `rustc` has been built with support for them, for example:
+
+```text
+rustc --target aarch64-apple-watchos-sim your-code.rs
+```
+
+## Testing
+
+There is no support for running the Rust testsuite on WatchOS or the simulators.
+
+There is no easy way to run simple programs on WatchOS or the WatchOS simulators. Static library builds can be embedded into WatchOS applications.
+
+## Cross-compilation toolchains and C code
+
+This target can be cross-compiled from x86_64 or aarch64 macOS hosts.
+
+Other hosts are not supported for cross-compilation, but might work when also providing the required Xcode SDK.
diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr
index a1f7e17d778..24ce2280c8a 100644
--- a/src/test/ui/check-cfg/well-known-values.stderr
+++ b/src/test/ui/check-cfg/well-known-values.stderr
@@ -7,7 +7,7 @@ LL | #[cfg(target_os = "linuz")]
    |                   help: did you mean: `"linux"`
    |
    = note: `#[warn(unexpected_cfgs)]` on by default
-   = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, windows, xous
+   = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous
 
 warning: unexpected `cfg` condition value
   --> $DIR/well-known-values.rs:14:7
diff --git a/src/test/ui/parser/can-begin-expr-check.rs b/src/test/ui/parser/can-begin-expr-check.rs
index 8974d9f48c1..e5be8de79a9 100644
--- a/src/test/ui/parser/can-begin-expr-check.rs
+++ b/src/test/ui/parser/can-begin-expr-check.rs
@@ -16,5 +16,5 @@ pub fn main() {
         return break as ();
     }
 
-    return enum; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found keyword `enum`
+    return enum; //~ ERROR expected one of `;`, `}`, or an operator, found keyword `enum`
 }
diff --git a/src/test/ui/parser/can-begin-expr-check.stderr b/src/test/ui/parser/can-begin-expr-check.stderr
index d674fc36bc2..9569ababad8 100644
--- a/src/test/ui/parser/can-begin-expr-check.stderr
+++ b/src/test/ui/parser/can-begin-expr-check.stderr
@@ -1,8 +1,8 @@
-error: expected one of `.`, `;`, `?`, `}`, or an operator, found keyword `enum`
+error: expected one of `;`, `}`, or an operator, found keyword `enum`
   --> $DIR/can-begin-expr-check.rs:19:12
    |
 LL |     return enum;
-   |            ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+   |            ^^^^ expected one of `;`, `}`, or an operator
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs
index 32aeee29472..54955944c7d 100644
--- a/src/test/ui/parser/duplicate-visibility.rs
+++ b/src/test/ui/parser/duplicate-visibility.rs
@@ -2,8 +2,8 @@ fn main() {}
 
 extern "C" { //~ NOTE while parsing this item list starting here
     pub pub fn foo();
-    //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub`
-    //~| NOTE expected one of 9 possible tokens
+    //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
+    //~| NOTE expected one of 8 possible tokens
     //~| HELP there is already a visibility modifier, remove one
     //~| NOTE explicit visibility first seen here
 } //~ NOTE the item list ends here
diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr
index 97144ac2f64..8ecebf01f17 100644
--- a/src/test/ui/parser/duplicate-visibility.stderr
+++ b/src/test/ui/parser/duplicate-visibility.stderr
@@ -1,4 +1,4 @@
-error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub`
+error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
   --> $DIR/duplicate-visibility.rs:4:9
    |
 LL | extern "C" {
@@ -6,7 +6,7 @@ LL | extern "C" {
 LL |     pub pub fn foo();
    |         ^^^
    |         |
-   |         expected one of 9 possible tokens
+   |         expected one of 8 possible tokens
    |         help: there is already a visibility modifier, remove one
 ...
 LL | }
diff --git a/src/test/ui/parser/issues/issue-20616-2.rs b/src/test/ui/parser/issues/issue-20616-2.rs
index f108ae5de14..2f2c6903a9f 100644
--- a/src/test/ui/parser/issues/issue-20616-2.rs
+++ b/src/test/ui/parser/issues/issue-20616-2.rs
@@ -9,7 +9,7 @@ type Type_1_<'a, T> = &'a T;
 //type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
 
 
-type Type_2 = Type_1_<'static ()>; //~ error: expected one of `,`, `:`, `=`, or `>`, found `(`
+type Type_2 = Type_1_<'static ()>; //~ error: expected one of `,` or `>`, found `(`
 
 
 //type Type_3<T> = Box<T,,>; // error: expected type, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-2.stderr b/src/test/ui/parser/issues/issue-20616-2.stderr
index 13e6aa7d605..42059685c5c 100644
--- a/src/test/ui/parser/issues/issue-20616-2.stderr
+++ b/src/test/ui/parser/issues/issue-20616-2.stderr
@@ -1,8 +1,8 @@
-error: expected one of `,`, `:`, `=`, or `>`, found `(`
+error: expected one of `,` or `>`, found `(`
   --> $DIR/issue-20616-2.rs:12:31
    |
 LL | type Type_2 = Type_1_<'static ()>;
-   |                               ^ expected one of `,`, `:`, `=`, or `>`
+   |                               ^ expected one of `,` or `>`
    |
 help: you might have meant to end the type parameters here
    |
diff --git a/src/test/ui/parser/issues/issue-62660.rs b/src/test/ui/parser/issues/issue-62660.rs
index 4f866b78976..33c8a9fa328 100644
--- a/src/test/ui/parser/issues/issue-62660.rs
+++ b/src/test/ui/parser/issues/issue-62660.rs
@@ -5,7 +5,7 @@ struct Foo;
 
 impl Foo {
     pub fn foo(_: i32, self: Box<Self) {}
-    //~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, `=`, or `>`, found `)`
+    //~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)`
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/issues/issue-62660.stderr b/src/test/ui/parser/issues/issue-62660.stderr
index be0b9a524df..14c0bdcb111 100644
--- a/src/test/ui/parser/issues/issue-62660.stderr
+++ b/src/test/ui/parser/issues/issue-62660.stderr
@@ -1,8 +1,8 @@
-error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, `=`, or `>`, found `)`
+error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)`
   --> $DIR/issue-62660.rs:7:38
    |
 LL |     pub fn foo(_: i32, self: Box<Self) {}
-   |                                      ^ expected one of 9 possible tokens
+   |                                      ^ expected one of 7 possible tokens
    |
 help: you might have meant to end the type parameters here
    |
diff --git a/src/test/ui/parser/issues/issue-84117.rs b/src/test/ui/parser/issues/issue-84117.rs
index 919585877cf..c9ebf133588 100644
--- a/src/test/ui/parser/issues/issue-84117.rs
+++ b/src/test/ui/parser/issues/issue-84117.rs
@@ -6,4 +6,4 @@ fn main() {
     //~| ERROR expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
     //~| ERROR expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
 }
-//~^ ERROR expected one of `,`, `:`, `=`, or `>`, found `}`
+//~^ ERROR expected one of `,` or `>`, found `}`
diff --git a/src/test/ui/parser/issues/issue-84117.stderr b/src/test/ui/parser/issues/issue-84117.stderr
index a2407affeef..237bc11bd06 100644
--- a/src/test/ui/parser/issues/issue-84117.stderr
+++ b/src/test/ui/parser/issues/issue-84117.stderr
@@ -21,11 +21,11 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, fo
 LL |     let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }
    |                                                                 ^ expected one of 8 possible tokens
 
-error: expected one of `,`, `:`, `=`, or `>`, found `}`
+error: expected one of `,` or `>`, found `}`
   --> $DIR/issue-84117.rs:8:1
    |
 LL |     let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }
-   |         ----------- while parsing the type for `outer_local`       - expected one of `,`, `:`, `=`, or `>`
+   |         ----------- while parsing the type for `outer_local`       - expected one of `,` or `>`
 ...
 LL | }
    | ^ unexpected token
diff --git a/src/test/ui/parser/issues/issue-93282.stderr b/src/test/ui/parser/issues/issue-93282.stderr
index 900f21a7cce..ee554784b3a 100644
--- a/src/test/ui/parser/issues/issue-93282.stderr
+++ b/src/test/ui/parser/issues/issue-93282.stderr
@@ -4,11 +4,11 @@ error: expected `while`, `for`, `loop` or `{` after a label
 LL |     f<'a,>
    |         ^ expected `while`, `for`, `loop` or `{` after a label
 
-error: expected one of `.`, `:`, `;`, `?`, `for`, `loop`, `while`, `{`, `}`, or an operator, found `,`
+error: expected one of `.`, `:`, `;`, `?`, `for`, `loop`, `while`, `}`, or an operator, found `,`
   --> $DIR/issue-93282.rs:2:9
    |
 LL |     f<'a,>
-   |         ^ expected one of 10 possible tokens
+   |         ^ expected one of 9 possible tokens
    |
 help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
    |
diff --git a/src/test/ui/parser/issues/issue-93867.rs b/src/test/ui/parser/issues/issue-93867.rs
new file mode 100644
index 00000000000..50744792391
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-93867.rs
@@ -0,0 +1,10 @@
+pub struct Entry<'a, K, V> {
+    k: &'a mut K,
+    v: V,
+}
+
+pub fn entry<'a, K, V>() -> Entry<'a K, V> {
+//                                  ^ missing comma
+//~^^ expected one of `,` or `>`, found `K`
+    unimplemented!()
+}
diff --git a/src/test/ui/parser/issues/issue-93867.stderr b/src/test/ui/parser/issues/issue-93867.stderr
new file mode 100644
index 00000000000..ee0cb4efd74
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-93867.stderr
@@ -0,0 +1,13 @@
+error: expected one of `,` or `>`, found `K`
+  --> $DIR/issue-93867.rs:6:38
+   |
+LL | pub fn entry<'a, K, V>() -> Entry<'a K, V> {
+   |                                      ^ expected one of `,` or `>`
+   |
+help: you might have meant to end the type parameters here
+   |
+LL | pub fn entry<'a, K, V>() -> Entry<'a> K, V> {
+   |                                     +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/lifetime-semicolon.fixed b/src/test/ui/parser/lifetime-semicolon.fixed
index 89e87fe9988..482b7704695 100644
--- a/src/test/ui/parser/lifetime-semicolon.fixed
+++ b/src/test/ui/parser/lifetime-semicolon.fixed
@@ -5,6 +5,6 @@ struct Foo<'a, 'b> {
 }
 
 fn foo<'a, 'b>(_x: &mut Foo<'a, 'b>) {}
-//~^ ERROR expected one of `,`, `:`, `=`, or `>`, found `;`
+//~^ ERROR expected one of `,` or `>`, found `;`
 
 fn main() {}
diff --git a/src/test/ui/parser/lifetime-semicolon.rs b/src/test/ui/parser/lifetime-semicolon.rs
index 744c93fc7c7..21c8b0a7f88 100644
--- a/src/test/ui/parser/lifetime-semicolon.rs
+++ b/src/test/ui/parser/lifetime-semicolon.rs
@@ -5,6 +5,6 @@ struct Foo<'a, 'b> {
 }
 
 fn foo<'a, 'b>(_x: &mut Foo<'a; 'b>) {}
-//~^ ERROR expected one of `,`, `:`, `=`, or `>`, found `;`
+//~^ ERROR expected one of `,` or `>`, found `;`
 
 fn main() {}
diff --git a/src/test/ui/parser/lifetime-semicolon.stderr b/src/test/ui/parser/lifetime-semicolon.stderr
index 5de7a5f2d5d..ee486c2366c 100644
--- a/src/test/ui/parser/lifetime-semicolon.stderr
+++ b/src/test/ui/parser/lifetime-semicolon.stderr
@@ -1,8 +1,8 @@
-error: expected one of `,`, `:`, `=`, or `>`, found `;`
+error: expected one of `,` or `>`, found `;`
   --> $DIR/lifetime-semicolon.rs:7:31
    |
 LL | fn foo<'a, 'b>(_x: &mut Foo<'a; 'b>) {}
-   |                               ^ expected one of `,`, `:`, `=`, or `>`
+   |                               ^ expected one of `,` or `>`
    |
 help: use a comma to separate type parameters
    |
diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.stderr b/src/test/ui/parser/require-parens-for-chained-comparison.stderr
index 92d700753dc..0bf52854ec2 100644
--- a/src/test/ui/parser/require-parens-for-chained-comparison.stderr
+++ b/src/test/ui/parser/require-parens-for-chained-comparison.stderr
@@ -59,11 +59,11 @@ error: expected `while`, `for`, `loop` or `{` after a label
 LL |     let _ = f<'_, i8>();
    |                 ^ expected `while`, `for`, `loop` or `{` after a label
 
-error: expected one of `.`, `:`, `;`, `?`, `else`, `for`, `loop`, `while`, `{`, or an operator, found `,`
+error: expected one of `.`, `:`, `;`, `?`, `else`, `for`, `loop`, `while`, or an operator, found `,`
   --> $DIR/require-parens-for-chained-comparison.rs:22:17
    |
 LL |     let _ = f<'_, i8>();
-   |                 ^ expected one of 10 possible tokens
+   |                 ^ expected one of 9 possible tokens
    |
 help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
    |
diff --git a/src/test/ui/typeck/issue-74086.rs b/src/test/ui/typeck/issue-74086.rs
index 44ca256b051..9b7c0d7cc6e 100644
--- a/src/test/ui/typeck/issue-74086.rs
+++ b/src/test/ui/typeck/issue-74086.rs
@@ -1,4 +1,5 @@
 fn main() {
     static BUG: fn(_) -> u8 = |_| 8;
     //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions [E0121]
+    //~| ERROR the placeholder `_` is not allowed within types on item signatures for static items
 }
diff --git a/src/test/ui/typeck/issue-74086.stderr b/src/test/ui/typeck/issue-74086.stderr
index e7aea33758c..95ebf9a906c 100644
--- a/src/test/ui/typeck/issue-74086.stderr
+++ b/src/test/ui/typeck/issue-74086.stderr
@@ -4,6 +4,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL |     static BUG: fn(_) -> u8 = |_| 8;
    |                    ^ not allowed in type signatures
 
-error: aborting due to previous error
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items
+  --> $DIR/issue-74086.rs:2:20
+   |
+LL |     static BUG: fn(_) -> u8 = |_| 8;
+   |                    ^ not allowed in type signatures
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/typeck/issue-81885.rs b/src/test/ui/typeck/issue-81885.rs
index 8935535fb7e..fb3949478a4 100644
--- a/src/test/ui/typeck/issue-81885.rs
+++ b/src/test/ui/typeck/issue-81885.rs
@@ -1,8 +1,9 @@
 const TEST4: fn() -> _ = 42;
                   //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+                  //~| ERROR the placeholder `_` is not allowed within types on item signatures for constant items
 
 fn main() {
     const TEST5: fn() -> _ = 42;
                       //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
-
+                      //~| ERROR the placeholder `_` is not allowed within types on item signatures for constant items
 }
diff --git a/src/test/ui/typeck/issue-81885.stderr b/src/test/ui/typeck/issue-81885.stderr
index 3ff4375cd8d..91c08bd8235 100644
--- a/src/test/ui/typeck/issue-81885.stderr
+++ b/src/test/ui/typeck/issue-81885.stderr
@@ -4,12 +4,24 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL | const TEST4: fn() -> _ = 42;
    |                      ^ not allowed in type signatures
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items
+  --> $DIR/issue-81885.rs:1:22
+   |
+LL | const TEST4: fn() -> _ = 42;
+   |                      ^ not allowed in type signatures
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/issue-81885.rs:5:26
+  --> $DIR/issue-81885.rs:6:26
+   |
+LL |     const TEST5: fn() -> _ = 42;
+   |                          ^ not allowed in type signatures
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items
+  --> $DIR/issue-81885.rs:6:26
    |
 LL |     const TEST5: fn() -> _ = 42;
    |                          ^ not allowed in type signatures
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/typeck/issue-88643.rs b/src/test/ui/typeck/issue-88643.rs
new file mode 100644
index 00000000000..4435cba0207
--- /dev/null
+++ b/src/test/ui/typeck/issue-88643.rs
@@ -0,0 +1,19 @@
+// Regression test for the ICE described in #88643. Specifically:
+// https://github.com/rust-lang/rust/issues/88643#issuecomment-913128893
+// and https://github.com/rust-lang/rust/issues/88643#issuecomment-913171935
+// and https://github.com/rust-lang/rust/issues/88643#issuecomment-913765984
+
+use std::collections::HashMap;
+
+pub trait T {}
+
+static CALLBACKS: HashMap<*const dyn T, dyn FnMut(&mut _) + 'static> = HashMap::new();
+//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static items [E0121]
+
+static CALLBACKS2: Vec<dyn Fn(& _)> = Vec::new();
+//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static items [E0121]
+
+static CALLBACKS3: Option<dyn Fn(& _)> = None;
+//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static items [E0121]
+
+fn main() {}
diff --git a/src/test/ui/typeck/issue-88643.stderr b/src/test/ui/typeck/issue-88643.stderr
new file mode 100644
index 00000000000..d5d596b6f42
--- /dev/null
+++ b/src/test/ui/typeck/issue-88643.stderr
@@ -0,0 +1,21 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items
+  --> $DIR/issue-88643.rs:10:56
+   |
+LL | static CALLBACKS: HashMap<*const dyn T, dyn FnMut(&mut _) + 'static> = HashMap::new();
+   |                                                        ^ not allowed in type signatures
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items
+  --> $DIR/issue-88643.rs:13:33
+   |
+LL | static CALLBACKS2: Vec<dyn Fn(& _)> = Vec::new();
+   |                                 ^ not allowed in type signatures
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items
+  --> $DIR/issue-88643.rs:16:36
+   |
+LL | static CALLBACKS3: Option<dyn Fn(& _)> = None;
+   |                                    ^ not allowed in type signatures
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.rs b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs
index 53f31b683c1..c459d8c3cdc 100644
--- a/src/test/ui/typeck/typeck_type_placeholder_item_help.rs
+++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs
@@ -12,6 +12,7 @@ const TEST3: _ = Some(42);
 
 const TEST4: fn() -> _ = 42;
 //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+//~| ERROR the placeholder `_` is not allowed within types on item signatures for constant items
 
 trait Test5 {
     const TEST5: _ = 42;
diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr
index e8191832318..07a5dbd93c7 100644
--- a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr
+++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr
@@ -31,8 +31,14 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL | const TEST4: fn() -> _ = 42;
    |                      ^ not allowed in type signatures
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items
+  --> $DIR/typeck_type_placeholder_item_help.rs:13:22
+   |
+LL | const TEST4: fn() -> _ = 42;
+   |                      ^ not allowed in type signatures
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
-  --> $DIR/typeck_type_placeholder_item_help.rs:17:18
+  --> $DIR/typeck_type_placeholder_item_help.rs:18:18
    |
 LL |     const TEST5: _ = 42;
    |                  ^
@@ -41,7 +47,7 @@ LL |     const TEST5: _ = 42;
    |                  help: replace with the correct type: `i32`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
-  --> $DIR/typeck_type_placeholder_item_help.rs:24:18
+  --> $DIR/typeck_type_placeholder_item_help.rs:25:18
    |
 LL |     const TEST6: _ = 13;
    |                  ^
@@ -49,6 +55,6 @@ LL |     const TEST6: _ = 13;
    |                  not allowed in type signatures
    |                  help: replace with the correct type: `i32`
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0121`.
diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs
index faded7c8024..bc2946e2c13 100644
--- a/src/tools/compiletest/src/raise_fd_limit.rs
+++ b/src/tools/compiletest/src/raise_fd_limit.rs
@@ -4,7 +4,7 @@
 /// on the number of cores available.
 ///
 /// This fixes issue #7772.
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
 #[allow(non_camel_case_types)]
 pub unsafe fn raise_fd_limit() {
     use std::cmp;
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index bed509d77be..215af347f17 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -31,6 +31,7 @@ const OS_TABLE: &[(&str, &str)] = &[
     ("redox", "redox"),
     ("sgx", "sgx"),
     ("solaris", "solaris"),
+    ("watchos", "watchos"),
     ("win32", "windows"),
     ("windows", "windows"),
     ("vxworks", "vxworks"),