about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-23 05:22:05 +0000
committerbors <bors@rust-lang.org>2022-08-23 05:22:05 +0000
commit38528d4dc0a0c079069764f23f11ef9f4fba2f95 (patch)
treee586ec664aa338e03b1dcdccf1e276e690697d82
parent7e3e8a816f91fda5c6e05c659d7038747aff0b55 (diff)
parent683a08af6a510c12c5df596de53046ba5afd2cfd (diff)
downloadrust-38528d4dc0a0c079069764f23f11ef9f4fba2f95.tar.gz
rust-38528d4dc0a0c079069764f23f11ef9f4fba2f95.zip
Auto merge of #100904 - matthiaskrgr:rollup-z3yzivj, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #100382 (Make the GATS self outlives error take into GATs in the inputs)
 - #100565 (Suggest adding a missing semicolon before an item)
 - #100641 (Add the armv4t-none-eabi target to the supported_targets)
 - #100789 (Use separate infcx to solve obligations during negative coherence)
 - #100832 (Some small bootstrap cleanup)
 - #100861 (fix ICE with extra-const-ub-checks)
 - #100862 (tidy: remove crossbeam-utils)
 - #100887 (Refactor part of codegen_call_terminator)
 - #100893 (Remove out-of-context comment in `mem::MaybeUninit` documentation)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_ast/src/token.rs24
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs91
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs22
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs12
-rw-r--r--compiler/rustc_const_eval/src/might_permit_raw_init.rs6
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs6
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs21
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs2
-rw-r--r--library/core/src/mem/maybe_uninit.rs7
-rw-r--r--src/bootstrap/dist.rs11
-rw-r--r--src/bootstrap/tool.rs19
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs7
-rw-r--r--src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr (renamed from src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr11
-rw-r--r--src/test/ui/consts/extra-const-ub/issue-100771.rs20
-rw-r--r--src/test/ui/generic-associated-types/self-outlives-lint.rs13
-rw-r--r--src/test/ui/generic-associated-types/self-outlives-lint.stderr13
-rw-r--r--src/test/ui/parser/recover-missing-semi-before-item.fixed61
-rw-r--r--src/test/ui/parser/recover-missing-semi-before-item.rs61
-rw-r--r--src/test/ui/parser/recover-missing-semi-before-item.stderr83
-rwxr-xr-xsrc/tools/publish_toolstate.py11
-rw-r--r--src/tools/tidy/Cargo.toml1
-rw-r--r--src/tools/tidy/src/main.rs7
26 files changed, 403 insertions, 111 deletions
diff --git a/Cargo.lock b/Cargo.lock
index cb245ce0ff8..ebacd32db4f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5295,7 +5295,6 @@ name = "tidy"
 version = "0.1.0"
 dependencies = [
  "cargo_metadata 0.14.0",
- "crossbeam-utils",
  "lazy_static",
  "regex",
  "walkdir",
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 85d9687c600..dd98946b4cc 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -436,6 +436,30 @@ impl Token {
             || self == &OpenDelim(Delimiter::Parenthesis)
     }
 
+    /// Returns `true` if the token can appear at the start of an item.
+    pub fn can_begin_item(&self) -> bool {
+        match self.kind {
+            Ident(name, _) => [
+                kw::Fn,
+                kw::Use,
+                kw::Struct,
+                kw::Enum,
+                kw::Pub,
+                kw::Trait,
+                kw::Extern,
+                kw::Impl,
+                kw::Unsafe,
+                kw::Static,
+                kw::Union,
+                kw::Macro,
+                kw::Mod,
+                kw::Type,
+            ]
+            .contains(&name),
+            _ => false,
+        }
+    }
+
     /// Returns `true` if the token is any literal.
     pub fn is_lit(&self) -> bool {
         matches!(self.kind, Literal(..))
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 3eee58d9d1c..47a40be5d8c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -798,58 +798,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let mut op = self.codegen_operand(&mut bx, arg);
 
             if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) {
-                if let Pair(..) = op.val {
-                    // In the case of Rc<Self>, we need to explicitly pass a
-                    // *mut RcBox<Self> with a Scalar (not ScalarPair) ABI. This is a hack
-                    // that is understood elsewhere in the compiler as a method on
-                    // `dyn Trait`.
-                    // To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until
-                    // we get a value of a built-in pointer type
-                    'descend_newtypes: while !op.layout.ty.is_unsafe_ptr()
-                        && !op.layout.ty.is_region_ptr()
-                    {
-                        for i in 0..op.layout.fields.count() {
-                            let field = op.extract_field(&mut bx, i);
-                            if !field.layout.is_zst() {
-                                // we found the one non-zero-sized field that is allowed
-                                // now find *its* non-zero-sized field, or stop if it's a
-                                // pointer
-                                op = field;
-                                continue 'descend_newtypes;
+                match op.val {
+                    Pair(data_ptr, meta) => {
+                        // In the case of Rc<Self>, we need to explicitly pass a
+                        // *mut RcBox<Self> with a Scalar (not ScalarPair) ABI. This is a hack
+                        // that is understood elsewhere in the compiler as a method on
+                        // `dyn Trait`.
+                        // To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until
+                        // we get a value of a built-in pointer type
+                        'descend_newtypes: while !op.layout.ty.is_unsafe_ptr()
+                            && !op.layout.ty.is_region_ptr()
+                        {
+                            for i in 0..op.layout.fields.count() {
+                                let field = op.extract_field(&mut bx, i);
+                                if !field.layout.is_zst() {
+                                    // we found the one non-zero-sized field that is allowed
+                                    // now find *its* non-zero-sized field, or stop if it's a
+                                    // pointer
+                                    op = field;
+                                    continue 'descend_newtypes;
+                                }
                             }
+
+                            span_bug!(span, "receiver has no non-zero-sized fields {:?}", op);
                         }
 
-                        span_bug!(span, "receiver has no non-zero-sized fields {:?}", op);
+                        // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
+                        // data pointer and vtable. Look up the method in the vtable, and pass
+                        // the data pointer as the first argument
+                        llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
+                            &mut bx,
+                            meta,
+                            op.layout.ty,
+                            &fn_abi,
+                        ));
+                        llargs.push(data_ptr);
+                        continue 'make_args;
                     }
-
-                    // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
-                    // data pointer and vtable. Look up the method in the vtable, and pass
-                    // the data pointer as the first argument
-                    match op.val {
-                        Pair(data_ptr, meta) => {
-                            llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
-                                &mut bx,
-                                meta,
-                                op.layout.ty,
-                                &fn_abi,
-                            ));
-                            llargs.push(data_ptr);
-                            continue 'make_args;
-                        }
-                        other => bug!("expected a Pair, got {:?}", other),
+                    Ref(data_ptr, Some(meta), _) => {
+                        // by-value dynamic dispatch
+                        llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
+                            &mut bx,
+                            meta,
+                            op.layout.ty,
+                            &fn_abi,
+                        ));
+                        llargs.push(data_ptr);
+                        continue;
                     }
-                } else if let Ref(data_ptr, Some(meta), _) = op.val {
-                    // by-value dynamic dispatch
-                    llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
-                        &mut bx,
-                        meta,
-                        op.layout.ty,
-                        &fn_abi,
-                    ));
-                    llargs.push(data_ptr);
-                    continue;
-                } else {
-                    span_bug!(span, "can't codegen a virtual call on {:?}", op);
+                    _ => span_bug!(span, "can't codegen a virtual call on {:?}", op),
                 }
             }
 
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 936044fbe24..5cfa63bd105 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -81,7 +81,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
 }
 
 /// The `InterpCx` is only meant to be used to do field and index projections into constants for
