about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-05-03 20:02:30 +0000
committerbors <bors@rust-lang.org>2023-05-03 20:02:30 +0000
commit473f916d836cc662c5bdbb0d40af9fb4678fab9e (patch)
tree481cdfed5453e25afbf102e9b4a420688711da61
parent9b99ff76b28605ad2e2c49e369721ae400e6a665 (diff)
parentb5bbe68fbb6da7f36314ef2f241914227ab72f0e (diff)
downloadrust-473f916d836cc662c5bdbb0d40af9fb4678fab9e.tar.gz
rust-473f916d836cc662c5bdbb0d40af9fb4678fab9e.zip
Auto merge of #111153 - Dylan-DPC:rollup-0pq0hh3, r=Dylan-DPC
Rollup of 11 pull requests

Successful merges:

 - #107978 (Correctly convert an NT path to a Win32 path in `read_link`)
 - #110436 (Support loading version information from xz tarballs)
 - #110791 (Implement negative bounds for internal testing purposes)
 - #110874 (Adjust obligation cause code for `find_and_report_unsatisfied_index_impl`)
 - #110908 (resolve: One more attempt to simplify `module_children`)
 - #110943 (interpret: fail more gracefully on uninit unsized locals)
 - #111062 (Don't bail out early when checking invalid `repr` attr)
 - #111069 (remove pointless `FIXME` in `bootstrap::download`)
 - #111086 (Remove `MemEncoder`)
 - #111097 (Avoid ICEing miri on layout query cycles)
 - #111112 (Add some triagebot notifications for nnethercote.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock10
-rw-r--r--compiler/rustc_ast/src/ast.rs18
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs17
-rw-r--r--compiler/rustc_ast_passes/messages.ftl8
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs17
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs15
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs6
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs10
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs6
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/bounds.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs25
-rw-r--r--compiler/rustc_infer/src/traits/util.rs4
-rw-r--r--compiler/rustc_interface/src/queries.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs16
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs6
-rw-r--r--compiler/rustc_middle/messages.ftl3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs21
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs5
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs3
-rw-r--r--compiler/rustc_middle/src/values.rs6
-rw-r--r--compiler/rustc_parse/messages.ftl10
-rw-r--r--compiler/rustc_parse/src/errors.rs31
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs2
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs4
-rw-r--r--compiler/rustc_parse/src/parser/item.rs10
-rw-r--r--compiler/rustc_parse/src/parser/path.rs2
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs125
-rw-r--r--compiler/rustc_passes/src/check_attr.rs8
-rw-r--r--compiler/rustc_privacy/src/lib.rs8
-rw-r--r--compiler/rustc_resolve/src/imports.rs19
-rw-r--r--compiler/rustc_resolve/src/lib.rs9
-rw-r--r--compiler/rustc_serialize/Cargo.toml1
-rw-r--r--compiler/rustc_serialize/src/opaque.rs129
-rw-r--r--compiler/rustc_serialize/tests/opaque.rs56
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs15
-rw-r--r--library/std/src/fs/tests.rs6
-rw-r--r--library/std/src/sys/windows/args.rs5
-rw-r--r--library/std/src/sys/windows/fs.rs29
-rw-r--r--src/bootstrap/download.rs1
-rw-r--r--src/librustdoc/clean/inline.rs3
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/html/format.rs1
-rw-r--r--src/librustdoc/html/templates/type_layout.html93
-rw-r--r--src/librustdoc/json/conversions.rs4
-rw-r--r--src/librustdoc/visit_ast.rs9
-rw-r--r--src/tools/build-manifest/Cargo.toml1
-rw-r--r--src/tools/build-manifest/src/versions.rs28
-rw-r--r--src/tools/miri/tests/fail/layout_cycle.rs28
-rw-r--r--src/tools/miri/tests/fail/layout_cycle.stderr28
-rw-r--r--src/tools/rustfmt/src/types.rs6
-rw-r--r--src/tools/rustfmt/tests/target/negative-bounds.rs11
-rw-r--r--tests/ui-fulldeps/deriving-encodable-decodable-box.rs34
-rw-r--r--tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs44
-rw-r--r--tests/ui-fulldeps/issue-14021.rs33
-rw-r--r--tests/ui/const_prop/const-prop-ice.rs (renamed from tests/ui/consts/const-prop-ice.rs)0
-rw-r--r--tests/ui/const_prop/const-prop-ice.stderr (renamed from tests/ui/consts/const-prop-ice.stderr)0
-rw-r--r--tests/ui/const_prop/const-prop-ice2.rs (renamed from tests/ui/consts/const-prop-ice2.rs)0
-rw-r--r--tests/ui/const_prop/const-prop-ice2.stderr (renamed from tests/ui/consts/const-prop-ice2.stderr)0
-rw-r--r--tests/ui/const_prop/const-prop-ice3.rs (renamed from tests/ui/consts/const-prop-ice3.rs)0
-rw-r--r--tests/ui/const_prop/const-prop-overflowing-casts.rs (renamed from tests/ui/consts/const-prop-overflowing-casts.rs)0
-rw-r--r--tests/ui/const_prop/const-prop-read-static-in-const.rs (renamed from tests/ui/consts/const-prop-read-static-in-const.rs)0
-rw-r--r--tests/ui/const_prop/const-prop-read-static-in-const.stderr (renamed from tests/ui/consts/const-prop-read-static-in-const.stderr)0
-rw-r--r--tests/ui/const_prop/unsized-local-ice.rs9
-rw-r--r--tests/ui/feature-gates/feature-gate-negative_bounds.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-negative_bounds.stderr8
-rw-r--r--tests/ui/issues/issue-58857.stderr4
-rw-r--r--tests/ui/parser/issues/issue-33418.fixed19
-rw-r--r--tests/ui/parser/issues/issue-33418.rs8
-rw-r--r--tests/ui/parser/issues/issue-33418.stderr38
-rw-r--r--tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed9
-rw-r--r--tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs3
-rw-r--r--tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr32
-rw-r--r--tests/ui/repr/invalid_repr_list_help.rs5
-rw-r--r--tests/ui/repr/invalid_repr_list_help.stderr20
-rw-r--r--tests/ui/traits/negative-bounds/associated-constraints.rs20
-rw-r--r--tests/ui/traits/negative-bounds/associated-constraints.stderr34
-rw-r--r--tests/ui/traits/negative-bounds/simple.rs42
-rw-r--r--tests/ui/traits/negative-bounds/simple.stderr70
-rw-r--r--tests/ui/typeck/bad-index-due-to-nested.stderr18
-rw-r--r--triagebot.toml14
91 files changed, 846 insertions, 579 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d7806b5daa6..0b0182472aa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -297,6 +297,7 @@ dependencies = [
  "sha2",
  "tar",
  "toml",
+ "xz2",
 ]
 
 [[package]]
@@ -2060,9 +2061,9 @@ dependencies = [
 
 [[package]]
 name = "lzma-sys"
-version = "0.1.16"
+version = "0.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f24f76ec44a8ac23a31915d6e326bca17ce88da03096f1ff194925dc714dac99"
+checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27"
 dependencies = [
  "cc",
  "libc",
@@ -4059,6 +4060,7 @@ dependencies = [
  "indexmap",
  "rustc_macros",
  "smallvec",
+ "tempfile",
  "thin-vec",
 ]
 
@@ -5658,9 +5660,9 @@ dependencies = [
 
 [[package]]
 name = "xz2"
-version = "0.1.6"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c"
+checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2"
 dependencies = [
  "lzma-sys",
 ]
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index dce7106d128..b5dba0713bf 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -287,12 +287,20 @@ pub enum TraitBoundModifier {
     /// No modifiers
     None,
 
+    /// `!Trait`
+    Negative,
+
     /// `?Trait`
     Maybe,
 
     /// `~const Trait`
     MaybeConst,
 
+    /// `~const !Trait`
+    //
+    // This parses but will be rejected during AST validation.
+    MaybeConstNegative,
+
     /// `~const ?Trait`
     //
     // This parses but will be rejected during AST validation.
@@ -2446,6 +2454,16 @@ impl fmt::Debug for ImplPolarity {
     }
 }
 
+#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
+pub enum BoundPolarity {
+    /// `Type: Trait`
+    Positive,
+    /// `Type: !Trait`
+    Negative(Span),
+    /// `Type: ?Trait`
+    Maybe(Span),
+}
+
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum FnRetTy {
     /// Returns type is not specified.
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index b5b28bf8e31..4100efb6eb3 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1368,13 +1368,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
                             GenericBound::Trait(
                                 ty,
-                                TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
+                                TraitBoundModifier::None
+                                | TraitBoundModifier::MaybeConst
+                                | TraitBoundModifier::Negative,
                             ) => Some(this.lower_poly_trait_ref(ty, itctx)),
                             // `~const ?Bound` will cause an error during AST validation
                             // anyways, so treat it like `?Bound` as compilation proceeds.
                             GenericBound::Trait(
                                 _,
-                                TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
+                                TraitBoundModifier::Maybe
+                                | TraitBoundModifier::MaybeConstMaybe
+                                | TraitBoundModifier::MaybeConstNegative,
                             ) => None,
                             GenericBound::Outlives(lifetime) => {
                                 if lifetime_bound.is_none() {
@@ -2421,11 +2425,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             TraitBoundModifier::None => hir::TraitBoundModifier::None,
             TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
 
+            TraitBoundModifier::Negative => {
+                if self.tcx.features().negative_bounds {
+                    hir::TraitBoundModifier::Negative
+                } else {
+                    hir::TraitBoundModifier::None
+                }
+            }
+
             // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
             // placeholder for compilation to proceed.
             TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
                 hir::TraitBoundModifier::Maybe
             }
+            TraitBoundModifier::MaybeConstNegative => hir::TraitBoundModifier::MaybeConst,
         }
     }
 
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index ffca37ae9d5..2f413789e77 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -206,7 +206,7 @@ ast_passes_tilde_const_disallowed = `~const` is not allowed here
     .closure = closures cannot have `~const` trait bounds
     .function = this function is not `const`, so it cannot have `~const` trait bounds
 
-ast_passes_optional_const_exclusive = `~const` and `?` are mutually exclusive
+ast_passes_optional_const_exclusive = `~const` and `{$modifier}` are mutually exclusive
 
 ast_passes_const_and_async = functions cannot be both `const` and `async`
     .const = `const` because of this
@@ -235,3 +235,9 @@ ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using t
     .help = remove one of these features
 
 ast_passes_show_span = {$msg}
+
+ast_passes_negative_bound_not_supported =
+    negative bounds are not supported
+
+ast_passes_constraint_on_negative_bound =
+    associated type constraints not allowed on negative bounds
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index c79626ccd76..bf43bbdbbee 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1168,12 +1168,27 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     });
                 }
                 (_, TraitBoundModifier::MaybeConstMaybe) => {
-                    self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span()});
+                    self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "?" });
+                }
+                (_, TraitBoundModifier::MaybeConstNegative) => {
+                    self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "!" });
                 }
                 _ => {}
             }
         }
 