-/// `simd_shuffle` and const patterns in match arms.
+/// `simd_shuffle` and const patterns in match arms. It never performs alignment checks.
 ///
 /// The function containing the `match` that is currently being analyzed may have generic bounds
 /// that inform us about the generic bounds of the constant. E.g., using an associated constant
@@ -98,7 +98,11 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>(
         tcx,
         root_span,
         param_env,
-        CompileTimeInterpreter::new(tcx.const_eval_limit(), can_access_statics),
+        CompileTimeInterpreter::new(
+            tcx.const_eval_limit(),
+            can_access_statics,
+            /*check_alignment:*/ false,
+        ),
     )
 }
 
@@ -203,7 +207,13 @@ pub(crate) fn turn_into_const_value<'tcx>(
     let cid = key.value;
     let def_id = cid.instance.def.def_id();
     let is_static = tcx.is_static(def_id);
-    let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static);
+    // This is just accessing an already computed constant, so no need to check alginment here.
+    let ecx = mk_eval_cx(
+        tcx,
+        tcx.def_span(key.value.instance.def_id()),
+        key.param_env,
+        /*can_access_statics:*/ is_static,
+    );
 
     let mplace = ecx.raw_const_to_mplace(constant).expect(
         "can only fail if layout computation failed, \
@@ -300,7 +310,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
         key.param_env,
         // Statics (and promoteds inside statics) may access other statics, because unlike consts
         // they do not have to behave "as if" they were evaluated at runtime.
-        CompileTimeInterpreter::new(tcx.const_eval_limit(), /*can_access_statics:*/ is_static),
+        CompileTimeInterpreter::new(
+            tcx.const_eval_limit(),
+            /*can_access_statics:*/ is_static,
+            /*check_alignment:*/ tcx.sess.opts.unstable_opts.extra_const_ub_checks,
+        ),
     );
 
     let res = ecx.load_mir(cid.instance.def, cid.promoted);
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 684877cae76..f24b19089c1 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -101,14 +101,22 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
     /// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
     /// This boolean here controls the second part.
     pub(super) can_access_statics: bool,
+
+    /// Whether to check alignment during evaluation.
+    check_alignment: bool,
 }
 
 impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
-    pub(crate) fn new(const_eval_limit: Limit, can_access_statics: bool) -> Self {
+    pub(crate) fn new(
+        const_eval_limit: Limit,
+        can_access_statics: bool,
+        check_alignment: bool,
+    ) -> Self {
         CompileTimeInterpreter {
             steps_remaining: const_eval_limit.0,
             stack: Vec::new(),
             can_access_statics,
+            check_alignment,
         }
     }
 }
@@ -238,7 +246,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
 
     #[inline(always)]
     fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
-        ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
+        ecx.machine.check_alignment
     }
 
     #[inline(always)]
diff --git a/compiler/rustc_const_eval/src/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/might_permit_raw_init.rs
index f971c2238c7..37ffa19ccd6 100644
--- a/compiler/rustc_const_eval/src/might_permit_raw_init.rs
+++ b/compiler/rustc_const_eval/src/might_permit_raw_init.rs
@@ -13,7 +13,11 @@ pub fn might_permit_raw_init<'tcx>(
     let strict = tcx.sess.opts.unstable_opts.strict_init_checks;
 
     if strict {
-        let machine = CompileTimeInterpreter::new(Limit::new(0), false);
+        let machine = CompileTimeInterpreter::new(
+            Limit::new(0),
+            /*can_access_statics:*/ false,
+            /*check_alignment:*/ true,
+        );
 
         let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
 
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 2c9f9a2c2c2..b8884dd32d6 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -927,10 +927,12 @@ impl<'a> Parser<'a> {
                 return Ok(true);
             } else if self.look_ahead(0, |t| {
                 t == &token::CloseDelim(Delimiter::Brace)
-                    || (t.can_begin_expr() && t != &token::Semi && t != &token::Pound)
+                    || ((t.can_begin_expr() || t.can_begin_item())
+                        && t != &token::Semi
+                        && t != &token::Pound)
                     // Avoid triggering with too many trailing `#` in raw string.
                     || (sm.is_multiline(
-                        self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo())
+                        self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()),
                     ) && t == &token::Pound)
             }) && !expected.contains(&TokenType::Token(token::Comma))
             {
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 0b49edc232c..cf6cb75d49a 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1028,6 +1028,7 @@ supported_targets! {
     ("mipsel-sony-psp", mipsel_sony_psp),
     ("mipsel-unknown-none", mipsel_unknown_none),
     ("thumbv4t-none-eabi", thumbv4t_none_eabi),
+    ("armv4t-none-eabi", armv4t_none_eabi),
 
     ("aarch64_be-unknown-linux-gnu", aarch64_be_unknown_linux_gnu),
     ("aarch64-unknown-linux-gnu_ilp32", aarch64_unknown_linux_gnu_ilp32),
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 985600d9ebc..3bc08fba91a 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -342,10 +342,8 @@ fn equate<'cx, 'tcx>(
     };
 
     let selcx = &mut SelectionContext::new(&infcx);
-    let opt_failing_obligation = obligations
-        .into_iter()
-        .chain(more_obligations)
-        .find(|o| negative_impl_exists(selcx, impl_env, o));
+    let opt_failing_obligation =
+        obligations.into_iter().chain(more_obligations).find(|o| negative_impl_exists(selcx, o));
 
     if let Some(failing_obligation) = opt_failing_obligation {
         debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
@@ -359,18 +357,15 @@ fn equate<'cx, 'tcx>(
 #[instrument(level = "debug", skip(selcx))]
 fn negative_impl_exists<'cx, 'tcx>(
     selcx: &SelectionContext<'cx, 'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
     o: &PredicateObligation<'tcx>,
 ) -> bool {
-    let infcx = &selcx.infcx().fork();
-
-    if resolve_negative_obligation(infcx, param_env, o) {
+    if resolve_negative_obligation(selcx.infcx().fork(), o) {
         return true;
     }
 
     // Try to prove a negative obligation exists for super predicates
-    for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) {
-        if resolve_negative_obligation(infcx, param_env, &o) {
+    for o in util::elaborate_predicates(selcx.tcx(), iter::once(o.predicate)) {
+        if resolve_negative_obligation(selcx.infcx().fork(), &o) {
             return true;
         }
     }
@@ -380,8 +375,7 @@ fn negative_impl_exists<'cx, 'tcx>(
 
 #[instrument(level = "debug", skip(infcx))]
 fn resolve_negative_obligation<'cx, 'tcx>(
-    infcx: &InferCtxt<'cx, 'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
+    infcx: InferCtxt<'cx, 'tcx>,
     o: &PredicateObligation<'tcx>,
 ) -> bool {
     let tcx = infcx.tcx;
@@ -390,7 +384,8 @@ fn resolve_negative_obligation<'cx, 'tcx>(
         return false;
     };
 
-    let errors = super::fully_solve_obligation(infcx, o);
+    let param_env = o.param_env;
+    let errors = super::fully_solve_obligation(&infcx, o);
     if !errors.is_empty() {
         return false;
     }
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index ed653f0f9c8..e8243d666b6 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -387,7 +387,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
                             tcx,
                             param_env,
                             item_hir_id,
-                            sig.output(),
+                            sig.inputs_and_output,
                             // We also assume that all of the function signature's parameter types
                             // are well formed.
                             &sig.inputs().iter().copied().collect(),
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index b4ea5360833..997494c769e 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -130,11 +130,8 @@ use crate::slice;
 ///         MaybeUninit::uninit().assume_init()
 ///     };
 ///
-///     // Dropping a `MaybeUninit` does nothing. Thus using raw pointer
-///     // assignment instead of `ptr::write` does not cause the old
-///     // uninitialized value to be dropped. Also if there is a panic during
-///     // this loop, we have a memory leak, but there is no memory safety
-///     // issue.
+///     // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
+///     // we have a memory leak, but there is no memory safety issue.
 ///     for elem in &mut data[..] {
 ///         elem.write(vec![42]);
 ///     }
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 6291b204e48..6bf57a89e89 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1226,17 +1226,10 @@ impl Step for Rustfmt {
 
         let rustfmt = builder
             .ensure(tool::Rustfmt { compiler, target, extra_features: Vec::new() })
-            .or_else(|| {
-                missing_tool("Rustfmt", builder.build.config.missing_tools);
-                None
-            })?;
+            .expect("rustfmt expected to build - essential tool");
         let cargofmt = builder
             .ensure(tool::Cargofmt { compiler, target, extra_features: Vec::new() })
-            .or_else(|| {
-                missing_tool("Cargofmt", builder.build.config.missing_tools);
-                None
-            })?;
-
+            .expect("cargo fmt expected to build - essential tool");
         let mut tarball = Tarball::new(builder, "rustfmt", &target.triple);
         tarball.set_overlay(OverlayKind::Rustfmt);
         tarball.is_preview(true);
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 06fa5039fdf..570da20e7d6 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -778,12 +778,10 @@ impl Step for RustAnalyzerProcMacroSrv {
 macro_rules! tool_extended {
     (($sel:ident, $builder:ident),
        $($name:ident,
-       $toolstate:ident,
        $path:expr,
        $tool_name:expr,
        stable = $stable:expr,
        $(in_tree = $in_tree:expr,)?
-       $(submodule = $submodule:literal,)?
        $(tool_std = $tool_std:literal,)?
        $extra_deps:block;)+) => {
         $(
@@ -828,7 +826,6 @@ macro_rules! tool_extended {
             #[allow(unused_mut)]
             fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
                 $extra_deps
-                $( $builder.update_submodule(&Path::new("src").join("tools").join($submodule)); )?
                 $builder.ensure(ToolBuild {
                     compiler: $sel.compiler,
                     target: $sel.target,
@@ -854,12 +851,12 @@ macro_rules! tool_extended {
 // Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to
 // invoke Cargo to build bootstrap. See the comment there for more details.
 tool_extended!((self, builder),
-    Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {};
-    CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
-    Clippy, clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {};
-    Miri, miri, "src/tools/miri", "miri", stable=false, {};
-    CargoMiri, miri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {};
-    Rls, rls, "src/tools/rls", "rls", stable=true, {
+    Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {};
+    CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
+    Clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {};
+    Miri, "src/tools/miri", "miri", stable=false, {};
+    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {};
+    Rls, "src/tools/rls", "rls", stable=true, {
         builder.ensure(Clippy {
             compiler: self.compiler,
             target: self.target,
@@ -870,8 +867,8 @@ tool_extended!((self, builder),
     // FIXME: tool_std is not quite right, we shouldn't allow nightly features.
     // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0,
     // and this is close enough for now.
-    RustDemangler, rust_demangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {};
-    Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {};
+    RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {};
+    Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {};
 );
 
 impl<'a> Builder<'a> {
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 01489e9aafb..f0f57f93386 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -223,6 +223,7 @@ target | std | host | notes
 `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-none-eabi` | * |  | ARMv4T A32
 `armv4t-unknown-linux-gnueabi` | ? |  |
 `armv5te-unknown-linux-uclibceabi` | ? |  | ARMv5TE Linux with uClibc
 `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs
index 159788b1b77..221c1bc23b3 100644
--- a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs
+++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs
@@ -1,10 +1,15 @@
+// revisions: stock with_negative_coherence
 #![feature(negative_impls)]
+#![cfg_attr(with_negative_coherence, feature(with_negative_coherence))]
 
 // FIXME: this should compile
 
 trait MyPredicate<'a> {}
-impl<'a, T> !MyPredicate<'a> for &T where T: 'a {}
+
+impl<'a, T> !MyPredicate<'a> for &'a T where T: 'a {}
+
 trait MyTrait<'a> {}
+
 impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
 impl<'a, T> MyTrait<'a> for &'a T {}
 //~^ ERROR: conflicting implementations of trait `MyTrait<'_>` for type `&_`
diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
index 263bd19b424..097cc4e0fe3 100644
--- a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr
+++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_`
-  --> $DIR/coherence-negative-outlives-lifetimes.rs:9:1
+  --> $DIR/coherence-negative-outlives-lifetimes.rs:14:1
    |
 LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
    | ---------------------------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr
new file mode 100644
index 00000000000..097cc4e0fe3
--- /dev/null
+++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr
@@ -0,0 +1,11 @@
+error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_`
+  --> $DIR/coherence-negative-outlives-lifetimes.rs:14:1
+   |
+LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
+   | ---------------------------------------------- first implementation here
+LL | impl<'a, T> MyTrait<'a> for &'a T {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/consts/extra-const-ub/issue-100771.rs b/src/test/ui/consts/extra-const-ub/issue-100771.rs
new file mode 100644
index 00000000000..a3296032841
--- /dev/null
+++ b/src/test/ui/consts/extra-const-ub/issue-100771.rs
@@ -0,0 +1,20 @@
+// check-pass
+// compile-flags: -Zextra-const-ub-checks
+
+#[derive(PartialEq, Eq, Copy, Clone)]
+#[repr(packed)]
+struct Foo {
+    field: (i64, u32, u32, u32),
+}
+
+const FOO: Foo = Foo {
+    field: (5, 6, 7, 8),
+};
+
+fn main() {
+    match FOO {
+        Foo { field: (5, 6, 7, 8) } => {},
+        FOO => unreachable!(),
+        _ => unreachable!(),
+    }
+}
diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.rs b/src/test/ui/generic-associated-types/self-outlives-lint.rs
index 300907adbfc..9bb42d4ff1c 100644
--- a/src/test/ui/generic-associated-types/self-outlives-lint.rs
+++ b/src/test/ui/generic-associated-types/self-outlives-lint.rs
@@ -210,4 +210,17 @@ trait StaticReturnAndTakes<'a> {
     fn bar<'b>(&self, arg: Self::Y<'b>);
 }
 
+// We require bounds when the GAT appears in the inputs
+trait Input {
+    type Item<'a>;
+    //~^ missing required
+    fn takes_item<'a>(&'a self, item: Self::Item<'a>);
+}
+
+// We don't require bounds when the GAT appears in the where clauses
+trait WhereClause {
+    type Item<'a>;
+    fn takes_item<'a>(&'a self) where Self::Item<'a>: ;
+}
+
 fn main() {}
diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.stderr b/src/test/ui/generic-associated-types/self-outlives-lint.stderr
index fdb1f50a776..a43b35bd79c 100644
--- a/src/test/ui/generic-associated-types/self-outlives-lint.stderr
+++ b/src/test/ui/generic-associated-types/self-outlives-lint.stderr
@@ -163,5 +163,16 @@ LL |     type Fut<'out>;
    = note: this bound is currently required to ensure that impls have maximum flexibility
    = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
 
-error: aborting due to 15 previous errors
+error: missing required bound on `Item`
+  --> $DIR/self-outlives-lint.rs:215:5
+   |
+LL |     type Item<'a>;
+   |     ^^^^^^^^^^^^^-
+   |                  |
+   |                  help: add the required where clause: `where Self: 'a`
+   |
+   = note: this bound is currently required to ensure that impls have maximum flexibility
+   = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: aborting due to 16 previous errors
 
diff --git a/src/test/ui/parser/recover-missing-semi-before-item.fixed b/src/test/ui/parser/recover-missing-semi-before-item.fixed
new file mode 100644
index 00000000000..0be17e69e8f
--- /dev/null
+++ b/src/test/ui/parser/recover-missing-semi-before-item.fixed
@@ -0,0 +1,61 @@
+// run-rustfix
+
+#![allow(unused_variables, dead_code)]
+
+fn for_struct() {
+    let foo = 3; //~ ERROR expected `;`, found keyword `struct`
+    struct Foo;
+}
+
+fn for_union() {
+    let foo = 3; //~ ERROR expected `;`, found `union`
+    union Foo {
+        foo: usize,
+    }
+}
+
+fn for_enum() {
+    let foo = 3; //~ ERROR expected `;`, found keyword `enum`
+    enum Foo {
+        Bar,
+    }
+}
+
+fn for_fn() {
+    let foo = 3; //~ ERROR expected `;`, found keyword `fn`
+    fn foo() {}
+}
+
+fn for_extern() {
+    let foo = 3; //~ ERROR expected `;`, found keyword `extern`
+    extern fn foo() {}
+}
+
+fn for_impl() {
+    struct Foo;
+    let foo = 3; //~ ERROR expected `;`, found keyword `impl`
+    impl Foo {}
+}
+
+fn for_use() {
+    let foo = 3; //~ ERROR expected `;`, found keyword `pub`
+    pub use bar::Bar;
+}
+
+fn for_mod() {
+    let foo = 3; //~ ERROR expected `;`, found keyword `mod`
+    mod foo {}
+}
+
+fn for_type() {
+    let foo = 3; //~ ERROR expected `;`, found keyword `type`
+    type Foo = usize;
+}
+
+mod bar {
+    pub struct Bar;
+}
+
+const X: i32 = 123; //~ ERROR expected `;`, found keyword `fn`
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-missing-semi-before-item.rs b/src/test/ui/parser/recover-missing-semi-before-item.rs
new file mode 100644
index 00000000000..867b7b749bb
--- /dev/null
+++ b/src/test/ui/parser/recover-missing-semi-before-item.rs
@@ -0,0 +1,61 @@
+// run-rustfix
+
+#![allow(unused_variables, dead_code)]
+
+fn for_struct() {
+    let foo = 3 //~ ERROR expected `;`, found keyword `struct`
+    struct Foo;
+}
+
+fn for_union() {
+    let foo = 3 //~ ERROR expected `;`, found `union`
+    union Foo {
+        foo: usize,
+    }
+}
+
+fn for_enum() {
+    let foo = 3 //~ ERROR expected `;`, found keyword `enum`
+    enum Foo {
+        Bar,
+    }
+}
+
+fn for_fn() {
+    let foo = 3 //~ ERROR expected `;`, found keyword `fn`
+    fn foo() {}
+}
+
+fn for_extern() {
+    let foo = 3 //~ ERROR expected `;`, found keyword `extern`
+    extern fn foo() {}
+}
+
+fn for_impl() {
+    struct Foo;
+    let foo = 3 //~ ERROR expected `;`, found keyword `impl`
+    impl Foo {}
+}
+
+fn for_use() {
+    let foo = 3 //~ ERROR expected `;`, found keyword `pub`
+    pub use bar::Bar;
+}
+
+fn for_mod() {
+    let foo = 3 //~ ERROR expected `;`, found keyword `mod`
+    mod foo {}
+}
+
+fn for_type() {
+    let foo = 3 //~ ERROR expected `;`, found keyword `type`
+    type Foo = usize;
+}
+
+mod bar {
+    pub struct Bar;
+}
+
+const X: i32 = 123 //~ ERROR expected `;`, found keyword `fn`
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-missing-semi-before-item.stderr b/src/test/ui/parser/recover-missing-semi-before-item.stderr
new file mode 100644
index 00000000000..61c43f2f189
--- /dev/null
+++ b/src/test/ui/parser/recover-missing-semi-before-item.stderr
@@ -0,0 +1,83 @@
+error: expected `;`, found keyword `struct`
+  --> $DIR/recover-missing-semi-before-item.rs:6:16
+   |
+LL |     let foo = 3
+   |                ^ help: add `;` here
+LL |     struct Foo;
+   |     ------ unexpected token
+
+error: expected `;`, found `union`
+  --> $DIR/recover-missing-semi-before-item.rs:11:16
+   |
+LL |     let foo = 3
+   |                ^ help: add `;` here
+LL |     union Foo {
+   |     ----- unexpected token
+
+error: expected `;`, found keyword `enum`
+  --> $DIR/recover-missing-semi-before-item.rs:18:16
+   |
+LL |     let foo = 3
+   |                ^ help: add `;` here
+LL |     enum Foo {
+   |     ---- unexpected token
+
+error: expected `;`, found keyword `fn`
+  --> $DIR/recover-missing-semi-before-item.rs:25:16
+   |
+LL |     let foo = 3
+   |                ^ help: add `;` here
+LL |     fn foo() {}
+   |     -- unexpected token
+
+error: expected `;`, found keyword `extern`
+  --> $DIR/recover-missing-semi-before-item.rs:30:16
+   |
+LL |     let foo = 3
+   |                ^ help: add `;` here
+LL |     extern fn foo() {}
+   |     ------ unexpected token
+
+error: expected `;`, found keyword `impl`
+  --> $DIR/recover-missing-semi-before-item.rs:36:16
+   |
+LL |     let foo = 3
+   |                ^ help: add `;` here
+LL |     impl Foo {}
+   |     ---- unexpected token
+
+error: expected `;`, found keyword `pub`
+  --> $DIR/recover-missing-semi-before-item.rs:41:16
+   |
+LL |     let foo = 3
+   |                ^ help: add `;` here
+LL |     pub use bar::Bar;
+   |     --- unexpected token
+
+error: expected `;`, found keyword `mod`
+  --> $DIR/recover-missing-semi-before-item.rs:46:16
+   |
+LL |     let foo = 3
+   |                ^ help: add `;` here
+LL |     mod foo {}
+   |     --- unexpected token
+
+error: expected `;`, found keyword `type`
+  --> $DIR/recover-missing-semi-before-item.rs:51:16
+   |
+LL |     let foo = 3
+   |                ^ help: add `;` here
+LL |     type Foo = usize;
+   |     ---- unexpected token
+
+error: expected `;`, found keyword `fn`
+  --> $DIR/recover-missing-semi-before-item.rs:59:19
+   |
+LL | const X: i32 = 123
+   |                   ^ help: add `;` here
+LL |
+LL | fn main() {}
+   | -- unexpected token
+
+error: aborting due to 10 previous errors
+
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index fe5195738c1..1c57b731aaa 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -32,20 +32,18 @@ except ImportError:
 MAINTAINERS = {
     'miri': {'oli-obk', 'RalfJung'},
     'rls': {'Xanewok'},
-    'rustfmt': {'topecongiro', 'calebcartwright'},
-    'book': {'carols10cents', 'steveklabnik'},
+    'book': {'carols10cents'},
     'nomicon': {'frewsxcv', 'Gankra', 'JohnTitor'},
-    'reference': {'steveklabnik', 'Havvy', 'matthewjasper', 'ehuss'},
-    'rust-by-example': {'steveklabnik', 'marioidival'},
+    'reference': {'Havvy', 'matthewjasper', 'ehuss'},
+    'rust-by-example': {'marioidival'},
     'embedded-book': {'adamgreig', 'andre-richter', 'jamesmunns', 'therealprof'},
-    'edition-guide': {'ehuss', 'steveklabnik'},
+    'edition-guide': {'ehuss'},
     'rustc-dev-guide': {'spastorino', 'amanjeev', 'JohnTitor'},
 }
 
 LABELS = {
     'miri': ['A-miri', 'C-bug'],
     'rls': ['A-rls', 'C-bug'],
-    'rustfmt': ['A-rustfmt', 'C-bug'],
     'book': ['C-bug'],
     'nomicon': ['C-bug'],
     'reference': ['C-bug'],
@@ -58,7 +56,6 @@ LABELS = {
 REPOS = {
     'miri': 'https://github.com/rust-lang/miri',
     'rls': 'https://github.com/rust-lang/rls',
-    'rustfmt': 'https://github.com/rust-lang/rustfmt',
     'book': 'https://github.com/rust-lang/book',
     'nomicon': 'https://github.com/rust-lang/nomicon',
     'reference': 'https://github.com/rust-lang/reference',
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 96ab42b4719..471d78a2922 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -9,7 +9,6 @@ cargo_metadata = "0.14"
 regex = "1"
 lazy_static = "1"
 walkdir = "2"
-crossbeam-utils = "0.8.0"
 
 [[bin]]
 name = "rust-tidy"
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index aa8d8b4f64d..c1ce94f4705 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -6,7 +6,6 @@
 
 use tidy::*;
 
-use crossbeam_utils::thread::{scope, ScopedJoinHandle};
 use std::collections::VecDeque;
 use std::env;
 use std::num::NonZeroUsize;
@@ -14,6 +13,7 @@ use std::path::PathBuf;
 use std::process;
 use std::str::FromStr;
 use std::sync::atomic::{AtomicBool, Ordering};
+use std::thread::{scope, ScopedJoinHandle};
 
 fn main() {
     let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into();
@@ -44,7 +44,7 @@ fn main() {
                     handles.pop_front().unwrap().join().unwrap();
                 }
 
-                let handle = s.spawn(|_| {
+                let handle = s.spawn(|| {
                     let mut flag = false;
                     $p::check($($args),* , &mut flag);
                     if (flag) {
@@ -102,8 +102,7 @@ fn main() {
             r
         };
         check!(unstable_book, &src_path, collected);
-    })
-    .unwrap();
+    });
 
     if bad.load(Ordering::Relaxed) {
         eprintln!("some tidy checks failed");