+        // Negative trait bounds are not allowed to have associated constraints
+        if let GenericBound::Trait(trait_ref, TraitBoundModifier::Negative) = bound
+            && let Some(segment) = trait_ref.trait_ref.path.segments.last()
+            && let Some(ast::GenericArgs::AngleBracketed(args)) = segment.args.as_deref()
+        {
+            for arg in &args.args {
+                if let ast::AngleBracketedArg::Constraint(constraint) = arg {
+                    self.err_handler().emit_err(errors::ConstraintOnNegativeBound { span: constraint.span });
+                }
+            }
+        }
+
         visit::walk_param_bound(self, bound)
     }
 
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 1732865f0bb..82fe2a21d08 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -567,6 +567,7 @@ pub enum TildeConstReason {
 pub struct OptionalConstExclusive {
     #[primary_span]
     pub span: Span,
+    pub modifier: &'static str,
 }
 
 #[derive(Diagnostic)]
@@ -693,3 +694,17 @@ pub struct ShowSpan {
     pub span: Span,
     pub msg: &'static str,
 }
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_negative_bound_not_supported)]
+pub struct NegativeBoundUnsupported {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_constraint_on_negative_bound)]
+pub struct ConstraintOnNegativeBound {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index ee3ded311c5..a46fe9e898f 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -603,6 +603,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
     gate_all!(dyn_star, "`dyn*` trait objects are experimental");
     gate_all!(const_closures, "const closures are experimental");
 
+    if !visitor.features.negative_bounds {
+        for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {
+            sess.emit_err(errors::NegativeBoundUnsupported { span });
+        }
+    }
+
     // All uses of `gate_all!` below this point were added in #65742,
     // and subsequently disabled (with the non-early gating readded).
     // We emit an early future-incompatible warning for these.
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 849336c8669..ae346510ccc 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1570,12 +1570,19 @@ impl<'a> State<'a> {
                 GenericBound::Trait(tref, modifier) => {
                     match modifier {
                         TraitBoundModifier::None => {}
+                        TraitBoundModifier::Negative => {
+                            self.word("!");
+                        }
                         TraitBoundModifier::Maybe => {
                             self.word("?");
                         }
                         TraitBoundModifier::MaybeConst => {
                             self.word_space("~const");
                         }
+                        TraitBoundModifier::MaybeConstNegative => {
+                            self.word_space("~const");
+                            self.word("!");
+                        }
                         TraitBoundModifier::MaybeConstMaybe => {
                             self.word_space("~const");
                             self.word("?");
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 26d55618b49..c3cc17c255b 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -31,7 +31,7 @@ use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::dependency_format::Dependencies;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
 use rustc_middle::ty::query::{ExternProviders, Providers};
-use rustc_serialize::opaque::{MemDecoder, MemEncoder};
+use rustc_serialize::opaque::{FileEncoder, MemDecoder};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
 use rustc_session::cstore::{self, CrateSource};
@@ -39,6 +39,7 @@ use rustc_session::utils::NativeLibKind;
 use rustc_span::symbol::Symbol;
 use rustc_span::DebuggerVisualizerFile;
 use std::collections::BTreeSet;
+use std::io;
 use std::path::{Path, PathBuf};
 
 pub mod back;
@@ -215,8 +216,11 @@ const RLINK_MAGIC: &[u8] = b"rustlink";
 const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION");
 
 impl CodegenResults {
-    pub fn serialize_rlink(codegen_results: &CodegenResults) -> Vec<u8> {
-        let mut encoder = MemEncoder::new();
+    pub fn serialize_rlink(
+        rlink_file: &Path,
+        codegen_results: &CodegenResults,
+    ) -> Result<usize, io::Error> {
+        let mut encoder = FileEncoder::new(rlink_file)?;
         encoder.emit_raw_bytes(RLINK_MAGIC);
         // `emit_raw_bytes` is used to make sure that the version representation does not depend on
         // Encoder's inner representation of `u32`.
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 4d54c01830b..b10f2e9f862 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -337,7 +337,7 @@ fn valtree_into_mplace<'tcx>(
 
     match ty.kind() {
         ty::FnDef(_, _) => {
-            ecx.write_immediate(Immediate::Uninit, &place.into()).unwrap();
+            // Zero-sized type, nothing to do.
         }
         ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
             let scalar_int = valtree.unwrap_leaf();
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 5310ef0bb3e..a7f66071fe2 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -245,6 +245,12 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
 impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
     pub fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
         if self.layout.is_unsized() {
+            if matches!(self.op, Operand::Immediate(Immediate::Uninit)) {
+                // Uninit unsized places shouldn't occur. In the interpreter we have them
+                // temporarily for unsized arguments before their value is put in; in ConstProp they
+                // remain uninit and this code can actually be reached.
+                throw_inval!(UninitUnsizedLocal);
+            }
             // There are no unsized immediates.
             self.assert_mem_place().len(cx)
         } else {
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 6201e5b619b..294ed18a239 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -164,6 +164,8 @@ declare_features! (
     (active, link_cfg, "1.14.0", None, None),
     /// Allows the `multiple_supertrait_upcastable` lint.
     (active, multiple_supertrait_upcastable, "1.69.0", None, None),
+    /// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
+    (incomplete, negative_bounds, "CURRENT_RUSTC_VERSION", None, None),
     /// Allows using `#[omit_gdb_pretty_printer_section]`.
     (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
     /// Allows using `#[prelude_import]` on glob `use` items.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index e220a029339..38cd5865cc3 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -435,6 +435,7 @@ pub enum GenericArgsParentheses {
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
 pub enum TraitBoundModifier {
     None,
+    Negative,
     Maybe,
     MaybeConst,
 }
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index def192f6e10..a6114e27030 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -665,6 +665,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         span: Span,
         binding_span: Option<Span>,
         constness: ty::BoundConstness,
+        polarity: ty::ImplPolarity,
         bounds: &mut Bounds<'tcx>,
         speculative: bool,
         trait_ref_span: Span,
@@ -696,10 +697,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             ty::Binder::bind_with_vars(tcx.mk_trait_ref(trait_def_id, substs), bound_vars);
 
         debug!(?poly_trait_ref, ?assoc_bindings);
-        bounds.push_trait_bound(tcx, poly_trait_ref, span, constness);
+        bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity);
 
         let mut dup_bindings = FxHashMap::default();
         for binding in &assoc_bindings {
+            // Don't register additional associated type bounds for negative bounds,
+            // since we should have emitten an error for them earlier, and they will
+            // not be well-formed!
+            if polarity == ty::ImplPolarity::Negative {
+                self.tcx()
+                    .sess
+                    .delay_span_bug(binding.span, "negative trait bounds should not have bindings");
+                continue;
+            }
+
             // Specify type to assert that error was already reported in `Err` case.
             let _: Result<_, ErrorGuaranteed> = self.add_predicates_for_ast_type_binding(
                 hir_id,
@@ -711,6 +722,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 binding_span.unwrap_or(binding.span),
                 constness,
                 only_self_bounds,
+                polarity,
             );
             // Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
         }
@@ -743,6 +755,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         trait_ref: &hir::TraitRef<'_>,
         span: Span,
         constness: ty::BoundConstness,
+        polarity: ty::ImplPolarity,
         self_ty: Ty<'tcx>,
         bounds: &mut Bounds<'tcx>,
         speculative: bool,
@@ -764,6 +777,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             span,
             binding_span,
             constness,
+            polarity,
             bounds,
             speculative,
             trait_ref_span,
@@ -799,6 +813,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             span,
             binding_span,
             constness,
+            ty::ImplPolarity::Positive,
             bounds,
             speculative,
             trait_ref_span,
@@ -961,16 +976,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         for ast_bound in ast_bounds {
             match ast_bound {
                 hir::GenericBound::Trait(poly_trait_ref, modifier) => {
-                    let constness = match modifier {
-                        hir::TraitBoundModifier::MaybeConst => ty::BoundConstness::ConstIfConst,
-                        hir::TraitBoundModifier::None => ty::BoundConstness::NotConst,
+                    let (constness, polarity) = match modifier {
+                        hir::TraitBoundModifier::MaybeConst => {
+                            (ty::BoundConstness::ConstIfConst, ty::ImplPolarity::Positive)
+                        }
+                        hir::TraitBoundModifier::None => {
+                            (ty::BoundConstness::NotConst, ty::ImplPolarity::Positive)
+                        }
+                        hir::TraitBoundModifier::Negative => {
+                            (ty::BoundConstness::NotConst, ty::ImplPolarity::Negative)
+                        }
                         hir::TraitBoundModifier::Maybe => continue,
                     };
-
                     let _ = self.instantiate_poly_trait_ref(
                         &poly_trait_ref.trait_ref,
                         poly_trait_ref.span,
                         constness,
+                        polarity,
                         param_ty,
                         bounds,
                         false,
@@ -1088,6 +1110,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         path_span: Span,
         constness: ty::BoundConstness,
         only_self_bounds: OnlySelfBounds,
+        polarity: ty::ImplPolarity,
     ) -> Result<(), ErrorGuaranteed> {
         // Given something like `U: SomeTrait<T = X>`, we want to produce a
         // predicate like `<U as SomeTrait>::T = X`. This is somewhat
@@ -1438,6 +1461,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 &trait_bound.trait_ref,
                 trait_bound.span,
                 ty::BoundConstness::NotConst,
+                ty::ImplPolarity::Positive,
                 dummy_self,
                 &mut bounds,
                 false,
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index 284b099e7bc..7156fea8f89 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -42,8 +42,14 @@ impl<'tcx> Bounds<'tcx> {
         trait_ref: ty::PolyTraitRef<'tcx>,
         span: Span,
         constness: ty::BoundConstness,
+        polarity: ty::ImplPolarity,
     ) {
-        self.predicates.push((trait_ref.with_constness(constness).to_predicate(tcx), span));
+        self.predicates.push((
+            trait_ref
+                .map_bound(|trait_ref| ty::TraitPredicate { trait_ref, constness, polarity })
+                .to_predicate(tcx),
+            span,
+        ));
     }
 
     pub fn push_projection_bound(
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 961457b7579..3fe34f23aef 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -528,6 +528,7 @@ pub fn hir_trait_to_predicates<'tcx>(
         hir_trait,
         DUMMY_SP,
         ty::BoundConstness::NotConst,
+        ty::ImplPolarity::Positive,
         self_ty,
         &mut bounds,
         true,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 778ef06d57e..047d8a82bfc 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -2822,7 +2822,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // but has nested obligations which are unsatisfied.
                     for (base_t, _) in self.autoderef(base.span, base_t).silence_errors() {
                         if let Some((_, index_ty, element_ty)) =
-                            self.find_and_report_unsatisfied_index_impl(expr.hir_id, base, base_t)
+                            self.find_and_report_unsatisfied_index_impl(base, base_t)
                         {
                             self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
                             return element_ty;
@@ -2881,7 +2881,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// predicates cause this to be, so that the user can add them to fix their code.
     fn find_and_report_unsatisfied_index_impl(
         &self,
-        index_expr_hir_id: HirId,
         base_expr: &hir::Expr<'_>,
         base_ty: Ty<'tcx>,
     ) -> Option<(ErrorGuaranteed, Ty<'tcx>, Ty<'tcx>)> {
@@ -2914,13 +2913,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // in the first place.
             ocx.register_obligations(traits::predicates_for_generics(
                 |idx, span| {
-                    traits::ObligationCause::new(
-                        base_expr.span,
-                        self.body_id,
-                        if span.is_dummy() {
-                            traits::ExprItemObligation(impl_def_id, index_expr_hir_id, idx)
-                        } else {
-                            traits::ExprBindingObligation(impl_def_id, span, index_expr_hir_id, idx)
+                    cause.clone().derived_cause(
+                        ty::Binder::dummy(ty::TraitPredicate {
+                            trait_ref: impl_trait_ref,
+                            polarity: ty::ImplPolarity::Positive,
+                            constness: ty::BoundConstness::NotConst,
+                        }),
+                        |derived| {
+                            traits::ImplDerivedObligation(Box::new(
+                                traits::ImplDerivedObligationCause {
+                                    derived,
+                                    impl_or_alias_def_id: impl_def_id,
+                                    impl_def_predicate_index: Some(idx),
+                                    span,
+                                },
+                            ))
                         },
                     )
                 },
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index ef01d5d513b..f54e5e5e56f 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -200,6 +200,10 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
         let bound_predicate = elaboratable.predicate().kind();
         match bound_predicate.skip_binder() {
             ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
+                // Negative trait bounds do not imply any supertrait bounds
+                if data.polarity == ty::ImplPolarity::Negative {
+                    return;
+                }
                 // Get predicates implied by the trait, or only super predicates if we only care about self predicates.
                 let predicates = if self.only_self {
                     tcx.super_predicates_of(data.def_id())
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 77fbbf64a0a..6483d51a0b9 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -368,9 +368,8 @@ impl Linker {
         }
 
         if sess.opts.unstable_opts.no_link {
-            let encoded = CodegenResults::serialize_rlink(&codegen_results);
             let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT);
-            std::fs::write(&rlink_file, encoded)
+            CodegenResults::serialize_rlink(&rlink_file, &codegen_results)
                 .map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
             return Ok(());
         }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index f5ffdd27cae..3253d0a9057 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1364,9 +1364,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         record!(self.tables.params_in_repr[def_id] <- params_in_repr);
 
         if adt_def.is_enum() {
-            let module_children = tcx.module_children_non_reexports(local_def_id);
+            let module_children = tcx.module_children_local(local_def_id);
             record_array!(self.tables.module_children_non_reexports[def_id] <-
-                module_children.iter().map(|def_id| def_id.local_def_index));
+                module_children.iter().map(|child| child.res.def_id().index));
         } else {
             // For non-enum, there is only one variant, and its def_id is the adt's.
             debug_assert_eq!(adt_def.variants().len(), 1);
@@ -1412,12 +1412,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             // Encode this here because we don't do it in encode_def_ids.
             record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
         } else {
-            let non_reexports = tcx.module_children_non_reexports(local_def_id);
+            let module_children = tcx.module_children_local(local_def_id);
+
             record_array!(self.tables.module_children_non_reexports[def_id] <-
-                non_reexports.iter().map(|def_id| def_id.local_def_index));
+                module_children.iter().filter(|child| child.reexport_chain.is_empty())
+                    .map(|child| child.res.def_id().index));
 
             record_defaulted_array!(self.tables.module_children_reexports[def_id] <-
-                tcx.module_children_reexports(local_def_id));
+                module_children.iter().filter(|child| !child.reexport_chain.is_empty()));
         }
     }
 
@@ -1676,9 +1678,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemKind::Trait(..) => {
                 record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
 
-                let module_children = tcx.module_children_non_reexports(item.owner_id.def_id);
+                let module_children = tcx.module_children_local(item.owner_id.def_id);
                 record_array!(self.tables.module_children_non_reexports[def_id] <-
-                    module_children.iter().map(|def_id| def_id.local_def_index));
+                    module_children.iter().map(|child| child.res.def_id().index));
 
                 let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
                 record_associated_item_def_ids(self, associated_item_def_ids);
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index dd02463e16a..84f6b7f934d 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -357,10 +357,16 @@ define_tables! {
     associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
     opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
     unused_generic_params: Table<DefIndex, UnusedGenericParams>,
+    // Reexported names are not associated with individual `DefId`s,
+    // e.g. a glob import can introduce a lot of names, all with the same `DefId`.
+    // That's why the encoded list needs to contain `ModChild` structures describing all the names
+    // individually instead of `DefId`s.
     module_children_reexports: Table<DefIndex, LazyArray<ModChild>>,
 
 - optional:
     attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
+    // For non-reexported names in a module every name is associated with a separate `DefId`,
+    // so we can take their names, visibilities etc from other encoded tables.
     module_children_non_reexports: Table<DefIndex, LazyArray<DefIndex>>,
     associated_item_or_field_def_ids: Table<DefIndex, LazyArray<DefIndex>>,
     opt_def_kind: Table<DefIndex, DefKind>,
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index bd9d89deee1..c6bbf2ef0cd 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -32,6 +32,9 @@ middle_values_too_big =
 middle_cannot_be_normalized =
     unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized
 
+middle_cycle =
+    a cycle occurred during layout computation
+
 middle_strict_coherence_needs_negative_coherence =
     to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
     .label = due to this attribute
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index c5137cf0666..e45284ca506 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -134,6 +134,9 @@ pub enum InvalidProgramInfo<'tcx> {
     FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
     /// SizeOf of unsized type was requested.
     SizeOfUnsizedType(Ty<'tcx>),
+    /// An unsized local was accessed without having been initialized.
+    /// This is not meaningful as we can't even have backing memory for such locals.
+    UninitUnsizedLocal,
 }
 
 impl fmt::Display for InvalidProgramInfo<'_> {
@@ -150,6 +153,7 @@ impl fmt::Display for InvalidProgramInfo<'_> {
             Layout(ref err) => write!(f, "{err}"),
             FnAbiAdjustForForeignAbi(ref err) => write!(f, "{err}"),
             SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{ty}`"),
+            UninitUnsizedLocal => write!(f, "unsized local is used while uninitialized"),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index a309eaf048d..bf78b379986 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2414,26 +2414,17 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    /// Named module children from all items except `use` and `extern crate` imports.
-    ///
-    /// In addition to regular items this list also includes struct or variant constructors, and
+    /// Named module children from all kinds of items, including imports.
+    /// In addition to regular items this list also includes struct and variant constructors, and
     /// items inside `extern {}` blocks because all of them introduce names into parent module.
-    /// For non-reexported children every such name is associated with a separate `DefId`.
     ///
     /// Module here is understood in name resolution sense - it can be a `mod` item,
     /// or a crate root, or an enum, or a trait.
-    pub fn module_children_non_reexports(self, def_id: LocalDefId) -> &'tcx [LocalDefId] {
-        self.resolutions(()).module_children_non_reexports.get(&def_id).map_or(&[], |v| &v[..])
-    }
-
-    /// Named module children from `use` and `extern crate` imports.
     ///
-    /// Reexported names are not associated with individual `DefId`s,
-    /// e.g. a glob import can introduce a lot of names, all with the same `DefId`.
-    /// That's why the list needs to contain `ModChild` structures describing all the names
-    /// individually instead of `DefId`s.
-    pub fn module_children_reexports(self, def_id: LocalDefId) -> &'tcx [ModChild] {
-        self.resolutions(()).module_children_reexports.get(&def_id).map_or(&[], |v| &v[..])
+    /// This is not a query, making it a query causes perf regressions
+    /// (probably due to hashing spans in `ModChild`ren).
+    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
+        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 6e6b7c39ecb..f2a2e67cf82 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -210,6 +210,7 @@ pub enum LayoutError<'tcx> {
     Unknown(Ty<'tcx>),
     SizeOverflow(Ty<'tcx>),
     NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
+    Cycle,
 }
 
 impl IntoDiagnostic<'_, !> for LayoutError<'_> {
@@ -230,6 +231,9 @@ impl IntoDiagnostic<'_, !> for LayoutError<'_> {
                 diag.set_arg("failure_ty", e.get_type_for_failure());
                 diag.set_primary_message(fluent::middle_cannot_be_normalized);
             }
+            LayoutError::Cycle => {
+                diag.set_primary_message(fluent::middle_cycle);
+            }
         }
         diag
     }
@@ -250,6 +254,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
                 t,
                 e.get_type_for_failure()
             ),
+            LayoutError::Cycle => write!(f, "a cycle occurred during layout computation"),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index db6b35026a8..8986defacc7 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -165,8 +165,7 @@ pub struct ResolverGlobalCtxt {
     pub effective_visibilities: EffectiveVisibilities,
     pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
     pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
-    pub module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>,
-    pub module_children_reexports: LocalDefIdMap<Vec<ModChild>>,
+    pub module_children: LocalDefIdMap<Vec<ModChild>>,
     pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
     pub main_def: Option<MainDefinition>,
     pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 2aced27f7bb..6ac9f950450 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2816,6 +2816,9 @@ define_print_and_forward_display! {
         if let ty::BoundConstness::ConstIfConst = self.constness && cx.tcx().features().const_trait_impl {
             p!("~const ");
         }
+        if let ty::ImplPolarity::Negative = self.polarity {
+            p!("!");
+        }
         p!(print(self.trait_ref.print_only_trait_path()))
     }
 
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index 5c38c0acc7f..c62c33d4dfc 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -106,6 +106,12 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<ty::Binder<'_, ty::F
     }
 }
 
+impl<'tcx, T> Value<TyCtxt<'tcx>, DepKind> for Result<T, ty::layout::LayoutError<'_>> {
+    fn from_cycle_error(_tcx: TyCtxt<'tcx>, _cycle: &[QueryInfo<DepKind>]) -> Self {
+        Err(ty::layout::LayoutError::Cycle)
+    }
+}
+
 // item_and_field_ids should form a cycle where each field contains the
 // type in the next element in the list
 pub fn recursive_type_error(
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 9a5232b1bcd..cd296dca133 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -615,13 +615,6 @@ parse_invalid_dyn_keyword = invalid `dyn` keyword
     .help = `dyn` is only needed at the start of a trait `+`-separated list
     .suggestion = remove this keyword
 
-parse_negative_bounds_not_supported = negative bounds are not supported
-    .label = negative bounds are not supported
-    .suggestion = {$num_bounds ->
-            [one] remove the bound
-           *[other] remove the bounds
-        }
-
 parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
 parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
 parse_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
@@ -772,7 +765,8 @@ parse_assoc_lifetime = associated lifetimes are not supported
 
 parse_tilde_const_lifetime = `~const` may only modify trait bounds, not lifetime bounds
 
-parse_maybe_lifetime = `?` may only modify trait bounds, not lifetime bounds
+parse_modifier_lifetime = `{$sigil}` may only modify trait bounds, not lifetime bounds
+    .suggestion = remove the `{$sigil}`
 
 parse_parenthesized_lifetime = parenthesized lifetime bounds are not supported
     .suggestion = remove the parentheses
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index b445ccc7ad0..010a13aefa4 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -2280,31 +2280,6 @@ pub(crate) struct InvalidDynKeyword {
     pub span: Span,
 }
 
-#[derive(Diagnostic)]
-#[diag(parse_negative_bounds_not_supported)]
-pub(crate) struct NegativeBoundsNotSupported {
-    #[primary_span]
-    pub negative_bounds: Vec<Span>,
-    #[label]
-    pub last_span: Span,
-    #[subdiagnostic]
-    pub sub: Option<NegativeBoundsNotSupportedSugg>,
-}
-
-#[derive(Subdiagnostic)]
-#[suggestion(
-    parse_suggestion,
-    style = "tool-only",
-    code = "{fixed}",
-    applicability = "machine-applicable"
-)]
-pub(crate) struct NegativeBoundsNotSupportedSugg {
-    #[primary_span]
-    pub bound_list: Span,
-    pub num_bounds: usize,
-    pub fixed: String,
-}
-
 #[derive(Subdiagnostic)]
 pub enum HelpUseLatestEdition {
     #[help(parse_help_set_edition_cargo)]
@@ -2412,10 +2387,12 @@ pub(crate) struct TildeConstLifetime {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_maybe_lifetime)]
-pub(crate) struct MaybeLifetime {
+#[diag(parse_modifier_lifetime)]
+pub(crate) struct ModifierLifetime {
     #[primary_span]
+    #[suggestion(style = "tool-only", applicability = "maybe-incorrect", code = "")]
     pub span: Span,
+    pub sigil: &'static str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 513f51a3b5c..36883bd2172 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1284,7 +1284,7 @@ impl<'a> Parser<'a> {
         }
 
         self.bump(); // `+`
-        let bounds = self.parse_generic_bounds(None)?;
+        let bounds = self.parse_generic_bounds()?;
         let sum_span = ty.span.to(self.prev_token.span);
 
         let sub = match &ty.kind {
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 61a7ae93bfa..e6d0f9fbc76 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -78,7 +78,7 @@ impl<'a> Parser<'a> {
                 }
                 self.restore_snapshot(snapshot);
             }
-            self.parse_generic_bounds(colon_span)?
+            self.parse_generic_bounds()?
         } else {
             Vec::new()
         };
@@ -419,7 +419,7 @@ impl<'a> Parser<'a> {
         // or with mandatory equality sign and the second type.
         let ty = self.parse_ty_for_where_clause()?;
         if self.eat(&token::Colon) {
-            let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?;
+            let bounds = self.parse_generic_bounds()?;
             Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
                 span: lo.to(self.prev_token.span),
                 bound_generic_params: lifetime_defs,
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index d7bfc432d54..6ca88200dc5 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -788,11 +788,7 @@ impl<'a> Parser<'a> {
         // Parse optional colon and supertrait bounds.
         let had_colon = self.eat(&token::Colon);
         let span_at_colon = self.prev_token.span;
-        let bounds = if had_colon {
-            self.parse_generic_bounds(Some(self.prev_token.span))?
-        } else {
-            Vec::new()
-        };
+        let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() };
 
         let span_before_eq = self.prev_token.span;
         if self.eat(&token::Eq) {
@@ -802,7 +798,7 @@ impl<'a> Parser<'a> {
                 self.sess.emit_err(errors::BoundsNotAllowedOnTraitAliases { span });
             }
 
-            let bounds = self.parse_generic_bounds(None)?;
+            let bounds = self.parse_generic_bounds()?;
             generics.where_clause = self.parse_where_clause()?;
             self.expect_semi()?;
 
@@ -883,7 +879,7 @@ impl<'a> Parser<'a> {
 
         // Parse optional colon and param bounds.
         let bounds =
-            if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
+            if self.eat(&token::Colon) { self.parse_generic_bounds()? } else { Vec::new() };
         let before_where_clause = self.parse_where_clause()?;
 
         let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 47822a9ac78..feb7e829caf 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -606,7 +606,7 @@ impl<'a> Parser<'a> {
                     let kind = if self.eat(&token::Colon) {
                         // Parse associated type constraint bound.
 
-                        let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?;
+                        let bounds = self.parse_generic_bounds()?;
                         AssocConstraintKind::Bound { bounds }
                     } else if self.eat(&token::Eq) {
                         self.parse_assoc_equality_term(ident, self.prev_token.span)?
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index f58f09d06bc..a29b696aea8 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -3,8 +3,7 @@ use super::{Parser, PathStyle, TokenType};
 use crate::errors::{
     self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
     FnPointerCannotBeAsync, FnPointerCannotBeConst, FnPtrWithGenerics, FnPtrWithGenericsSugg,
-    InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime,
-    NegativeBoundsNotSupported, NegativeBoundsNotSupportedSugg, NestedCVariadicType,
+    InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType,
     ReturnTypesUseThinArrow,
 };
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
@@ -14,8 +13,9 @@ use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token, TokenKind};
 use rustc_ast::util::case::Case;
 use rustc_ast::{
-    self as ast, BareFnTy, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime,
-    MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, Ty, TyKind,
+    self as ast, BareFnTy, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam,
+    Generics, Lifetime, MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier,
+    TraitObjectSyntax, Ty, TyKind,
 };
 use rustc_errors::{Applicability, PResult};
 use rustc_span::source_map::Span;
@@ -23,10 +23,10 @@ use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Symbol;
 use thin_vec::{thin_vec, ThinVec};
 
-/// Any `?` or `~const` modifiers that appear at the start of a bound.
+/// Any `?`, `!`, or `~const` modifiers that appear at the start of a bound.
 struct BoundModifiers {
     /// `?Trait`.
-    maybe: Option<Span>,
+    bound_polarity: BoundPolarity,
 
     /// `~const Trait`.
     maybe_const: Option<Span>,
@@ -34,11 +34,13 @@ struct BoundModifiers {
 
 impl BoundModifiers {
     fn to_trait_bound_modifier(&self) -> TraitBoundModifier {
-        match (self.maybe, self.maybe_const) {
-            (None, None) => TraitBoundModifier::None,
-            (Some(_), None) => TraitBoundModifier::Maybe,
-            (None, Some(_)) => TraitBoundModifier::MaybeConst,
-            (Some(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe,
+        match (self.bound_polarity, self.maybe_const) {
+            (BoundPolarity::Positive, None) => TraitBoundModifier::None,
+            (BoundPolarity::Negative(_), None) => TraitBoundModifier::Negative,
+            (BoundPolarity::Maybe(_), None) => TraitBoundModifier::Maybe,
+            (BoundPolarity::Positive, Some(_)) => TraitBoundModifier::MaybeConst,
+            (BoundPolarity::Negative(_), Some(_)) => TraitBoundModifier::MaybeConstNegative,
+            (BoundPolarity::Maybe(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe,
         }
     }
 }
@@ -368,7 +370,7 @@ impl<'a> Parser<'a> {
 
     fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
         let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus());
-        let bounds = self.parse_generic_bounds_common(allow_plus, None)?;
+        let bounds = self.parse_generic_bounds_common(allow_plus)?;
         if lt_no_plus {
             self.sess.emit_err(NeedPlusAfterTraitObjectLifetime { span: lo });
         }
@@ -395,7 +397,7 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, TyKind> {
         if plus {
             self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
-            bounds.append(&mut self.parse_generic_bounds(Some(self.prev_token.span))?);
+            bounds.append(&mut self.parse_generic_bounds()?);
         }
         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
     }
@@ -598,7 +600,7 @@ impl<'a> Parser<'a> {
                 }
             })
         }
-        let bounds = self.parse_generic_bounds(None)?;
+        let bounds = self.parse_generic_bounds()?;
         *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
         Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
     }
@@ -629,7 +631,7 @@ impl<'a> Parser<'a> {
         };
 
         // Always parse bounds greedily for better error recovery.
-        let bounds = self.parse_generic_bounds(None)?;
+        let bounds = self.parse_generic_bounds()?;
         *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
         Ok(TyKind::TraitObject(bounds, syntax))
     }
@@ -660,23 +662,15 @@ impl<'a> Parser<'a> {
         }
     }
 
-    pub(super) fn parse_generic_bounds(
-        &mut self,
-        colon_span: Option<Span>,
-    ) -> PResult<'a, GenericBounds> {
-        self.parse_generic_bounds_common(AllowPlus::Yes, colon_span)
+    pub(super) fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> {
+        self.parse_generic_bounds_common(AllowPlus::Yes)
     }
 
     /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
     ///
     /// See `parse_generic_bound` for the `BOUND` grammar.
-    fn parse_generic_bounds_common(
-        &mut self,
-        allow_plus: AllowPlus,
-        colon_span: Option<Span>,
-    ) -> PResult<'a, GenericBounds> {
+    fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> {
         let mut bounds = Vec::new();
-        let mut negative_bounds = Vec::new();
 
         // In addition to looping while we find generic bounds:
         // We continue even if we find a keyword. This is necessary for error recovery on,
@@ -693,19 +687,12 @@ impl<'a> Parser<'a> {
                 self.sess.emit_err(InvalidDynKeyword { span: self.token.span });
                 self.bump();
             }
-            match self.parse_generic_bound()? {
-                Ok(bound) => bounds.push(bound),
-                Err(neg_sp) => negative_bounds.push(neg_sp),
-            }
+            bounds.push(self.parse_generic_bound()?);
             if allow_plus == AllowPlus::No || !self.eat_plus() {
                 break;
             }
         }
 
-        if !negative_bounds.is_empty() {
-            self.error_negative_bounds(colon_span, &bounds, negative_bounds);
-        }
-
         Ok(bounds)
     }
 
@@ -713,55 +700,22 @@ impl<'a> Parser<'a> {
     fn can_begin_bound(&mut self) -> bool {
         // This needs to be synchronized with `TokenKind::can_begin_bound`.
         self.check_path()
-        || self.check_lifetime()
-        || self.check(&token::Not) // Used for error reporting only.
-        || self.check(&token::Question)
-        || self.check(&token::Tilde)
-        || self.check_keyword(kw::For)
-        || self.check(&token::OpenDelim(Delimiter::Parenthesis))
-    }
-
-    fn error_negative_bounds(
-        &self,
-        colon_span: Option<Span>,
-        bounds: &[GenericBound],
-        negative_bounds: Vec<Span>,
-    ) {
-        let sub = if let Some(bound_list) = colon_span {
-            let bound_list = bound_list.to(self.prev_token.span);
-            let mut new_bound_list = String::new();
-            if !bounds.is_empty() {
-                let mut snippets = bounds.iter().map(|bound| self.span_to_snippet(bound.span()));
-                while let Some(Ok(snippet)) = snippets.next() {
-                    new_bound_list.push_str(" + ");
-                    new_bound_list.push_str(&snippet);
-                }
-                new_bound_list = new_bound_list.replacen(" +", ":", 1);
-            }
-
-            Some(NegativeBoundsNotSupportedSugg {
-                bound_list,
-                num_bounds: negative_bounds.len(),
-                fixed: new_bound_list,
-            })
-        } else {
-            None
-        };
-
-        let last_span = *negative_bounds.last().expect("no negative bounds, but still error?");
-        self.sess.emit_err(NegativeBoundsNotSupported { negative_bounds, last_span, sub });
+            || self.check_lifetime()
+            || self.check(&token::Not)
+            || self.check(&token::Question)
+            || self.check(&token::Tilde)
+            || self.check_keyword(kw::For)
+            || self.check(&token::OpenDelim(Delimiter::Parenthesis))
     }
 
     /// Parses a bound according to the grammar:
     /// ```ebnf
     /// BOUND = TY_BOUND | LT_BOUND
     /// ```
-    fn parse_generic_bound(&mut self) -> PResult<'a, Result<GenericBound, Span>> {
-        let anchor_lo = self.prev_token.span;
+    fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
         let lo = self.token.span;
         let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis));
         let inner_lo = self.token.span;
-        let is_negative = self.eat(&token::Not);
 
         let modifiers = self.parse_ty_bound_modifiers()?;
         let bound = if self.token.is_lifetime() {
@@ -771,7 +725,7 @@ impl<'a> Parser<'a> {
             self.parse_generic_ty_bound(lo, has_parens, modifiers)?
         };
 
-        Ok(if is_negative { Err(anchor_lo.to(self.prev_token.span)) } else { Ok(bound) })
+        Ok(bound)
     }
 
     /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
@@ -799,8 +753,14 @@ impl<'a> Parser<'a> {
             self.sess.emit_err(errors::TildeConstLifetime { span });
         }
 
-        if let Some(span) = modifiers.maybe {
-            self.sess.emit_err(errors::MaybeLifetime { span });
+        match modifiers.bound_polarity {
+            BoundPolarity::Positive => {}
+            BoundPolarity::Negative(span) => {
+                self.sess.emit_err(errors::ModifierLifetime { span, sigil: "!" });
+            }
+            BoundPolarity::Maybe(span) => {
+                self.sess.emit_err(errors::ModifierLifetime { span, sigil: "?" });
+            }
         }
     }
 
@@ -843,9 +803,16 @@ impl<'a> Parser<'a> {
             None
         };
 
-        let maybe = self.eat(&token::Question).then_some(self.prev_token.span);
+        let bound_polarity = if self.eat(&token::Question) {
+            BoundPolarity::Maybe(self.prev_token.span)
+        } else if self.eat(&token::Not) {
+            self.sess.gated_spans.gate(sym::negative_bounds, self.prev_token.span);
+            BoundPolarity::Negative(self.prev_token.span)
+        } else {
+            BoundPolarity::Positive
+        };
 
-        Ok(BoundModifiers { maybe, maybe_const })
+        Ok(BoundModifiers { bound_polarity, maybe_const })
     }
 
     /// Parses a type bound according to:
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 3f28ac26f86..06aa2737915 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -101,12 +101,11 @@ impl CheckAttrVisitor<'_> {
         item: Option<ItemLike<'_>>,
     ) {
         let mut doc_aliases = FxHashMap::default();
-        let mut is_valid = true;
         let mut specified_inline = None;
         let mut seen = FxHashMap::default();
         let attrs = self.tcx.hir().attrs(hir_id);
         for attr in attrs {
-            let attr_is_valid = match attr.name_or_empty() {
+            match attr.name_or_empty() {
                 sym::do_not_recommend => self.check_do_not_recommend(attr.span, target),
                 sym::inline => self.check_inline(hir_id, attr, span, target),
                 sym::no_coverage => self.check_no_coverage(hir_id, attr, span, target),
@@ -188,7 +187,6 @@ impl CheckAttrVisitor<'_> {
                 sym::link_ordinal => self.check_link_ordinal(&attr, span, target),
                 _ => true,
             };
-            is_valid &= attr_is_valid;
 
             // lint-only checks
             match attr.name_or_empty() {
@@ -255,10 +253,6 @@ impl CheckAttrVisitor<'_> {
             self.check_unused_attribute(hir_id, attr)
         }
 
-        if !is_valid {
-            return;
-        }
-
         self.check_repr(attrs, span, target, item, hir_id);
         self.check_used(attrs, target);
     }
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index c607c7fd5f4..7e60870fef0 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -515,9 +515,11 @@ impl<'tcx> EmbargoVisitor<'tcx> {
             let vis = self.tcx.local_visibility(item_id.owner_id.def_id);
             self.update_macro_reachable_def(item_id.owner_id.def_id, def_kind, vis, defining_mod);
         }
-        for export in self.tcx.module_children_reexports(module_def_id) {
-            if export.vis.is_accessible_from(defining_mod, self.tcx)
-                && let Res::Def(def_kind, def_id) = export.res
+        for child in self.tcx.module_children_local(module_def_id) {
+            // FIXME: Use module children for the logic above too.
+            if !child.reexport_chain.is_empty()
+                && child.vis.is_accessible_from(defining_mod, self.tcx)
+                && let Res::Def(def_kind, def_id) = child.res
                 && let Some(def_id) = def_id.as_local() {
                 let vis = self.tcx.local_visibility(def_id);
                 self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod);
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 2044798f4d0..9e4429507b1 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -1261,14 +1261,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         *module.globs.borrow_mut() = Vec::new();
 
         if let Some(def_id) = module.opt_def_id() {
-            let mut non_reexports = Vec::new();
-            let mut reexports = Vec::new();
+            let mut children = Vec::new();
 
             module.for_each_child(self, |this, ident, _, binding| {
                 let res = binding.res().expect_non_local();
-                if !binding.is_import() {
-                    non_reexports.push(res.def_id().expect_local());
-                } else if res != def::Res::Err && !binding.is_ambiguity() {
+                if res != def::Res::Err && !binding.is_ambiguity() {
                     let mut reexport_chain = SmallVec::new();
                     let mut next_binding = binding;
                     while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
@@ -1276,17 +1273,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         next_binding = binding;
                     }
 
-                    reexports.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
+                    children.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
                 }
             });
 
-            // Should be fine because this code is only called for local modules.
-            let def_id = def_id.expect_local();
-            if !non_reexports.is_empty() {
-                self.module_children_non_reexports.insert(def_id, non_reexports);
-            }
-            if !reexports.is_empty() {
-                self.module_children_reexports.insert(def_id, reexports);
+            if !children.is_empty() {
+                // Should be fine because this code is only called for local modules.
+                self.module_children.insert(def_id.expect_local(), children);
             }
         }
     }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 125f5ce7611..e46463579fe 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -909,8 +909,7 @@ pub struct Resolver<'a, 'tcx> {
 
     /// `CrateNum` resolutions of `extern crate` items.
     extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
-    module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>,
-    module_children_reexports: LocalDefIdMap<Vec<ModChild>>,
+    module_children: LocalDefIdMap<Vec<ModChild>>,
     trait_map: NodeMap<Vec<TraitCandidate>>,
 
     /// A map from nodes to anonymous modules.
@@ -1260,8 +1259,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             lifetimes_res_map: Default::default(),
             extra_lifetime_params_map: Default::default(),
             extern_crate_map: Default::default(),
-            module_children_non_reexports: Default::default(),
-            module_children_reexports: Default::default(),
+            module_children: Default::default(),
             trait_map: NodeMap::default(),
             underscore_disambiguator: 0,
             empty_module,
@@ -1399,8 +1397,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             has_pub_restricted,
             effective_visibilities,
             extern_crate_map,
-            module_children_non_reexports: self.module_children_non_reexports,
-            module_children_reexports: self.module_children_reexports,
+            module_children: self.module_children,
             glob_map,
             maybe_unused_trait_imports,
             main_def,
diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml
index e4dbb8a637c..6046780685a 100644
--- a/compiler/rustc_serialize/Cargo.toml
+++ b/compiler/rustc_serialize/Cargo.toml
@@ -10,3 +10,4 @@ thin-vec = "0.2.12"
 
 [dev-dependencies]
 rustc_macros = { path = "../rustc_macros" }
+tempfile = "3.2"
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index 0f6e4b329b8..a2ec318df6d 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -12,118 +12,14 @@ use std::ptr;
 // Encoder
 // -----------------------------------------------------------------------------
 
-pub struct MemEncoder {
-    pub data: Vec<u8>,
-}
-
-impl MemEncoder {
-    pub fn new() -> MemEncoder {
-        MemEncoder { data: vec![] }
-    }
-
-    #[inline]
-    pub fn position(&self) -> usize {
-        self.data.len()
-    }
-
-    pub fn finish(self) -> Vec<u8> {
-        self.data
-    }
-}
-
-macro_rules! write_leb128 {
-    ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{
-        const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>();
-        let old_len = $enc.data.len();
-
-        if MAX_ENCODED_LEN > $enc.data.capacity() - old_len {
-            $enc.data.reserve(MAX_ENCODED_LEN);
-        }
-
-        // SAFETY: The above check and `reserve` ensures that there is enough
-        // room to write the encoded value to the vector's internal buffer.
-        unsafe {
-            let buf = &mut *($enc.data.as_mut_ptr().add(old_len)
-                as *mut [MaybeUninit<u8>; MAX_ENCODED_LEN]);
-            let encoded = leb128::$fun(buf, $value);
-            $enc.data.set_len(old_len + encoded.len());
-        }
-    }};
-}
-
-impl Encoder for MemEncoder {
-    #[inline]
-    fn emit_usize(&mut self, v: usize) {
-        write_leb128!(self, v, usize, write_usize_leb128)
-    }
-
-    #[inline]
-    fn emit_u128(&mut self, v: u128) {
-        write_leb128!(self, v, u128, write_u128_leb128);
-    }
-
-    #[inline]
-    fn emit_u64(&mut self, v: u64) {
-        write_leb128!(self, v, u64, write_u64_leb128);
-    }
-
-    #[inline]
-    fn emit_u32(&mut self, v: u32) {
-        write_leb128!(self, v, u32, write_u32_leb128);
-    }
-
-    #[inline]
-    fn emit_u16(&mut self, v: u16) {
-        self.data.extend_from_slice(&v.to_le_bytes());
-    }
-
-    #[inline]
-    fn emit_u8(&mut self, v: u8) {
-        self.data.push(v);
-    }
-
-    #[inline]
-    fn emit_isize(&mut self, v: isize) {
-        write_leb128!(self, v, isize, write_isize_leb128)
-    }
-
-    #[inline]
-    fn emit_i128(&mut self, v: i128) {
-        write_leb128!(self, v, i128, write_i128_leb128)
-    }
-
-    #[inline]
-    fn emit_i64(&mut self, v: i64) {
-        write_leb128!(self, v, i64, write_i64_leb128)
-    }
-
-    #[inline]
-    fn emit_i32(&mut self, v: i32) {
-        write_leb128!(self, v, i32, write_i32_leb128)
-    }
-
-    #[inline]
-    fn emit_i16(&mut self, v: i16) {
-        self.data.extend_from_slice(&v.to_le_bytes());
-    }
-
-    #[inline]
-    fn emit_raw_bytes(&mut self, s: &[u8]) {
-        self.data.extend_from_slice(s);
-    }
-}
-
 pub type FileEncodeResult = Result<usize, io::Error>;
 
 /// `FileEncoder` encodes data to file via fixed-size buffer.
 ///
-/// When encoding large amounts of data to a file, using `FileEncoder` may be
-/// preferred over using `MemEncoder` to encode to a `Vec`, and then writing the
-/// `Vec` to file, as the latter uses as much memory as there is encoded data,
-/// while the former uses the fixed amount of memory allocated to the buffer.
-/// `FileEncoder` also has the advantage of not needing to reallocate as data
-/// is appended to it, but the disadvantage of requiring more error handling,
-/// which has some runtime overhead.
+/// There used to be a `MemEncoder` type that encoded all the data into a
+/// `Vec`. `FileEncoder` is better because its memory use is determined by the
+/// size of the buffer, rather than the full length of the encoded data, and
+/// because it doesn't need to reallocate memory along the way.
 pub struct FileEncoder {
     /// The input buffer. For adequate performance, we need more control over
     /// buffering than `BufWriter` offers. If `BufWriter` ever offers a raw
@@ -645,13 +541,6 @@ impl<'a> Decoder for MemDecoder<'a> {
 
 // Specialize encoding byte slices. This specialization also applies to encoding `Vec<u8>`s, etc.,
 // since the default implementations call `encode` on their slices internally.
-impl Encodable<MemEncoder> for [u8] {
-    fn encode(&self, e: &mut MemEncoder) {
-        Encoder::emit_usize(e, self.len());
-        e.emit_raw_bytes(self);
-    }
-}
-
 impl Encodable<FileEncoder> for [u8] {
     fn encode(&self, e: &mut FileEncoder) {
         Encoder::emit_usize(e, self.len());
@@ -675,16 +564,6 @@ impl IntEncodedWithFixedSize {
     pub const ENCODED_SIZE: usize = 8;
 }
 
-impl Encodable<MemEncoder> for IntEncodedWithFixedSize {
-    #[inline]
-    fn encode(&self, e: &mut MemEncoder) {
-        let _start_pos = e.position();
-        e.emit_raw_bytes(&self.0.to_le_bytes());
-        let _end_pos = e.position();
-        debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
-    }
-}
-
 impl Encodable<FileEncoder> for IntEncodedWithFixedSize {
     #[inline]
     fn encode(&self, e: &mut FileEncoder) {
diff --git a/compiler/rustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/tests/opaque.rs
index 5e7dd18aa84..861091688bb 100644
--- a/compiler/rustc_serialize/tests/opaque.rs
+++ b/compiler/rustc_serialize/tests/opaque.rs
@@ -1,9 +1,10 @@
 #![allow(rustc::internal)]
 
 use rustc_macros::{Decodable, Encodable};
-use rustc_serialize::opaque::{MemDecoder, MemEncoder};
+use rustc_serialize::opaque::{MemDecoder, FileEncoder};
 use rustc_serialize::{Decodable, Encodable};
 use std::fmt::Debug;
+use std::fs;
 
 #[derive(PartialEq, Clone, Debug, Encodable, Decodable)]
 struct Struct {
@@ -27,18 +28,21 @@ struct Struct {
 }
 
 fn check_round_trip<
-    T: Encodable<MemEncoder> + for<'a> Decodable<MemDecoder<'a>> + PartialEq + Debug,
+    T: Encodable<FileEncoder> + for<'a> Decodable<MemDecoder<'a>> + PartialEq + Debug,
 >(
     values: Vec<T>,
 ) {
-    let mut encoder = MemEncoder::new();
+    let tmpfile = tempfile::NamedTempFile::new().unwrap();
+    let tmpfile = tmpfile.path();
+
+    let mut encoder = FileEncoder::new(&tmpfile).unwrap();
     for value in &values {
         Encodable::encode(value, &mut encoder);
     }
+    encoder.finish().unwrap();
 
-    let data = encoder.finish();
+    let data = fs::read(&tmpfile).unwrap();
     let mut decoder = MemDecoder::new(&data[..], 0);
-
     for value in values {
         let decoded = Decodable::decode(&mut decoder);
         assert_eq!(value, decoded);
@@ -61,7 +65,7 @@ fn test_u8() {
 
 #[test]
 fn test_u16() {
-    for i in u16::MIN..u16::MAX {
+    for i in [u16::MIN, 111, 3333, 55555, u16::MAX] {
         check_round_trip(vec![1, 2, 3, i, i, i]);
     }
 }
@@ -92,7 +96,7 @@ fn test_i8() {
 
 #[test]
 fn test_i16() {
-    for i in i16::MIN..i16::MAX {
+    for i in [i16::MIN, -100, 0, 101, i16::MAX] {
         check_round_trip(vec![-1, 2, -3, i, i, i, 2]);
     }
 }
@@ -251,3 +255,41 @@ fn test_tuples() {
     check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]);
     check_round_trip(vec![(String::new(), "some string".to_string())]);
 }
+
+#[test]
+fn test_unit_like_struct() {
+    #[derive(Encodable, Decodable, PartialEq, Debug)]
+    struct UnitLikeStruct;
+
+    check_round_trip(vec![UnitLikeStruct]);
+}
+
+#[test]
+fn test_box() {
+    #[derive(Encodable, Decodable, PartialEq, Debug)]
+    struct A {
+        foo: Box<[bool]>,
+    }
+
+    let obj = A { foo: Box::new([true, false]) };
+    check_round_trip(vec![obj]);
+}
+
+#[test]
+fn test_cell() {
+    use std::cell::{Cell, RefCell};
+
+    #[derive(Encodable, Decodable, PartialEq, Debug)]
+    struct A {
+        baz: isize,
+    }
+
+    #[derive(Encodable, Decodable, PartialEq, Debug)]
+    struct B {
+        foo: Cell<bool>,
+        bar: RefCell<A>,
+    }
+
+    let obj = B { foo: Cell::new(true), bar: RefCell::new(A { baz: 2 }) };
+    check_round_trip(vec![obj]);
+}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7969b848fd9..714d10f2341 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -984,6 +984,7 @@ symbols! {
         needs_panic_runtime,
         neg,
         negate_unsigned,
+        negative_bounds,
         negative_impls,
         neon,
         never,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 08220c4fe9f..3e9e497672a 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -530,6 +530,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         associated_ty: Option<(&'static str, Ty<'tcx>)>,
         mut body_id: LocalDefId,
     ) {
+        if trait_pred.skip_binder().polarity == ty::ImplPolarity::Negative {
+            return;
+        }
+
         let trait_pred = self.resolve_numeric_literals_with_default(trait_pred);
 
         let self_ty = trait_pred.skip_binder().self_ty();
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 1db9b8ce92e..a8864f47ef0 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -57,6 +57,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         if obligation.polarity() == ty::ImplPolarity::Negative {
             self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
             self.assemble_candidates_from_impls(obligation, &mut candidates);
+            self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
         } else {
             self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
 
@@ -187,6 +188,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         // Keep only those bounds which may apply, and propagate overflow if it occurs.
         for bound in matching_bounds {
+            if bound.skip_binder().polarity != stack.obligation.predicate.skip_binder().polarity {
+                continue;
+            }
+
             // FIXME(oli-obk): it is suspicious that we are dropping the constness and
             // polarity here.
             let wc = self.where_clause_may_apply(stack, bound.map_bound(|t| t.trait_ref))?;
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 40e19abc0d0..0590e02d84a 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -328,6 +328,13 @@ impl<'tcx> WfPredicates<'tcx> {
         let tcx = self.tcx;
         let trait_ref = &trait_pred.trait_ref;
 
+        // Negative trait predicates don't require supertraits to hold, just
+        // that their substs are WF.
+        if trait_pred.polarity == ty::ImplPolarity::Negative {
+            self.compute_negative_trait_pred(trait_ref);
+            return;
+        }
+
         // if the trait predicate is not const, the wf obligations should not be const as well.
         let obligations = if trait_pred.constness == ty::BoundConstness::NotConst {
             self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs)
@@ -393,6 +400,14 @@ impl<'tcx> WfPredicates<'tcx> {
         );
     }
 
+    // Compute the obligations that are required for `trait_ref` to be WF,
+    // given that it is a *negative* trait predicate.
+    fn compute_negative_trait_pred(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
+        for arg in trait_ref.substs {
+            self.compute(arg);
+        }
+    }
+
     /// Pushes the obligations required for `trait_ref::Item` to be WF
     /// into `self.out`.
     fn compute_projection(&mut self, data: ty::AliasTy<'tcx>) {
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 401def18458..a8a0b9f122d 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -919,6 +919,7 @@ fn symlink_noexist() {
 
 #[test]
 fn read_link() {
+    let tmpdir = tmpdir();
     if cfg!(windows) {
         // directory symlink
         assert_eq!(check!(fs::read_link(r"C:\Users\All Users")), Path::new(r"C:\ProgramData"));
@@ -933,8 +934,11 @@ fn read_link() {
                 Path::new(r"C:\Users")
             );
         }
+        // Check that readlink works with non-drive paths on Windows.
+        let link = tmpdir.join("link_unc");
+        check!(symlink_dir(r"\\localhost\c$\", &link));
+        assert_eq!(check!(fs::read_link(&link)), Path::new(r"\\localhost\c$\"));
     }
-    let tmpdir = tmpdir();
     let link = tmpdir.join("link");
     if !got_symlink_permission(&tmpdir) {
         return;
diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs
index 43c0cdb657e..5bfd8b52ed0 100644
--- a/library/std/src/sys/windows/args.rs
+++ b/library/std/src/sys/windows/args.rs
@@ -313,6 +313,9 @@ pub(crate) fn make_bat_command_line(
 ///
 /// This is necessary because cmd.exe does not support verbatim paths.
 pub(crate) fn to_user_path(path: &Path) -> io::Result<Vec<u16>> {
+    from_wide_to_user_path(to_u16s(path)?)
+}
+pub(crate) fn from_wide_to_user_path(mut path: Vec<u16>) -> io::Result<Vec<u16>> {
     use crate::ptr;
     use crate::sys::windows::fill_utf16_buf;
 
@@ -325,8 +328,6 @@ pub(crate) fn to_user_path(path: &Path) -> io::Result<Vec<u16>> {
     const N: u16 = b'N' as _;
     const C: u16 = b'C' as _;
 
-    let mut path = to_u16s(path)?;
-
     // Early return if the path is too long to remove the verbatim prefix.
     const LEGACY_MAX_PATH: usize = 260;
     if path.len() > LEGACY_MAX_PATH {
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index f99cdfbecfb..fe052c8281b 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -477,7 +477,7 @@ impl File {
     fn reparse_point(
         &self,
         space: &mut Align8<[MaybeUninit<u8>]>,
-    ) -> io::Result<(c::DWORD, *const c::REPARSE_DATA_BUFFER)> {
+    ) -> io::Result<(c::DWORD, *mut c::REPARSE_DATA_BUFFER)> {
         unsafe {
             let mut bytes = 0;
             cvt({
@@ -496,7 +496,7 @@ impl File {
                 )
             })?;
             const _: () = assert!(core::mem::align_of::<c::REPARSE_DATA_BUFFER>() <= 8);
-            Ok((bytes, space.0.as_ptr().cast::<c::REPARSE_DATA_BUFFER>()))
+            Ok((bytes, space.0.as_mut_ptr().cast::<c::REPARSE_DATA_BUFFER>()))
         }
     }
 
@@ -506,22 +506,22 @@ impl File {
         unsafe {
             let (path_buffer, subst_off, subst_len, relative) = match (*buf).ReparseTag {
                 c::IO_REPARSE_TAG_SYMLINK => {
-                    let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
-                        ptr::addr_of!((*buf).rest).cast();
+                    let info: *mut c::SYMBOLIC_LINK_REPARSE_BUFFER =
+                        ptr::addr_of_mut!((*buf).rest).cast();
                     assert!(info.is_aligned());
                     (
-                        ptr::addr_of!((*info).PathBuffer).cast::<u16>(),
+                        ptr::addr_of_mut!((*info).PathBuffer).cast::<u16>(),
                         (*info).SubstituteNameOffset / 2,
                         (*info).SubstituteNameLength / 2,
                         (*info).Flags & c::SYMLINK_FLAG_RELATIVE != 0,
                     )
                 }
                 c::IO_REPARSE_TAG_MOUNT_POINT => {
-                    let info: *const c::MOUNT_POINT_REPARSE_BUFFER =
-                        ptr::addr_of!((*buf).rest).cast();
+                    let info: *mut c::MOUNT_POINT_REPARSE_BUFFER =
+                        ptr::addr_of_mut!((*buf).rest).cast();
                     assert!(info.is_aligned());
                     (
-                        ptr::addr_of!((*info).PathBuffer).cast::<u16>(),
+                        ptr::addr_of_mut!((*info).PathBuffer).cast::<u16>(),
                         (*info).SubstituteNameOffset / 2,
                         (*info).SubstituteNameLength / 2,
                         false,
@@ -535,13 +535,20 @@ impl File {
                 }
             };
             let subst_ptr = path_buffer.add(subst_off.into());
-            let mut subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
+            let subst = slice::from_raw_parts_mut(subst_ptr, subst_len as usize);
             // Absolute paths start with an NT internal namespace prefix `\??\`
             // We should not let it leak through.
             if !relative && subst.starts_with(&[92u16, 63u16, 63u16, 92u16]) {
-                subst = &subst[4..];
+                // Turn `\??\` into `\\?\` (a verbatim path).
+                subst[1] = b'\\' as u16;
+                // Attempt to convert to a more user-friendly path.
+                let user = super::args::from_wide_to_user_path(
+                    subst.iter().copied().chain([0]).collect(),
+                )?;
+                Ok(PathBuf::from(OsString::from_wide(&user.strip_suffix(&[0]).unwrap_or(&user))))
+            } else {
+                Ok(PathBuf::from(OsString::from_wide(subst)))
             }
-            Ok(PathBuf::from(OsString::from_wide(subst)))
         }
     }
 
diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs
index c1cf9b93fb3..3e82a381a1b 100644
--- a/src/bootstrap/download.rs
+++ b/src/bootstrap/download.rs
@@ -427,7 +427,6 @@ impl Config {
 
     fn download_toolchain(
         &self,
-        // FIXME(ozkanonur) use CompilerMetadata instead of `version: &str`
         version: &str,
         sysroot: &str,
         stamp_key: &str,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 3f6a5d6d901..951f54e9366 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -152,8 +152,9 @@ pub(crate) fn try_inline_glob(
             // reexported by the glob, e.g. because they are shadowed by something else.
             let reexports = cx
                 .tcx
-                .module_children_reexports(current_mod)
+                .module_children_local(current_mod)
                 .iter()
+                .filter(|child| !child.reexport_chain.is_empty())
                 .filter_map(|child| child.res.opt_def_id())
                 .collect();
             let mut items = build_module_items(cx, did, visited, inlined_names, Some(&reexports));
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 1531e7fc7b9..f9a46e33f9a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2089,9 +2089,9 @@ pub(crate) fn reexport_chain<'tcx>(
     import_def_id: LocalDefId,
     target_def_id: LocalDefId,
 ) -> &'tcx [Reexport] {
-    for child in tcx.module_children_reexports(tcx.local_parent(import_def_id)) {
+    for child in tcx.module_children_local(tcx.local_parent(import_def_id)) {
         if child.res.opt_def_id() == Some(target_def_id.to_def_id())
-            && child.reexport_chain[0].id() == Some(import_def_id.to_def_id())
+            && child.reexport_chain.first().and_then(|r| r.id()) == Some(import_def_id.to_def_id())
         {
             return &child.reexport_chain;
         }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 297120da284..1c6810bdaf9 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -439,6 +439,7 @@ impl clean::GenericBound {
                 let modifier_str = match modifier {
                     hir::TraitBoundModifier::None => "",
                     hir::TraitBoundModifier::Maybe => "?",
+                    hir::TraitBoundModifier::Negative => "!",
                     // ~const is experimental; do not display those bounds in rustdoc
                     hir::TraitBoundModifier::MaybeConst => "",
                 };
diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html
index 58b220c7428..20e09a54805 100644
--- a/src/librustdoc/html/templates/type_layout.html
+++ b/src/librustdoc/html/templates/type_layout.html
@@ -1,53 +1,58 @@
-<h2 id="layout" class="small-section-header">  {# #}
+<h2 id="layout" class="small-section-header"> {# #}
     Layout<a href="#layout" class="anchor">§</a> {# #}
 </h2> {# #}
 <div class="docblock"> {# #}
     {% match type_layout_size %}
-        {% when Ok(type_layout_size) %}
-            <div class="warning"> {# #}
-                <p> {# #}
-                    <strong>Note:</strong> Most layout information is <strong>completely {#+ #}
-                    unstable</strong> and may even differ between compilations. {#+ #}
-                    The only exception is types with certain <code>repr(...)</code> {#+ #}
-                    attributes. Please see the Rust Reference’s {#+ #}
-                    <a href="https://doc.rust-lang.org/reference/type-layout.html">“Type Layout”</a> {#+ #}
-                    chapter for details on type layout guarantees. {# #}
-                </p> {# #}
-            </div> {# #}
-            <p><strong>Size:</strong> {{ type_layout_size|safe }}</p> {# #}
-            {% if !variants.is_empty() %}
-                <p> {# #}
-                    <strong>Size for each variant:</strong> {# #}
-                </p> {# #}
-                <ul> {# #}
-                    {% for (name, layout_size) in variants %}
-                        <li> {# #}
-                            <code>{{ name }}</code>: {#+ #}
-                            {{ layout_size|safe }}
-                        </li> {# #}
-                    {% endfor %}
-                </ul> {# #}
-            {% endif %}
-        {# This kind of layout error can occur with valid code, e.g. if you try to
-           get the layout of a generic type such as `Vec<T>`. #}
+    {% when Ok(type_layout_size) %}
+    <div class="warning"> {# #}
+        <p> {# #}
+            <strong>Note:</strong> Most layout information is <strong>completely {#+ #}
+                unstable</strong> and may even differ between compilations. {#+ #}
+            The only exception is types with certain <code>repr(...)</code> {#+ #}
+            attributes. Please see the Rust Reference’s {#+ #}
+            <a href="https://doc.rust-lang.org/reference/type-layout.html">“Type Layout”</a> {#+ #}
+            chapter for details on type layout guarantees. {# #}
+        </p> {# #}
+    </div> {# #}
+    <p><strong>Size:</strong> {{ type_layout_size|safe }}</p> {# #}
+    {% if !variants.is_empty() %}
+    <p> {# #}
+        <strong>Size for each variant:</strong> {# #}
+    </p> {# #}
+    <ul> {# #}
+        {% for (name, layout_size) in variants %}
+        <li> {# #}
+            <code>{{ name }}</code>: {#+ #}
+            {{ layout_size|safe }}
+        </li> {# #}
+        {% endfor %}
+    </ul> {# #}
+    {% endif %}
+    {# This kind of layout error can occur with valid code, e.g. if you try to
+    get the layout of a generic type such as `Vec<T>`. #}
         {% when Err(LayoutError::Unknown(_)) %}
-            <p> {# #}
-                <strong>Note:</strong> Unable to compute type layout, {#+ #}
-                possibly due to this type having generic parameters. {#+ #}
-                Layout can only be computed for concrete, fully-instantiated types. {# #}
-            </p> {# #}
+        <p> {# #}
+            <strong>Note:</strong> Unable to compute type layout, {#+ #}
+            possibly due to this type having generic parameters. {#+ #}
+            Layout can only be computed for concrete, fully-instantiated types. {# #}
+        </p> {# #}
         {# This kind of error probably can't happen with valid code, but we don't
-           want to panic and prevent the docs from building, so we just let the
-           user know that we couldn't compute the layout. #}
+        want to panic and prevent the docs from building, so we just let the
+        user know that we couldn't compute the layout. #}
         {% when Err(LayoutError::SizeOverflow(_)) %}
-            <p> {# #}
-                <strong>Note:</strong> Encountered an error during type layout; {#+ #}
-                the type was too big. {# #}
-            </p> {# #}
+        <p> {# #}
+            <strong>Note:</strong> Encountered an error during type layout; {#+ #}
+            the type was too big. {# #}
+        </p> {# #}
         {% when Err(LayoutError::NormalizationFailure(_, _)) %}
-            <p> {# #}
-                <strong>Note:</strong> Encountered an error during type layout; {#+ #}
-                the type failed to be normalized. {# #}
-            </p> {# #}
-    {% endmatch %}
+        <p> {# #}
+            <strong>Note:</strong> Encountered an error during type layout; {#+ #}
+            the type failed to be normalized. {# #}
+        </p> {# #}
+        {% when Err(LayoutError::Cycle) %}
+        <p> {# #}
+            <strong>Note:</strong> Encountered an error during type layout; {#+ #}
+            the type's layout depended on the type's layout itself. {# #}
+        </p> {# #}
+        {% endmatch %}
 </div> {# #}
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 62aab46fa7e..b5bebb70593 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -533,6 +533,10 @@ pub(crate) fn from_trait_bound_modifier(
         None => TraitBoundModifier::None,
         Maybe => TraitBoundModifier::Maybe,
         MaybeConst => TraitBoundModifier::MaybeConst,
+        // FIXME(negative-bounds): This bound should be rendered negative, but
+        // since that's experimental, maybe let's not add it to the rustdoc json
+        // API just now...
+        Negative => TraitBoundModifier::None,
     }
 }
 
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index a6089680fae..841c7a78b2d 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -136,14 +136,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         // is declared but also a reexport of itself producing two exports of the same
         // macro in the same module.
         let mut inserted = FxHashSet::default();
-        for export in self.cx.tcx.module_children_reexports(CRATE_DEF_ID) {
-            if let Res::Def(DefKind::Macro(_), def_id) = export.res &&
+        for child in self.cx.tcx.module_children_local(CRATE_DEF_ID) {
+            if !child.reexport_chain.is_empty() &&
+                let Res::Def(DefKind::Macro(_), def_id) = child.res &&
                 let Some(local_def_id) = def_id.as_local() &&
                 self.cx.tcx.has_attr(def_id, sym::macro_export) &&
                 inserted.insert(def_id)
             {
-                    let item = self.cx.tcx.hir().expect_item(local_def_id);
-                    top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None));
+                let item = self.cx.tcx.hir().expect_item(local_def_id);
+                top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None));
             }
         }
 
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index c437bde5ae6..6c3b5bb00a3 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -9,6 +9,7 @@ serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 anyhow = "1.0.32"
 flate2 = "1.0.16"
+xz2 = "0.1.7"
 tar = "0.4.29"
 sha2 = "0.10.1"
 rayon = "1.5.1"
diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs
index dde9745afb7..7a4c15d01ea 100644
--- a/src/tools/build-manifest/src/versions.rs
+++ b/src/tools/build-manifest/src/versions.rs
@@ -5,6 +5,7 @@ use std::fs::File;
 use std::io::Read;
 use std::path::{Path, PathBuf};
 use tar::Archive;
+use xz2::read::XzDecoder;
 
 const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu";
 
@@ -175,9 +176,23 @@ impl Versions {
     }
 
     fn load_version_from_tarball(&mut self, package: &PkgType) -> Result<VersionInfo, Error> {
-        let tarball_name = self.tarball_name(package, DEFAULT_TARGET)?;
-        let tarball = self.dist_path.join(tarball_name);
+        for ext in ["xz", "gz"] {
+            let info =
+                self.load_version_from_tarball_inner(&self.dist_path.join(self.archive_name(
+                    package,
+                    DEFAULT_TARGET,
+                    &format!("tar.{}", ext),
+                )?))?;
+            if info.present {
+                return Ok(info);
+            }
+        }
+
+        // If neither tarball is present, we fallback to returning the non-present info.
+        Ok(VersionInfo::default())
+    }
 
+    fn load_version_from_tarball_inner(&mut self, tarball: &Path) -> Result<VersionInfo, Error> {
         let file = match File::open(&tarball) {
             Ok(file) => file,
             Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
@@ -187,7 +202,14 @@ impl Versions {
             }
             Err(err) => return Err(err.into()),
         };
-        let mut tar = Archive::new(GzDecoder::new(file));
+        let mut tar: Archive<Box<dyn std::io::Read>> =
+            Archive::new(if tarball.extension().map_or(false, |e| e == "gz") {
+                Box::new(GzDecoder::new(file))
+            } else if tarball.extension().map_or(false, |e| e == "xz") {
+                Box::new(XzDecoder::new(file))
+            } else {
+                unimplemented!("tarball extension not recognized: {}", tarball.display())
+            });
 
         let mut version = None;
         let mut git_commit = None;
diff --git a/src/tools/miri/tests/fail/layout_cycle.rs b/src/tools/miri/tests/fail/layout_cycle.rs
new file mode 100644
index 00000000000..d050310bd80
--- /dev/null
+++ b/src/tools/miri/tests/fail/layout_cycle.rs
@@ -0,0 +1,28 @@
+//@error-pattern: a cycle occurred during layout computation
+//~^ ERROR: cycle detected when computing layout of
+
+use std::mem;
+
+pub struct S<T: Tr> {
+    pub f: <T as Tr>::I,
+}
+
+pub trait Tr {
+    type I: Tr;
+}
+
+impl<T: Tr> Tr for S<T> {
+    type I = S<S<T>>;
+}
+
+impl Tr for () {
+    type I = ();
+}
+
+fn foo<T: Tr>() -> usize {
+    mem::size_of::<S<T>>()
+}
+
+fn main() {
+    println!("{}", foo::<S<()>>());
+}
diff --git a/src/tools/miri/tests/fail/layout_cycle.stderr b/src/tools/miri/tests/fail/layout_cycle.stderr
new file mode 100644
index 00000000000..62b7d5fb77d
--- /dev/null
+++ b/src/tools/miri/tests/fail/layout_cycle.stderr
@@ -0,0 +1,28 @@
+error[E0391]: cycle detected when computing layout of `S<S<()>>`
+   |
+   = note: ...which requires computing layout of `<S<()> as Tr>::I`...
+   = note: ...which again requires computing layout of `S<S<()>>`, completing the cycle
+
+error: post-monomorphization error: a cycle occurred during layout computation
+  --> RUSTLIB/core/src/mem/mod.rs:LL:CC
+   |
+LL |     intrinsics::size_of::<T>()
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation
+   |
+   = note: inside `std::mem::size_of::<S<S<()>>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC
+note: inside `foo::<S<()>>`
+  --> $DIR/layout_cycle.rs:LL:CC
+   |
+LL |     mem::size_of::<S<T>>()
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+note: inside `main`
+  --> $DIR/layout_cycle.rs:LL:CC
+   |
+LL |     println!("{}", foo::<S<()>>());
+   |                    ^^^^^^^^^^^^^^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 01e2fb6e61e..f548388ed8b 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -552,6 +552,12 @@ impl Rewrite for ast::GenericBound {
                     ast::TraitBoundModifier::MaybeConstMaybe => poly_trait_ref
                         .rewrite(context, shape.offset_left(8)?)
                         .map(|s| format!("~const ?{}", s)),
+                    ast::TraitBoundModifier::Negative => poly_trait_ref
+                        .rewrite(context, shape.offset_left(1)?)
+                        .map(|s| format!("!{}", s)),
+                    ast::TraitBoundModifier::MaybeConstNegative => poly_trait_ref
+                        .rewrite(context, shape.offset_left(8)?)
+                        .map(|s| format!("~const !{}", s)),
                 };
                 rewrite.map(|s| if has_paren { format!("({})", s) } else { s })
             }
diff --git a/src/tools/rustfmt/tests/target/negative-bounds.rs b/src/tools/rustfmt/tests/target/negative-bounds.rs
new file mode 100644
index 00000000000..4fb35cccf66
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/negative-bounds.rs
@@ -0,0 +1,11 @@
+fn negative()
+where
+    i32: !Copy,
+{
+}
+
+fn maybe_const_negative()
+where
+    i32: ~const !Copy,
+{
+}
diff --git a/tests/ui-fulldeps/deriving-encodable-decodable-box.rs b/tests/ui-fulldeps/deriving-encodable-decodable-box.rs
deleted file mode 100644
index 1c376f59e51..00000000000
--- a/tests/ui-fulldeps/deriving-encodable-decodable-box.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// run-pass
-
-#![allow(unused_imports)]
-#![feature(rustc_private)]
-
-extern crate rustc_macros;
-extern crate rustc_serialize;
-
-// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
-// files.
-#[allow(unused_extern_crates)]
-extern crate rustc_driver;
-
-use rustc_macros::{Decodable, Encodable};
-use rustc_serialize::opaque::{MemDecoder, MemEncoder};
-use rustc_serialize::{Decodable, Encodable, Encoder};
-
-#[derive(Encodable, Decodable)]
-struct A {
-    foo: Box<[bool]>,
-}
-
-fn main() {
-    let obj = A { foo: Box::new([true, false]) };
-
-    let mut encoder = MemEncoder::new();
-    obj.encode(&mut encoder);
-    let data = encoder.finish();
-
-    let mut decoder = MemDecoder::new(&data, 0);
-    let obj2 = A::decode(&mut decoder);
-
-    assert_eq!(obj.foo, obj2.foo);
-}
diff --git a/tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs b/tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs
deleted file mode 100644
index 844d40f2ecd..00000000000
--- a/tests/ui-fulldeps/deriving-encodable-decodable-cell-refcell.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-// run-pass
-
-#![allow(unused_imports)]
-// This briefly tests the capability of `Cell` and `RefCell` to implement the
-// `Encodable` and `Decodable` traits via `#[derive(Encodable, Decodable)]`
-#![feature(rustc_private)]
-
-extern crate rustc_macros;
-extern crate rustc_serialize;
-
-// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
-// files.
-#[allow(unused_extern_crates)]
-extern crate rustc_driver;
-
-use rustc_macros::{Decodable, Encodable};
-use rustc_serialize::opaque::{MemDecoder, MemEncoder};
-use rustc_serialize::{Decodable, Encodable, Encoder};
-use std::cell::{Cell, RefCell};
-
-#[derive(Encodable, Decodable)]
-struct A {
-    baz: isize,
-}
-
-#[derive(Encodable, Decodable)]
-struct B {
-    foo: Cell<bool>,
-    bar: RefCell<A>,
-}
-
-fn main() {
-    let obj = B { foo: Cell::new(true), bar: RefCell::new(A { baz: 2 }) };
-
-    let mut encoder = MemEncoder::new();
-    obj.encode(&mut encoder);
-    let data = encoder.finish();
-
-    let mut decoder = MemDecoder::new(&data, 0);
-    let obj2 = B::decode(&mut decoder);
-
-    assert_eq!(obj.foo.get(), obj2.foo.get());
-    assert_eq!(obj.bar.borrow().baz, obj2.bar.borrow().baz);
-}
diff --git a/tests/ui-fulldeps/issue-14021.rs b/tests/ui-fulldeps/issue-14021.rs
deleted file mode 100644
index 309b5c4a03d..00000000000
--- a/tests/ui-fulldeps/issue-14021.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-// run-pass
-
-#![allow(unused_mut)]
-#![allow(unused_imports)]
-#![feature(rustc_private)]
-
-extern crate rustc_macros;
-extern crate rustc_serialize;
-
-// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
-// files.
-#[allow(unused_extern_crates)]
-extern crate rustc_driver;
-
-use rustc_macros::{Decodable, Encodable};
-use rustc_serialize::opaque::{MemDecoder, MemEncoder};
-use rustc_serialize::{Decodable, Encodable, Encoder};
-
-#[derive(Encodable, Decodable, PartialEq, Debug)]
-struct UnitLikeStruct;
-
-pub fn main() {
-    let obj = UnitLikeStruct;
-
-    let mut encoder = MemEncoder::new();
-    obj.encode(&mut encoder);
-    let data = encoder.finish();
-
-    let mut decoder = MemDecoder::new(&data, 0);
-    let obj2 = UnitLikeStruct::decode(&mut decoder);
-
-    assert_eq!(obj, obj2);
-}
diff --git a/tests/ui/consts/const-prop-ice.rs b/tests/ui/const_prop/const-prop-ice.rs
index 5bffe020629..5bffe020629 100644
--- a/tests/ui/consts/const-prop-ice.rs
+++ b/tests/ui/const_prop/const-prop-ice.rs
diff --git a/tests/ui/consts/const-prop-ice.stderr b/tests/ui/const_prop/const-prop-ice.stderr
index 3bcf2b2de7b..3bcf2b2de7b 100644
--- a/tests/ui/consts/const-prop-ice.stderr
+++ b/tests/ui/const_prop/const-prop-ice.stderr
diff --git a/tests/ui/consts/const-prop-ice2.rs b/tests/ui/const_prop/const-prop-ice2.rs
index d533e394c06..d533e394c06 100644
--- a/tests/ui/consts/const-prop-ice2.rs
+++ b/tests/ui/const_prop/const-prop-ice2.rs
diff --git a/tests/ui/consts/const-prop-ice2.stderr b/tests/ui/const_prop/const-prop-ice2.stderr
index 2b65ffc2db7..2b65ffc2db7 100644
--- a/tests/ui/consts/const-prop-ice2.stderr
+++ b/tests/ui/const_prop/const-prop-ice2.stderr
diff --git a/tests/ui/consts/const-prop-ice3.rs b/tests/ui/const_prop/const-prop-ice3.rs
index 8ab011661e3..8ab011661e3 100644
--- a/tests/ui/consts/const-prop-ice3.rs
+++ b/tests/ui/const_prop/const-prop-ice3.rs
diff --git a/tests/ui/consts/const-prop-overflowing-casts.rs b/tests/ui/const_prop/const-prop-overflowing-casts.rs
index 8cc5b98250b..8cc5b98250b 100644
--- a/tests/ui/consts/const-prop-overflowing-casts.rs
+++ b/tests/ui/const_prop/const-prop-overflowing-casts.rs
diff --git a/tests/ui/consts/const-prop-read-static-in-const.rs b/tests/ui/const_prop/const-prop-read-static-in-const.rs
index 21426205955..21426205955 100644
--- a/tests/ui/consts/const-prop-read-static-in-const.rs
+++ b/tests/ui/const_prop/const-prop-read-static-in-const.rs
diff --git a/tests/ui/consts/const-prop-read-static-in-const.stderr b/tests/ui/const_prop/const-prop-read-static-in-const.stderr
index 793da628587..793da628587 100644
--- a/tests/ui/consts/const-prop-read-static-in-const.stderr
+++ b/tests/ui/const_prop/const-prop-read-static-in-const.stderr
diff --git a/tests/ui/const_prop/unsized-local-ice.rs b/tests/ui/const_prop/unsized-local-ice.rs
new file mode 100644
index 00000000000..c725b3238ea
--- /dev/null
+++ b/tests/ui/const_prop/unsized-local-ice.rs
@@ -0,0 +1,9 @@
+// build-pass
+//! Regression test for <https://github.com/rust-lang/rust/issues/68538>.
+#![feature(unsized_fn_params)]
+
+pub fn take_unsized_slice(s: [u8]) {
+    s[0];
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-negative_bounds.rs b/tests/ui/feature-gates/feature-gate-negative_bounds.rs
new file mode 100644
index 00000000000..533cb0ce5bc
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-negative_bounds.rs
@@ -0,0 +1,4 @@
+fn test<T: !Copy>() {}
+//~^ ERROR negative bounds are not supported
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-negative_bounds.stderr b/tests/ui/feature-gates/feature-gate-negative_bounds.stderr
new file mode 100644
index 00000000000..ae010fdf3f8
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-negative_bounds.stderr
@@ -0,0 +1,8 @@
+error: negative bounds are not supported
+  --> $DIR/feature-gate-negative_bounds.rs:1:12
+   |
+LL | fn test<T: !Copy>() {}
+   |            ^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/issues/issue-58857.stderr b/tests/ui/issues/issue-58857.stderr
index e2acec47e5a..6aef35f0bb9 100644
--- a/tests/ui/issues/issue-58857.stderr
+++ b/tests/ui/issues/issue-58857.stderr
@@ -1,8 +1,8 @@
 error: negative bounds are not supported
-  --> $DIR/issue-58857.rs:4:7
+  --> $DIR/issue-58857.rs:4:9
    |
 LL | impl<A: !Valid> Conj<A>{}
-   |       ^^^^^^^^ negative bounds are not supported
+   |         ^
 
 error: aborting due to previous error
 
diff --git a/tests/ui/parser/issues/issue-33418.fixed b/tests/ui/parser/issues/issue-33418.fixed
deleted file mode 100644
index ed885ae1435..00000000000
--- a/tests/ui/parser/issues/issue-33418.fixed
+++ /dev/null
@@ -1,19 +0,0 @@
-// run-rustfix
-
-trait Tr {}
-//~^ ERROR negative bounds are not supported
-trait Tr2: SuperA {}
-//~^ ERROR negative bounds are not supported
-trait Tr3: SuperB {}
-//~^ ERROR negative bounds are not supported
-trait Tr4: SuperB + SuperD {}
-//~^ ERROR negative bounds are not supported
-trait Tr5 {}
-//~^ ERROR negative bounds are not supported
-
-trait SuperA {}
-trait SuperB {}
-trait SuperC {}
-trait SuperD {}
-
-fn main() {}
diff --git a/tests/ui/parser/issues/issue-33418.rs b/tests/ui/parser/issues/issue-33418.rs
index 9934284abfb..4ebd5871e53 100644
--- a/tests/ui/parser/issues/issue-33418.rs
+++ b/tests/ui/parser/issues/issue-33418.rs
@@ -1,5 +1,3 @@
-// run-rustfix
-
 trait Tr: !SuperA {}
 //~^ ERROR negative bounds are not supported
 trait Tr2: SuperA + !SuperB {}
@@ -7,10 +5,12 @@ trait Tr2: SuperA + !SuperB {}
 trait Tr3: !SuperA + SuperB {}
 //~^ ERROR negative bounds are not supported
 trait Tr4: !SuperA + SuperB
-    + !SuperC + SuperD {}
+//~^ ERROR negative bounds are not supported
++ !SuperC + SuperD {}
 //~^ ERROR negative bounds are not supported
 trait Tr5: !SuperA
-    + !SuperB {}
+//~^ ERROR negative bounds are not supported
++ !SuperB {}
 //~^ ERROR negative bounds are not supported
 
 trait SuperA {}
diff --git a/tests/ui/parser/issues/issue-33418.stderr b/tests/ui/parser/issues/issue-33418.stderr
index 9a8733e8929..b111bcfd240 100644
--- a/tests/ui/parser/issues/issue-33418.stderr
+++ b/tests/ui/parser/issues/issue-33418.stderr
@@ -1,36 +1,44 @@
 error: negative bounds are not supported
-  --> $DIR/issue-33418.rs:3:9
+  --> $DIR/issue-33418.rs:1:11
    |
 LL | trait Tr: !SuperA {}
-   |         ^^^^^^^^^ negative bounds are not supported
+   |           ^
 
 error: negative bounds are not supported
-  --> $DIR/issue-33418.rs:5:19
+  --> $DIR/issue-33418.rs:3:21
    |
 LL | trait Tr2: SuperA + !SuperB {}
-   |                   ^^^^^^^^^ negative bounds are not supported
+   |                     ^
 
 error: negative bounds are not supported
-  --> $DIR/issue-33418.rs:7:10
+  --> $DIR/issue-33418.rs:5:12
    |
 LL | trait Tr3: !SuperA + SuperB {}
-   |          ^^^^^^^^^ negative bounds are not supported
+   |            ^
 
 error: negative bounds are not supported
-  --> $DIR/issue-33418.rs:9:10
+  --> $DIR/issue-33418.rs:7:12
    |
 LL | trait Tr4: !SuperA + SuperB
-   |          ^^^^^^^^^
-LL |     + !SuperC + SuperD {}
-   |     ^^^^^^^^^ negative bounds are not supported
+   |            ^
 
 error: negative bounds are not supported
-  --> $DIR/issue-33418.rs:12:10
+  --> $DIR/issue-33418.rs:9:3
+   |
+LL | + !SuperC + SuperD {}
+   |   ^
+
+error: negative bounds are not supported
+  --> $DIR/issue-33418.rs:11:12
    |
 LL | trait Tr5: !SuperA
-   |          ^^^^^^^^^
-LL |     + !SuperB {}
-   |     ^^^^^^^^^ negative bounds are not supported
+   |            ^
+
+error: negative bounds are not supported
+  --> $DIR/issue-33418.rs:13:3
+   |
+LL | + !SuperB {}
+   |   ^
 
-error: aborting due to 5 previous errors
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed
index 95019b27869..2c42f973174 100644
--- a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed
+++ b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed
@@ -6,9 +6,12 @@
 
 fn main() {}
 
-pub fn f1<T>() {}
+pub fn f1<T: 'static>() {}
 //~^ ERROR negative bounds are not supported
-pub fn f2<'a, T: Ord>() {}
+//~| ERROR `!` may only modify trait bounds, not lifetime bound
+pub fn f2<'a, T: Ord + 'a>() {}
 //~^ ERROR negative bounds are not supported
-pub fn f3<'a, T: Ord>() {}
+//~| ERROR `!` may only modify trait bounds, not lifetime bound
+pub fn f3<'a, T: 'a + Ord>() {}
 //~^ ERROR negative bounds are not supported
+//~| ERROR `!` may only modify trait bounds, not lifetime bound
diff --git a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs
index 82f54f8faa9..e510efaae5b 100644
--- a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs
+++ b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs
@@ -8,7 +8,10 @@ fn main() {}
 
 pub fn f1<T: !'static>() {}
 //~^ ERROR negative bounds are not supported
+//~| ERROR `!` may only modify trait bounds, not lifetime bound
 pub fn f2<'a, T: Ord + !'a>() {}
 //~^ ERROR negative bounds are not supported
+//~| ERROR `!` may only modify trait bounds, not lifetime bound
 pub fn f3<'a, T: !'a + Ord>() {}
 //~^ ERROR negative bounds are not supported
+//~| ERROR `!` may only modify trait bounds, not lifetime bound
diff --git a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr
index a4a422948ac..91fe02db3a6 100644
--- a/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr
+++ b/tests/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr
@@ -1,20 +1,38 @@
+error: `!` may only modify trait bounds, not lifetime bounds
+  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:14
+   |
+LL | pub fn f1<T: !'static>() {}
+   |              ^
+
+error: `!` may only modify trait bounds, not lifetime bounds
+  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:12:24
+   |
+LL | pub fn f2<'a, T: Ord + !'a>() {}
+   |                        ^
+
+error: `!` may only modify trait bounds, not lifetime bounds
+  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:15:18
+   |
+LL | pub fn f3<'a, T: !'a + Ord>() {}
+   |                  ^
+
 error: negative bounds are not supported
-  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:12
+  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:14
    |
 LL | pub fn f1<T: !'static>() {}
-   |            ^^^^^^^^^^ negative bounds are not supported
+   |              ^
 
 error: negative bounds are not supported
-  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:11:22
+  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:12:24
    |
 LL | pub fn f2<'a, T: Ord + !'a>() {}
-   |                      ^^^^^ negative bounds are not supported
+   |                        ^
 
 error: negative bounds are not supported
-  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:13:16
+  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:15:18
    |
 LL | pub fn f3<'a, T: !'a + Ord>() {}
-   |                ^^^^^ negative bounds are not supported
+   |                  ^
 
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/tests/ui/repr/invalid_repr_list_help.rs b/tests/ui/repr/invalid_repr_list_help.rs
index c320984536c..785ffb1e0f4 100644
--- a/tests/ui/repr/invalid_repr_list_help.rs
+++ b/tests/ui/repr/invalid_repr_list_help.rs
@@ -15,3 +15,8 @@ pub struct OwO3 {
 pub enum OwO4 {
     UwU = 1,
 }
+
+#[repr(uwu)] //~ERROR: unrecognized representation hint
+#[doc(owo)]  //~WARN: unknown `doc` attribute
+             //~^ WARN: this was previously
+pub struct Owo5;
diff --git a/tests/ui/repr/invalid_repr_list_help.stderr b/tests/ui/repr/invalid_repr_list_help.stderr
index 2acd56d9a32..48a6af3dd4c 100644
--- a/tests/ui/repr/invalid_repr_list_help.stderr
+++ b/tests/ui/repr/invalid_repr_list_help.stderr
@@ -30,6 +30,24 @@ LL | #[repr(uwu, u8)]
    |
    = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
-error: aborting due to 4 previous errors
+warning: unknown `doc` attribute `owo`
+  --> $DIR/invalid_repr_list_help.rs:20:7
+   |
+LL | #[doc(owo)]
+   |       ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+   = note: `#[warn(invalid_doc_attributes)]` on by default
+
+error[E0552]: unrecognized representation hint
+  --> $DIR/invalid_repr_list_help.rs:19:8
+   |
+LL | #[repr(uwu)]
+   |        ^^^
+   |
+   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+
+error: aborting due to 5 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0552`.
diff --git a/tests/ui/traits/negative-bounds/associated-constraints.rs b/tests/ui/traits/negative-bounds/associated-constraints.rs
new file mode 100644
index 00000000000..bc1a0ef1708
--- /dev/null
+++ b/tests/ui/traits/negative-bounds/associated-constraints.rs
@@ -0,0 +1,20 @@
+#![feature(negative_bounds, associated_type_bounds)]
+//~^ WARN the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait Trait {
+    type Assoc;
+}
+
+fn test<T: !Trait<Assoc = i32>>() {}
+//~^ ERROR associated type constraints not allowed on negative bounds
+
+fn test2<T>() where T: !Trait<Assoc = i32> {}
+//~^ ERROR associated type constraints not allowed on negative bounds
+
+fn test3<T: !Trait<Assoc: Send>>() {}
+//~^ ERROR associated type constraints not allowed on negative bounds
+
+fn test4<T>() where T: !Trait<Assoc: Send> {}
+//~^ ERROR associated type constraints not allowed on negative bounds
+
+fn main() {}
diff --git a/tests/ui/traits/negative-bounds/associated-constraints.stderr b/tests/ui/traits/negative-bounds/associated-constraints.stderr
new file mode 100644
index 00000000000..335ac7e5ad9
--- /dev/null
+++ b/tests/ui/traits/negative-bounds/associated-constraints.stderr
@@ -0,0 +1,34 @@
+error: associated type constraints not allowed on negative bounds
+  --> $DIR/associated-constraints.rs:8:19
+   |
+LL | fn test<T: !Trait<Assoc = i32>>() {}
+   |                   ^^^^^^^^^^^
+
+error: associated type constraints not allowed on negative bounds
+  --> $DIR/associated-constraints.rs:11:31
+   |
+LL | fn test2<T>() where T: !Trait<Assoc = i32> {}
+   |                               ^^^^^^^^^^^
+
+error: associated type constraints not allowed on negative bounds
+  --> $DIR/associated-constraints.rs:14:20
+   |
+LL | fn test3<T: !Trait<Assoc: Send>>() {}
+   |                    ^^^^^^^^^^^
+
+error: associated type constraints not allowed on negative bounds
+  --> $DIR/associated-constraints.rs:17:31
+   |
+LL | fn test4<T>() where T: !Trait<Assoc: Send> {}
+   |                               ^^^^^^^^^^^
+
+warning: the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/associated-constraints.rs:1:12
+   |
+LL | #![feature(negative_bounds, associated_type_bounds)]
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
diff --git a/tests/ui/traits/negative-bounds/simple.rs b/tests/ui/traits/negative-bounds/simple.rs
new file mode 100644
index 00000000000..f6d1d5169c4
--- /dev/null
+++ b/tests/ui/traits/negative-bounds/simple.rs
@@ -0,0 +1,42 @@
+#![feature(negative_bounds, negative_impls)]
+//~^ WARN the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
+
+fn not_copy<T: !Copy>() {}
+
+fn neg_param_env<T: !Copy>() {
+    not_copy::<T>();
+}
+
+fn pos_param_env<T: Copy>() {
+    not_copy::<T>();
+    //~^ ERROR the trait bound `T: !Copy` is not satisfied
+}
+
+fn unknown<T>() {
+    not_copy::<T>();
+    //~^ ERROR the trait bound `T: !Copy` is not satisfied
+}
+
+struct NotCopyable;
+impl !Copy for NotCopyable {}
+
+fn neg_impl() {
+    not_copy::<NotCopyable>();
+}
+
+#[derive(Copy, Clone)]
+struct Copyable;
+
+fn pos_impl() {
+    not_copy::<Copyable>();
+    //~^ ERROR the trait bound `Copyable: !Copy` is not satisfied
+}
+
+struct NotNecessarilyCopyable;
+
+fn unknown_impl() {
+    not_copy::<NotNecessarilyCopyable>();
+    //~^ ERROR the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/traits/negative-bounds/simple.stderr b/tests/ui/traits/negative-bounds/simple.stderr
new file mode 100644
index 00000000000..a3cab41a2ce
--- /dev/null
+++ b/tests/ui/traits/negative-bounds/simple.stderr
@@ -0,0 +1,70 @@
+warning: the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/simple.rs:1:12
+   |
+LL | #![feature(negative_bounds, negative_impls)]
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `T: !Copy` is not satisfied
+  --> $DIR/simple.rs:11:16
+   |
+LL |     not_copy::<T>();
+   |                ^ the trait `!Copy` is not implemented for `T`
+   |
+note: required by a bound in `not_copy`
+  --> $DIR/simple.rs:4:16
+   |
+LL | fn not_copy<T: !Copy>() {}
+   |                ^^^^^ required by this bound in `not_copy`
+
+error[E0277]: the trait bound `T: !Copy` is not satisfied
+  --> $DIR/simple.rs:16:16
+   |
+LL |     not_copy::<T>();
+   |                ^ the trait `!Copy` is not implemented for `T`
+   |
+note: required by a bound in `not_copy`
+  --> $DIR/simple.rs:4:16
+   |
+LL | fn not_copy<T: !Copy>() {}
+   |                ^^^^^ required by this bound in `not_copy`
+
+error[E0277]: the trait bound `Copyable: !Copy` is not satisfied
+  --> $DIR/simple.rs:31:16
+   |
+LL |     not_copy::<Copyable>();
+   |                ^^^^^^^^ the trait `!Copy` is not implemented for `Copyable`
+   |
+   = help: the trait `Copy` is implemented for `Copyable`
+note: required by a bound in `not_copy`
+  --> $DIR/simple.rs:4:16
+   |
+LL | fn not_copy<T: !Copy>() {}
+   |                ^^^^^ required by this bound in `not_copy`
+help: consider annotating `Copyable` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct Copyable;
+   |
+
+error[E0277]: the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied
+  --> $DIR/simple.rs:38:16
+   |
+LL |     not_copy::<NotNecessarilyCopyable>();
+   |                ^^^^^^^^^^^^^^^^^^^^^^ the trait `!Copy` is not implemented for `NotNecessarilyCopyable`
+   |
+note: required by a bound in `not_copy`
+  --> $DIR/simple.rs:4:16
+   |
+LL | fn not_copy<T: !Copy>() {}
+   |                ^^^^^ required by this bound in `not_copy`
+help: consider annotating `NotNecessarilyCopyable` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct NotNecessarilyCopyable;
+   |
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/typeck/bad-index-due-to-nested.stderr b/tests/ui/typeck/bad-index-due-to-nested.stderr
index e03b06b336e..cdb23372c4b 100644
--- a/tests/ui/typeck/bad-index-due-to-nested.stderr
+++ b/tests/ui/typeck/bad-index-due-to-nested.stderr
@@ -4,11 +4,14 @@ error[E0277]: the trait bound `K: Hash` is not satisfied
 LL |     map[k]
    |     ^^^ the trait `Hash` is not implemented for `K`
    |
-note: required by a bound in `<HashMap<K, V> as Index<&K>>`
-  --> $DIR/bad-index-due-to-nested.rs:9:8
+note: required for `HashMap<K, V>` to implement `Index<&K>`
+  --> $DIR/bad-index-due-to-nested.rs:7:12
    |
+LL | impl<K, V> Index<&K> for HashMap<K, V>
+   |            ^^^^^^^^^     ^^^^^^^^^^^^^
+LL | where
 LL |     K: Hash,
-   |        ^^^^ required by this bound in `<HashMap<K, V> as Index<&K>>`
+   |        ---- unsatisfied trait bound introduced here
 help: consider restricting type parameter `K`
    |
 LL | fn index<'a, K: std::hash::Hash, V>(map: &'a HashMap<K, V>, k: K) -> &'a V {
@@ -20,11 +23,14 @@ error[E0277]: the trait bound `V: Copy` is not satisfied
 LL |     map[k]
    |     ^^^ the trait `Copy` is not implemented for `V`
    |
-note: required by a bound in `<HashMap<K, V> as Index<&K>>`
-  --> $DIR/bad-index-due-to-nested.rs:10:8
+note: required for `HashMap<K, V>` to implement `Index<&K>`
+  --> $DIR/bad-index-due-to-nested.rs:7:12
    |
+LL | impl<K, V> Index<&K> for HashMap<K, V>
+   |            ^^^^^^^^^     ^^^^^^^^^^^^^
+...
 LL |     V: Copy,
-   |        ^^^^ required by this bound in `<HashMap<K, V> as Index<&K>>`
+   |        ---- unsatisfied trait bound introduced here
 help: consider restricting type parameter `V`
    |
 LL | fn index<'a, K, V: std::marker::Copy>(map: &'a HashMap<K, V>, k: K) -> &'a V {
diff --git a/triagebot.toml b/triagebot.toml
index 89867b63d64..54c8b2060c5 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -475,10 +475,10 @@ cc = ["@rust-lang/style"]
 
 [mentions."Cargo.lock"]
 message = """
-These commits modify the `Cargo.lock` file. Random changes to `Cargo.lock` can be introduced when switching branches and rebasing PRs.
-This was probably unintentional and should be reverted before this PR is merged.
+These commits modify the `Cargo.lock` file. Unintentional changes to `Cargo.lock` can be introduced when switching branches and rebasing PRs.
 
-If this was intentional then you can ignore this comment.
+If this was unintentional then you should revert the changes before this PR is merged.
+Otherwise, you can ignore this comment.
 """
 
 [mentions."src/tools/x"]
@@ -489,6 +489,14 @@ message = "This PR changes src/bootstrap/defaults/config.compiler.toml. If appro
 [mentions."src/bootstrap/defaults/config.codegen.toml"]
 message = "This PR changes src/bootstrap/defaults/config.codegen.toml. If appropriate, please also update `config.compiler.toml` so the defaults are in sync."
 
+[mentions."tests/ui/deriving/deriving-all-codegen.stdout"]
+message = "Changes to the code generated for builtin derived traits."
+cc = ["@nnethercote"]
+
+[mentions."tests/ui/stats/hir-stats.stderr"]
+message = "Changes to the size of AST and/or HIR nodes."
+cc = ["@nnethercote"]
+
 [assign]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"