diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000000..ec6e107d547f0
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,21 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+
+[*.md]
+# double whitespace at end of line
+# denotes a line break in Markdown
+trim_trailing_whitespace = false
+
+[*.yml]
+indent_size = 2
diff --git a/Cargo.lock b/Cargo.lock
index 8bfdf23a30bf4..fb401ed4cd0bb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -496,9 +496,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chalk-derive"
-version = "0.36.0"
+version = "0.55.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f88ce4deae1dace71e49b7611cfae2d5489de3530d6daba5758043c47ac3a10"
+checksum = "3983193cacd81f0f924acb666b7fe5e1a0d81db9f113fa69203eda7ea8ce8b6c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -508,9 +508,9 @@ dependencies = [
 
 [[package]]
 name = "chalk-engine"
-version = "0.36.0"
+version = "0.55.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e34c9b1b10616782143d7f49490f91ae94afaf2202de3ab0b2835e78b4f0ccc"
+checksum = "05a171ce5abbf0fbd06f221ab80ab182c7ef78603d23b858bc44e7ce8a86a396"
 dependencies = [
  "chalk-derive",
  "chalk-ir",
@@ -521,19 +521,20 @@ dependencies = [
 
 [[package]]
 name = "chalk-ir"
-version = "0.36.0"
+version = "0.55.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63362c629c2014ab639b04029070763fb8224df136d1363d30e9ece4c8877da3"
+checksum = "a522f53af971e7678f472d687e053120157b3ae26e2ebd5ecbc0f5ab124f2cb6"
 dependencies = [
+ "bitflags",
  "chalk-derive",
  "lazy_static",
 ]
 
 [[package]]
 name = "chalk-solve"
-version = "0.36.0"
+version = "0.55.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cac338a67af52a7f50bb2f8232e730a3518ce432dbe303246acfe525ddd838c7"
+checksum = "cdf79fb77a567e456a170f7ec84ea6584163d4ba3f13660cd182013d34ca667c"
 dependencies = [
  "chalk-derive",
  "chalk-ir",
@@ -1783,9 +1784,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.79"
+version = "0.2.85"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743"
+checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -4313,6 +4314,7 @@ dependencies = [
  "chalk-ir",
  "chalk-solve",
  "rustc_ast",
+ "rustc_attr",
  "rustc_data_structures",
  "rustc_hir",
  "rustc_index",
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index f82269c4eee4f..93ba54da3424e 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -29,11 +29,11 @@ pub fn expand_assert<'cx>(
 
     let panic_call = if let Some(tokens) = custom_message {
         let path = if span.rust_2021() {
-            // On edition 2021, we always call `$crate::panic!()`.
+            // On edition 2021, we always call `$crate::panic::panic_2021!()`.
             Path {
                 span: sp,
                 segments: cx
-                    .std_path(&[sym::panic])
+                    .std_path(&[sym::panic, sym::panic_2021])
                     .into_iter()
                     .map(|ident| PathSegment::from_ident(ident))
                     .collect(),
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index 07fde27b5a314..39d08fbee3b7f 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -105,7 +105,6 @@ fn emit_aapcs_va_arg(
     let mut end = bx.build_sibling_block("va_arg.end");
     let zero = bx.const_i32(0);
     let offset_align = Align::from_bytes(4).unwrap();
-    assert_eq!(bx.tcx().sess.target.endian, Endian::Little);
 
     let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
     let (reg_off, reg_top_index, slot_size) = if gr_type {
@@ -144,9 +143,14 @@ fn emit_aapcs_va_arg(
     let top = in_reg.load(top, bx.tcx().data_layout.pointer_align.abi);
 
     // reg_value = *(@top + reg_off_v);
-    let top = in_reg.gep(top, &[reg_off_v]);
-    let top = in_reg.bitcast(top, bx.cx.type_ptr_to(layout.llvm_type(bx)));
-    let reg_value = in_reg.load(top, layout.align.abi);
+    let mut reg_addr = in_reg.gep(top, &[reg_off_v]);
+    if bx.tcx().sess.target.endian == Endian::Big && layout.size.bytes() != slot_size {
+        // On big-endian systems the value is right-aligned in its slot.
+        let offset = bx.const_i32((slot_size - layout.size.bytes()) as i32);
+        reg_addr = in_reg.gep(reg_addr, &[offset]);
+    }
+    let reg_addr = in_reg.bitcast(reg_addr, bx.cx.type_ptr_to(layout.llvm_type(bx)));
+    let reg_value = in_reg.load(reg_addr, layout.align.abi);
     in_reg.br(&end.llbb());
 
     // On Stack block
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index c669f7fed272a..9ce74dd9b5a79 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -267,6 +267,7 @@ E0516: include_str!("./error_codes/E0516.md"),
 E0517: include_str!("./error_codes/E0517.md"),
 E0518: include_str!("./error_codes/E0518.md"),
 E0520: include_str!("./error_codes/E0520.md"),
+E0521: include_str!("./error_codes/E0521.md"),
 E0522: include_str!("./error_codes/E0522.md"),
 E0524: include_str!("./error_codes/E0524.md"),
 E0525: include_str!("./error_codes/E0525.md"),
@@ -597,7 +598,6 @@ E0780: include_str!("./error_codes/E0780.md"),
     E0514, // metadata version mismatch
     E0519, // local crate and dependency have same (crate-name, disambiguator)
     // two dependencies have same (crate-name, disambiguator) but different SVH
-    E0521, // borrowed data escapes outside of closure
     E0523,
 //  E0526, // shuffle indices are not constant
 //  E0540, // multiple rustc_deprecated attributes
diff --git a/compiler/rustc_error_codes/src/error_codes/E0521.md b/compiler/rustc_error_codes/src/error_codes/E0521.md
new file mode 100644
index 0000000000000..65dcac983acd5
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0521.md
@@ -0,0 +1,28 @@
+Borrowed data escapes outside of closure.
+
+Erroneous code example:
+
+```compile_fail,E0521
+let mut list: Vec<&str> = Vec::new();
+
+let _add = |el: &str| {
+    list.push(el); // error: `el` escapes the closure body here
+};
+```
+
+A type anotation of a closure parameter implies a new lifetime declaration.
+Consider to drop it, the compiler is reliably able to infer them.
+
+```
+let mut list: Vec<&str> = Vec::new();
+
+let _add = |el| {
+    list.push(el);
+};
+```
+
+See the [Closure type inference and annotation][closure-infere-annotation] and
+[Lifetime elision][lifetime-elision] sections of the Book for more details.
+
+[closure-infere-annotation]: https://doc.rust-lang.org/book/ch13-01-closures.html#closure-type-inference-and-annotation
+[lifetime-elision]: https://doc.rust-lang.org/reference/lifetime-elision.html
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 9002d251f1237..aa4fd055d5ee0 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -353,10 +353,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
                     // `TyVar(vid)` is unresolved, track its universe index in the canonicalized
                     // result.
                     Err(mut ui) => {
-                        if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
-                            // FIXME: perf problem described in #55921.
-                            ui = ty::UniverseIndex::ROOT;
-                        }
+                        // FIXME: perf problem described in #55921.
+                        ui = ty::UniverseIndex::ROOT;
                         self.canonicalize_ty_var(
                             CanonicalVarInfo {
                                 kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
@@ -440,10 +438,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
                     // `ConstVar(vid)` is unresolved, track its universe index in the
                     // canonicalized result
                     Err(mut ui) => {
-                        if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
-                            // FIXME: perf problem described in #55921.
-                            ui = ty::UniverseIndex::ROOT;
-                        }
+                        // FIXME: perf problem described in #55921.
+                        ui = ty::UniverseIndex::ROOT;
                         return self.canonicalize_const_var(
                             CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
                             ct,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 2abb1c725b914..84aa19aedebf8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1855,7 +1855,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         diag.span_suggestion(
                             span,
                             &format!(
-                                "you might have meant to use field `{}` of type `{}`",
+                                "you might have meant to use field `{}` whose type is `{}`",
                                 name, ty
                             ),
                             suggestion,
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index 47b7768b410a1..d33aad3b71040 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -26,7 +26,7 @@ rustc_index = { path = "../rustc_index" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
-chalk-ir = "0.36.0"
+chalk-ir = "0.55.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 measureme = "9.0.0"
 rustc_session = { path = "../rustc_session" }
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index f288ad8d1d4a3..4bb39fe4a527e 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -96,7 +96,7 @@ impl<'tcx> ConstValue<'tcx> {
 }
 
 /// A `Scalar` represents an immediate, primitive value existing outside of a
-/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
+/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 16 bytes in
 /// size. Like a range of bytes in an `Allocation`, a `Scalar` can either represent the raw bytes
 /// of a simple value or a pointer into another `Allocation`
 #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, TyEncodable, TyDecodable, Hash)]
diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs
index f864ad8ebcd8a..74873778f74ba 100644
--- a/compiler/rustc_middle/src/traits/chalk.rs
+++ b/compiler/rustc_middle/src/traits/chalk.rs
@@ -72,6 +72,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
     type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
     type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
     type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>;
+    type InternedVariances = Vec<chalk_ir::Variance>;
     type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
     type DefId = DefId;
     type InternedAdtId = &'tcx AdtDef;
@@ -86,17 +87,34 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
             write!(fmt, "{:?}", pci.consequence)?;
 
             let conditions = pci.conditions.interned();
+            let constraints = pci.constraints.interned();
 
             let conds = conditions.len();
-            if conds == 0 {
+            let consts = constraints.len();
+            if conds == 0 && consts == 0 {
                 return Ok(());
             }
 
             write!(fmt, " :- ")?;
-            for cond in &conditions[..conds - 1] {
-                write!(fmt, "{:?}, ", cond)?;
+
+            if conds != 0 {
+                for cond in &conditions[..conds - 1] {
+                    write!(fmt, "{:?}, ", cond)?;
+                }
+                write!(fmt, "{:?}", conditions[conds - 1])?;
+            }
+
+            if conds != 0 && consts != 0 {
+                write!(fmt, " ; ")?;
             }
-            write!(fmt, "{:?}", conditions[conds - 1])?;
+
+            if consts != 0 {
+                for constraint in &constraints[..consts - 1] {
+                    write!(fmt, "{:?}, ", constraint)?;
+                }
+                write!(fmt, "{:?}", constraints[consts - 1])?;
+            }
+
             Ok(())
         };
         Some(write())
@@ -351,6 +369,20 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
     ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
         constraints
     }
+
+    fn intern_variances<E>(
+        &self,
+        data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>,
+    ) -> Result<Self::InternedVariances, E> {
+        data.into_iter().collect::<Result<Vec<_>, _>>()
+    }
+
+    fn variances_data<'a>(
+        &self,
+        variances: &'a Self::InternedVariances,
+    ) -> &'a [chalk_ir::Variance] {
+        variances
+    }
 }
 
 impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> {
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 004c06029ffba..0bab33976b29d 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -2415,7 +2415,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                                     _ => break,
                                 }
                             }
-                            break Some(e);
+                            break Some(&e[..]);
                         }
                         Elide::Forbid => break None,
                     };
@@ -2445,7 +2445,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             lifetime_refs.len(),
             &lifetime_names,
             lifetime_spans,
-            error.map(|p| &p[..]).unwrap_or(&[]),
+            error.unwrap_or(&[]),
         );
         err.emit();
     }
diff --git a/compiler/rustc_target/src/abi/call/aarch64.rs b/compiler/rustc_target/src/abi/call/aarch64.rs
index 1ab7722edab98..a5e985d471271 100644
--- a/compiler/rustc_target/src/abi/call/aarch64.rs
+++ b/compiler/rustc_target/src/abi/call/aarch64.rs
@@ -40,17 +40,7 @@ where
     let size = ret.layout.size;
     let bits = size.bits();
     if bits <= 128 {
-        let unit = if bits <= 8 {
-            Reg::i8()
-        } else if bits <= 16 {
-            Reg::i16()
-        } else if bits <= 32 {
-            Reg::i32()
-        } else {
-            Reg::i64()
-        };
-
-        ret.cast_to(Uniform { unit, total: size });
+        ret.cast_to(Uniform { unit: Reg::i64(), total: size });
         return;
     }
     ret.make_indirect();
@@ -72,17 +62,7 @@ where
     let size = arg.layout.size;
     let bits = size.bits();
     if bits <= 128 {
-        let unit = if bits <= 8 {
-            Reg::i8()
-        } else if bits <= 16 {
-            Reg::i16()
-        } else if bits <= 32 {
-            Reg::i32()
-        } else {
-            Reg::i64()
-        };
-
-        arg.cast_to(Uniform { unit, total: size });
+        arg.cast_to(Uniform { unit: Reg::i64(), total: size });
         return;
     }
     arg.make_indirect();
diff --git a/compiler/rustc_target/src/abi/call/arm.rs b/compiler/rustc_target/src/abi/call/arm.rs
index 26fed3bae4e48..b560e11fe1c5e 100644
--- a/compiler/rustc_target/src/abi/call/arm.rs
+++ b/compiler/rustc_target/src/abi/call/arm.rs
@@ -45,14 +45,7 @@ where
     let size = ret.layout.size;
     let bits = size.bits();
     if bits <= 32 {
-        let unit = if bits <= 8 {
-            Reg::i8()
-        } else if bits <= 16 {
-            Reg::i16()
-        } else {
-            Reg::i32()
-        };
-        ret.cast_to(Uniform { unit, total: size });
+        ret.cast_to(Uniform { unit: Reg::i32(), total: size });
         return;
     }
     ret.make_indirect();
diff --git a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs
new file mode 100644
index 0000000000000..192c4661c7ce6
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs
@@ -0,0 +1,20 @@
+use crate::abi::Endian;
+use crate::spec::{Target, TargetOptions};
+
+pub fn target() -> Target {
+    let mut base = super::linux_gnu_base::opts();
+    base.max_atomic_width = Some(128);
+
+    Target {
+        llvm_target: "aarch64_be-unknown-linux-gnu".to_string(),
+        pointer_width: 64,
+        data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
+        arch: "aarch64".to_string(),
+        options: TargetOptions {
+            unsupported_abis: super::arm_base::unsupported_abis(),
+            mcount: "\u{1}_mcount".to_string(),
+            endian: Endian::Big,
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
new file mode 100644
index 0000000000000..5b9e9c9519c54
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
@@ -0,0 +1,20 @@
+use crate::abi::Endian;
+use crate::spec::{Target, TargetOptions};
+
+pub fn target() -> Target {
+    let mut base = super::linux_gnu_base::opts();
+    base.max_atomic_width = Some(128);
+
+    Target {
+        llvm_target: "aarch64_be-unknown-linux-gnu_ilp32".to_string(),
+        pointer_width: 32,
+        data_layout: "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
+        arch: "aarch64".to_string(),
+        options: TargetOptions {
+            unsupported_abis: super::arm_base::unsupported_abis(),
+            mcount: "\u{1}_mcount".to_string(),
+            endian: Endian::Big,
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
new file mode 100644
index 0000000000000..f2d7576280fd9
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
@@ -0,0 +1,18 @@
+use crate::spec::{Target, TargetOptions};
+
+pub fn target() -> Target {
+    let mut base = super::linux_gnu_base::opts();
+    base.max_atomic_width = Some(128);
+
+    Target {
+        llvm_target: "aarch64-unknown-linux-gnu_ilp32".to_string(),
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
+        arch: "aarch64".to_string(),
+        options: TargetOptions {
+            unsupported_abis: super::arm_base::unsupported_abis(),
+            mcount: "\u{1}_mcount".to_string(),
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 0227febd294a0..7a93bac72ca07 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -808,6 +808,10 @@ supported_targets! {
     ("mipsel-sony-psp", mipsel_sony_psp),
     ("mipsel-unknown-none", mipsel_unknown_none),
     ("thumbv4t-none-eabi", thumbv4t_none_eabi),
+
+    ("aarch64_be-unknown-linux-gnu", aarch64_be_unknown_linux_gnu),
+    ("aarch64-unknown-linux-gnu_ilp32", aarch64_unknown_linux_gnu_ilp32),
+    ("aarch64_be-unknown-linux-gnu_ilp32", aarch64_be_unknown_linux_gnu_ilp32),
 }
 
 /// Everything `rustc` knows about how to compile for a specific target.
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 3facdd5f84c29..89820bb1417eb 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -16,8 +16,7 @@ use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::abstract_const::{Node, NodeId};
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind};
-use rustc_middle::ty::subst::Subst;
-use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::subst::{Subst, SubstsRef};
 use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
 use rustc_session::lint;
 use rustc_span::def_id::{DefId, LocalDefId};
@@ -43,10 +42,6 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
                 for pred in param_env.caller_bounds() {
                     match pred.kind().skip_binder() {
                         ty::PredicateKind::ConstEvaluatable(b_def, b_substs) => {
-                            debug!(
-                                "is_const_evaluatable: caller_bound={:?}, {:?}",
-                                b_def, b_substs
-                            );
                             if b_def == def && b_substs == substs {
                                 debug!("is_const_evaluatable: caller_bound ~~> ok");
                                 return Ok(());
@@ -113,15 +108,24 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
                     }
                     FailureKind::MentionsParam => {
                         // FIXME(const_evaluatable_checked): Better error message.
-                        infcx
-                            .tcx
-                            .sess
-                            .struct_span_err(span, "unconstrained generic constant")
-                            .span_help(
+                        let mut err =
+                            infcx.tcx.sess.struct_span_err(span, "unconstrained generic constant");
+                        let const_span = tcx.def_span(def.did);
+                        // FIXME(const_evaluatable_checked): Update this suggestion once
+                        // explicit const evaluatable bounds are implemented.
+                        if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(const_span)
+                        {
+                            err.span_help(
                                 tcx.def_span(def.did),
+                                &format!("try adding a `where` bound using this expression: where [u8; {}]: Sized", snippet),
+                            );
+                        } else {
+                            err.span_help(
+                                const_span,
                                 "consider adding a `where` bound for this expression",
-                            )
-                            .emit();
+                            );
+                        }
+                        err.emit();
                         return Err(ErrorHandled::Reported(ErrorReported));
                     }
                     FailureKind::Concrete => {
diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml
index 8bd9e29629dce..8fdbc3b76b459 100644
--- a/compiler/rustc_traits/Cargo.toml
+++ b/compiler/rustc_traits/Cargo.toml
@@ -6,15 +6,16 @@ edition = "2018"
 
 [dependencies]
 tracing = "0.1"
+rustc_attr = { path = "../rustc_attr" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
-chalk-ir = "0.36.0"
-chalk-solve = "0.36.0"
-chalk-engine = "0.36.0"
+chalk-ir = "0.55.0"
+chalk-solve = "0.55.0"
+chalk-engine = "0.55.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc_infer = { path = "../rustc_infer" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs
index bb48ed936188b..916186f4204e2 100644
--- a/compiler/rustc_traits/src/chalk/db.rs
+++ b/compiler/rustc_traits/src/chalk/db.rs
@@ -10,6 +10,9 @@ use rustc_middle::traits::ChalkRustInterner as RustInterner;
 use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
 use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt, TypeFoldable};
 
+use rustc_ast::ast;
+use rustc_attr as attr;
+
 use rustc_hir::def_id::DefId;
 
 use rustc_span::symbol::sym;
@@ -18,7 +21,6 @@ use std::fmt;
 use std::sync::Arc;
 
 use crate::chalk::lowering::{self, LowerInto};
-use rustc_ast::ast;
 
 pub struct RustIrDatabase<'tcx> {
     pub(crate) interner: RustInterner<'tcx>,
@@ -205,12 +207,32 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
     fn adt_repr(
         &self,
         adt_id: chalk_ir::AdtId<RustInterner<'tcx>>,
-    ) -> chalk_solve::rust_ir::AdtRepr {
+    ) -> Arc<chalk_solve::rust_ir::AdtRepr<RustInterner<'tcx>>> {
         let adt_def = adt_id.0;
-        chalk_solve::rust_ir::AdtRepr {
-            repr_c: adt_def.repr.c(),
-            repr_packed: adt_def.repr.packed(),
-        }
+        let int = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(i)).intern(&self.interner);
+        let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i)).intern(&self.interner);
+        Arc::new(chalk_solve::rust_ir::AdtRepr {
+            c: adt_def.repr.c(),
+            packed: adt_def.repr.packed(),
+            int: adt_def.repr.int.map(|i| match i {
+                attr::IntType::SignedInt(ty) => match ty {
+                    ast::IntTy::Isize => int(chalk_ir::IntTy::Isize),
+                    ast::IntTy::I8 => int(chalk_ir::IntTy::I8),
+                    ast::IntTy::I16 => int(chalk_ir::IntTy::I16),
+                    ast::IntTy::I32 => int(chalk_ir::IntTy::I32),
+                    ast::IntTy::I64 => int(chalk_ir::IntTy::I64),
+                    ast::IntTy::I128 => int(chalk_ir::IntTy::I128),
+                },
+                attr::IntType::UnsignedInt(ty) => match ty {
+                    ast::UintTy::Usize => uint(chalk_ir::UintTy::Usize),
+                    ast::UintTy::U8 => uint(chalk_ir::UintTy::U8),
+                    ast::UintTy::U16 => uint(chalk_ir::UintTy::U16),
+                    ast::UintTy::U32 => uint(chalk_ir::UintTy::U32),
+                    ast::UintTy::U64 => uint(chalk_ir::UintTy::U64),
+                    ast::UintTy::U128 => uint(chalk_ir::UintTy::U128),
+                },
+            }),
+        })
     }
 
     fn fn_def_datum(
@@ -316,7 +338,11 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             let self_ty = self_ty.fold_with(&mut regions_substitutor);
             let lowered_ty = self_ty.lower_into(&self.interner);
 
-            parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty)
+            parameters[0].assert_ty_ref(&self.interner).could_match(
+                &self.interner,
+                self.unification_database(),
+                &lowered_ty,
+            )
         });
 
         let impls = matched_impls.map(chalk_ir::ImplId).collect();
@@ -541,6 +567,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             Unsize => lang_items.unsize_trait(),
             Unpin => lang_items.unpin_trait(),
             CoerceUnsized => lang_items.coerce_unsized_trait(),
+            DiscriminantKind => lang_items.discriminant_kind_trait(),
         };
         def_id.map(chalk_ir::TraitId)
     }
@@ -586,7 +613,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
         let sig = &substs.as_slice(&self.interner)[substs.len(&self.interner) - 2];
         match sig.assert_ty_ref(&self.interner).kind(&self.interner) {
             chalk_ir::TyKind::Function(f) => {
-                let substitution = f.substitution.as_slice(&self.interner);
+                let substitution = f.substitution.0.as_slice(&self.interner);
                 let return_type =
                     substitution.last().unwrap().assert_ty_ref(&self.interner).clone();
                 // Closure arguments are tupled
@@ -644,6 +671,51 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
     ) -> Arc<chalk_solve::rust_ir::GeneratorWitnessDatum<RustInterner<'tcx>>> {
         unimplemented!()
     }
+
+    fn unification_database(&self) -> &dyn chalk_ir::UnificationDatabase<RustInterner<'tcx>> {
+        self
+    }
+
+    fn discriminant_type(
+        &self,
+        _: chalk_ir::Ty<RustInterner<'tcx>>,
+    ) -> chalk_ir::Ty<RustInterner<'tcx>> {
+        unimplemented!()
+    }
+}
+
+impl<'tcx> chalk_ir::UnificationDatabase<RustInterner<'tcx>> for RustIrDatabase<'tcx> {
+    fn fn_def_variance(
+        &self,
+        def_id: chalk_ir::FnDefId<RustInterner<'tcx>>,
+    ) -> chalk_ir::Variances<RustInterner<'tcx>> {
+        let variances = self.interner.tcx.variances_of(def_id.0);
+        chalk_ir::Variances::from_iter(
+            &self.interner,
+            variances.iter().map(|v| match v {
+                ty::Variance::Invariant => chalk_ir::Variance::Invariant,
+                ty::Variance::Covariant => chalk_ir::Variance::Covariant,
+                ty::Variance::Contravariant => chalk_ir::Variance::Contravariant,
+                ty::Variance::Bivariant => unimplemented!(),
+            }),
+        )
+    }
+
+    fn adt_variance(
+        &self,
+        def_id: chalk_ir::AdtId<RustInterner<'tcx>>,
+    ) -> chalk_ir::Variances<RustInterner<'tcx>> {
+        let variances = self.interner.tcx.variances_of(def_id.0.did);
+        chalk_ir::Variances::from_iter(
+            &self.interner,
+            variances.iter().map(|v| match v {
+                ty::Variance::Invariant => chalk_ir::Variance::Invariant,
+                ty::Variance::Covariant => chalk_ir::Variance::Covariant,
+                ty::Variance::Contravariant => chalk_ir::Variance::Contravariant,
+                ty::Variance::Bivariant => unimplemented!(),
+            }),
+        )
+    }
 }
 
 /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 2a1a3f57e2313..7d3589c4b6bd8 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -287,12 +287,12 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
                 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
                     num_binders: binders.len(interner),
                     sig: sig.lower_into(interner),
-                    substitution: chalk_ir::Substitution::from_iter(
+                    substitution: chalk_ir::FnSubst(chalk_ir::Substitution::from_iter(
                         interner,
                         inputs_and_outputs.iter().map(|ty| {
                             chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner)
                         }),
-                    ),
+                    )),
                 })
             }
             ty::Dynamic(predicates, region) => chalk_ir::TyKind::Dyn(chalk_ir::DynTy {
@@ -478,6 +478,10 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
             }
             chalk_ir::LifetimeData::Static => ty::RegionKind::ReStatic,
             chalk_ir::LifetimeData::Phantom(_, _) => unimplemented!(),
+            chalk_ir::LifetimeData::Empty(ui) => {
+                ty::RegionKind::ReEmpty(ty::UniverseIndex::from_usize(ui.counter))
+            }
+            chalk_ir::LifetimeData::Erased => ty::RegionKind::ReErased,
         };
         interner.tcx.mk_region(kind)
     }
diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs
index bd2f87f70a2f1..d98f18182c843 100644
--- a/compiler/rustc_traits/src/chalk/mod.rs
+++ b/compiler/rustc_traits/src/chalk/mod.rs
@@ -105,14 +105,40 @@ crate fn evaluate_goal<'tcx>(
     // really need this and so it's really minimal.
     // Right now, we also treat a `Unique` solution the same as
     // `Ambig(Definite)`. This really isn't right.
-    let make_solution = |subst: chalk_ir::Substitution<_>| {
+    let make_solution = |subst: chalk_ir::Substitution<_>,
+                         binders: chalk_ir::CanonicalVarKinds<_>| {
+        use rustc_middle::infer::canonical::CanonicalVarInfo;
+
         let mut var_values: IndexVec<BoundVar, GenericArg<'tcx>> = IndexVec::new();
         subst.as_slice(&interner).iter().for_each(|p| {
             var_values.push(p.lower_into(&interner));
         });
+        let variables: Vec<_> = binders
+            .iter(&interner)
+            .map(|var| {
+                let kind = match var.kind {
+                    chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind {
+                        chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General(
+                            ty::UniverseIndex::from_usize(var.skip_kind().counter),
+                        ),
+                        chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int,
+                        chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float,
+                    }),
+                    chalk_ir::VariableKind::Lifetime => CanonicalVarKind::Region(
+                        ty::UniverseIndex::from_usize(var.skip_kind().counter),
+                    ),
+                    chalk_ir::VariableKind::Const(_) => CanonicalVarKind::Const(
+                        ty::UniverseIndex::from_usize(var.skip_kind().counter),
+                    ),
+                };
+                CanonicalVarInfo { kind }
+            })
+            .collect();
+        let max_universe =
+            binders.iter(&interner).map(|v| v.skip_kind().counter).max().unwrap_or(0);
         let sol = Canonical {
-            max_universe: ty::UniverseIndex::from_usize(0),
-            variables: obligation.variables.clone(),
+            max_universe: ty::UniverseIndex::from_usize(max_universe),
+            variables: tcx.intern_canonical_var_infos(&variables),
             value: QueryResponse {
                 var_values: CanonicalVarValues { var_values },
                 region_constraints: QueryRegionConstraints::default(),
@@ -126,11 +152,13 @@ crate fn evaluate_goal<'tcx>(
         .map(|s| match s {
             Solution::Unique(subst) => {
                 // FIXME(chalk): handle constraints
-                make_solution(subst.value.subst)
+                make_solution(subst.value.subst, subst.binders)
             }
             Solution::Ambig(guidance) => {
                 match guidance {
-                    chalk_solve::Guidance::Definite(subst) => make_solution(subst.value),
+                    chalk_solve::Guidance::Definite(subst) => {
+                        make_solution(subst.value, subst.binders)
+                    }
                     chalk_solve::Guidance::Suggested(_) => unimplemented!(),
                     chalk_solve::Guidance::Unknown => {
                         // chalk_fulfill doesn't use the var_values here, so
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 79dc694e6be82..5554a448b5c59 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -823,6 +823,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// assert_eq!(map.remove(&1), Some("a"));
     /// assert_eq!(map.remove(&1), None);
     /// ```
+    #[doc(alias = "delete")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
     where
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index c2a96dd8ef471..d39eb1fd4f955 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -770,6 +770,7 @@ impl<T: Ord> BTreeSet<T> {
     /// assert_eq!(set.remove(&2), true);
     /// assert_eq!(set.remove(&2), false);
     /// ```
+    #[doc(alias = "delete")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
     where
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 10d30609aca32..6a7e4b2ba2573 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1234,7 +1234,7 @@ pub(crate) mod builtin {
     #[rustc_builtin_macro]
     #[macro_export]
     #[rustc_diagnostic_item = "assert_macro"]
-    #[allow_internal_unstable(core_panic)]
+    #[allow_internal_unstable(core_panic, edition_panic)]
     macro_rules! assert {
         ($cond:expr $(,)?) => {{ /* compiler built-in */ }};
         ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 64cf5286eb14a..778e34e634f64 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -889,6 +889,7 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
 /// ```
 ///
 /// [`RefCell`]: crate::cell::RefCell
+#[doc(alias = "delete")]
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn drop<T>(_x: T) {}
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 28a25572dd83e..27f7191831d41 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -859,6 +859,7 @@ where
     /// assert_eq!(map.remove(&1), Some("a"));
     /// assert_eq!(map.remove(&1), None);
     /// ```
+    #[doc(alias = "delete")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index b08510d6b01ae..912e975aa0a4c 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -874,6 +874,7 @@ where
     /// assert_eq!(set.remove(&2), true);
     /// assert_eq!(set.remove(&2), false);
     /// ```
+    #[doc(alias = "delete")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index e2d4f2e6a56af..43119c36cfec7 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -1524,6 +1524,7 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
 ///     Ok(())
 /// }
 /// ```
+#[doc(alias = "delete")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
     fs_imp::unlink(path.as_ref())
@@ -1958,6 +1959,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///     Ok(())
 /// }
 /// ```
+#[doc(alias = "delete")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
     fs_imp::rmdir(path.as_ref())
@@ -1995,6 +1997,7 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///     Ok(())
 /// }
 /// ```
+#[doc(alias = "delete")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
     fs_imp::remove_dir_all(path.as_ref())
diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs
index 617c4098aa959..525102212c41e 100644
--- a/library/std/src/os/linux/raw.rs
+++ b/library/std/src/os/linux/raw.rs
@@ -247,17 +247,17 @@ mod arch {
     use crate::os::raw::{c_int, c_long};
 
     #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub type blkcnt_t = u64;
+    pub type blkcnt_t = i64;
     #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub type blksize_t = u64;
+    pub type blksize_t = i32;
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub type ino_t = u64;
     #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub type nlink_t = u64;
+    pub type nlink_t = u32;
     #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub type off_t = u64;
+    pub type off_t = i64;
     #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub type time_t = i64;
+    pub type time_t = c_long;
 
     #[repr(C)]
     #[derive(Clone)]
@@ -288,15 +288,15 @@ mod arch {
         #[stable(feature = "raw_ext", since = "1.1.0")]
         pub st_blocks: i64,
         #[stable(feature = "raw_ext", since = "1.1.0")]
-        pub st_atime: i64,
+        pub st_atime: time_t,
         #[stable(feature = "raw_ext", since = "1.1.0")]
         pub st_atime_nsec: c_long,
         #[stable(feature = "raw_ext", since = "1.1.0")]
-        pub st_mtime: i64,
+        pub st_mtime: time_t,
         #[stable(feature = "raw_ext", since = "1.1.0")]
         pub st_mtime_nsec: c_long,
         #[stable(feature = "raw_ext", since = "1.1.0")]
-        pub st_ctime: i64,
+        pub st_ctime: time_t,
         #[stable(feature = "raw_ext", since = "1.1.0")]
         pub st_ctime_nsec: c_long,
         #[stable(feature = "raw_ext", since = "1.1.0")]
diff --git a/library/std/src/sys/wasm/thread.rs b/library/std/src/sys/wasm/thread.rs
index 95a9230aa7888..5eafb77da1dcd 100644
--- a/library/std/src/sys/wasm/thread.rs
+++ b/library/std/src/sys/wasm/thread.rs
@@ -86,7 +86,7 @@ pub fn my_id() -> u32 {
         if MY_ID == 0 {
             let mut cur = NEXT_ID.load(SeqCst);
             MY_ID = loop {
-                let next = cur.checked_add(1).unwrap_or_else(|| crate::arch::wasm32::unreachable());
+                let next = cur.checked_add(1).unwrap_or_else(|| crate::process::abort());
                 match NEXT_ID.compare_exchange(cur, next, SeqCst, SeqCst) {
                     Ok(_) => break next,
                     Err(i) => cur = i,
diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs
index ff1d82fc99040..faf554d285a9a 100644
--- a/library/unwind/src/libunwind.rs
+++ b/library/unwind/src/libunwind.rs
@@ -36,9 +36,12 @@ pub const unwinder_private_data_size: usize = 20;
 #[cfg(all(target_arch = "arm", target_os = "ios"))]
 pub const unwinder_private_data_size: usize = 5;
 
-#[cfg(target_arch = "aarch64")]
+#[cfg(all(target_arch = "aarch64", target_pointer_width = "64"))]
 pub const unwinder_private_data_size: usize = 2;
 
+#[cfg(all(target_arch = "aarch64", target_pointer_width = "32"))]
+pub const unwinder_private_data_size: usize = 5;
+
 #[cfg(target_arch = "mips")]
 pub const unwinder_private_data_size: usize = 2;
 
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index a367aa5349667..885fcfff030a2 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -146,7 +146,7 @@ mod defaults {
         // rustdoc tool.
         assert_eq!(
             first(builder.cache.all::<doc::ErrorIndex>()),
-            &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 0 }, target: a },]
+            &[doc::ErrorIndex { target: a },]
         );
         assert_eq!(
             first(builder.cache.all::<tool::ErrorIndex>()),
@@ -556,7 +556,7 @@ mod dist {
         // rustdoc tool.
         assert_eq!(
             first(builder.cache.all::<doc::ErrorIndex>()),
-            &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },]
+            &[doc::ErrorIndex { target: a },]
         );
         assert_eq!(
             first(builder.cache.all::<tool::ErrorIndex>()),
@@ -594,7 +594,7 @@ mod dist {
         // rustdoc tool.
         assert_eq!(
             first(builder.cache.all::<doc::ErrorIndex>()),
-            &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },]
+            &[doc::ErrorIndex { target: a },]
         );
         assert_eq!(
             first(builder.cache.all::<tool::ErrorIndex>()),
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 8c849846676f0..c4b3e4cf95dae 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -636,7 +636,6 @@ impl Step for Rustdoc {
 
 #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct ErrorIndex {
-    pub compiler: Compiler,
     pub target: TargetSelection,
 }
 
@@ -652,12 +651,7 @@ impl Step for ErrorIndex {
 
     fn make_run(run: RunConfig<'_>) {
         let target = run.target;
-        // error_index_generator depends on librustdoc. Use the compiler that
-        // is normally used to build rustdoc for other documentation so that
-        // it shares the same artifacts.
-        let compiler =
-            run.builder.compiler_for(run.builder.top_stage, run.builder.config.build, target);
-        run.builder.ensure(ErrorIndex { compiler, target });
+        run.builder.ensure(ErrorIndex { target });
     }
 
     /// Generates the HTML rendered error-index by running the
@@ -666,7 +660,7 @@ impl Step for ErrorIndex {
         builder.info(&format!("Documenting error index ({})", self.target));
         let out = builder.doc_out(self.target);
         t!(fs::create_dir_all(&out));
-        let mut index = tool::ErrorIndex::command(builder, self.compiler);
+        let mut index = tool::ErrorIndex::command(builder);
         index.arg("html");
         index.arg(out.join("error-index.html"));
         index.arg(&builder.version);
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 335a173100290..f0e33be757d16 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -14,7 +14,7 @@ use std::process::Command;
 use build_helper::{self, output, t};
 
 use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
-use crate::cache::{Interned, INTERNER};
+use crate::cache::Interned;
 use crate::compile;
 use crate::config::TargetSelection;
 use crate::dist;
@@ -1482,7 +1482,7 @@ impl Step for ErrorIndex {
         // error_index_generator depends on librustdoc. Use the compiler that
         // is normally used to build rustdoc for other tests (like compiletest
         // tests in src/test/rustdoc) so that it shares the same artifacts.
-        let compiler = run.builder.compiler_for(run.builder.top_stage, run.target, run.target);
+        let compiler = run.builder.compiler(run.builder.top_stage, run.builder.config.build);
         run.builder.ensure(ErrorIndex { compiler });
     }
 
@@ -1499,19 +1499,16 @@ impl Step for ErrorIndex {
         t!(fs::create_dir_all(&dir));
         let output = dir.join("error-index.md");
 
-        let mut tool = tool::ErrorIndex::command(builder, compiler);
+        let mut tool = tool::ErrorIndex::command(builder);
         tool.arg("markdown").arg(&output);
 
-        // Use the rustdoc that was built by self.compiler. This copy of
-        // rustdoc is shared with other tests (like compiletest tests in
-        // src/test/rustdoc). This helps avoid building rustdoc multiple
-        // times.
-        let rustdoc_compiler = builder.compiler(builder.top_stage, builder.config.build);
-        builder.info(&format!("Testing error-index stage{}", rustdoc_compiler.stage));
+        builder.info(&format!("Testing error-index stage{}", compiler.stage));
         let _time = util::timeit(&builder);
         builder.run_quiet(&mut tool);
-        builder.ensure(compile::Std { compiler: rustdoc_compiler, target: rustdoc_compiler.host });
-        markdown_test(builder, rustdoc_compiler, &output);
+        // The tests themselves need to link to std, so make sure it is
+        // available.
+        builder.ensure(compile::Std { compiler, target: compiler.host });
+        markdown_test(builder, compiler, &output);
     }
 }
 
@@ -1613,55 +1610,6 @@ impl Step for CrateLibrustc {
     }
 }
 
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct CrateNotDefault {
-    compiler: Compiler,
-    target: TargetSelection,
-    test_kind: TestKind,
-    krate: &'static str,
-}
-
-impl Step for CrateNotDefault {
-    type Output = ();
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.path("src/librustc_asan")
-            .path("src/librustc_lsan")
-            .path("src/librustc_msan")
-            .path("src/librustc_tsan")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        let builder = run.builder;
-        let compiler = builder.compiler(builder.top_stage, run.build_triple());
-
-        let test_kind = builder.kind.into();
-
-        builder.ensure(CrateNotDefault {
-            compiler,
-            target: run.target,
-            test_kind,
-            krate: match run.path {
-                _ if run.path.ends_with("src/librustc_asan") => "rustc_asan",
-                _ if run.path.ends_with("src/librustc_lsan") => "rustc_lsan",
-                _ if run.path.ends_with("src/librustc_msan") => "rustc_msan",
-                _ if run.path.ends_with("src/librustc_tsan") => "rustc_tsan",
-                _ => panic!("unexpected path {:?}", run.path),
-            },
-        });
-    }
-
-    fn run(self, builder: &Builder<'_>) {
-        builder.ensure(Crate {
-            compiler: self.compiler,
-            target: self.target,
-            mode: Mode::Std,
-            test_kind: self.test_kind,
-            krate: INTERNER.intern_str(self.krate),
-        });
-    }
-}
-
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Crate {
     pub compiler: Compiler,
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 835b8beb0e7df..bf6bea539e5c2 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -376,7 +376,15 @@ pub struct ErrorIndex {
 }
 
 impl ErrorIndex {
-    pub fn command(builder: &Builder<'_>, compiler: Compiler) -> Command {
+    pub fn command(builder: &Builder<'_>) -> Command {
+        // This uses stage-1 to match the behavior of building rustdoc.
+        // Error-index-generator links with the rustdoc library, so we want to
+        // use the same librustdoc to avoid building rustdoc twice (and to
+        // avoid building the compiler an extra time). This uses
+        // saturating_sub to deal with building with stage 0. (Using stage 0
+        // isn't recommended, since it will fail if any new error index tests
+        // use new syntax, but it should work otherwise.)
+        let compiler = builder.compiler(builder.top_stage.saturating_sub(1), builder.config.build);
         let mut cmd = Command::new(builder.ensure(ErrorIndex { compiler }));
         add_dylib_path(
             vec![PathBuf::from(&builder.sysroot_libdir(compiler, compiler.host))],
@@ -396,8 +404,14 @@ impl Step for ErrorIndex {
     fn make_run(run: RunConfig<'_>) {
         // Compile the error-index in the same stage as rustdoc to avoid
         // recompiling rustdoc twice if we can.
-        let host = run.builder.config.build;
-        let compiler = run.builder.compiler_for(run.builder.top_stage, host, host);
+        //
+        // NOTE: This `make_run` isn't used in normal situations, only if you
+        // manually build the tool with `x.py build
+        // src/tools/error-index-generator` which almost nobody does.
+        // Normally, `x.py test` or `x.py doc` will use the
+        // `ErrorIndex::command` function instead.
+        let compiler =
+            run.builder.compiler(run.builder.top_stage.saturating_sub(1), run.builder.config.build);
         run.builder.ensure(ErrorIndex { compiler });
     }
 
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index ce8caae375e98..eb74041964701 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -156,11 +156,14 @@ target | std | host | notes
 `aarch64-apple-tvos` | * |  | ARM64 tvOS
 `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
 `aarch64-unknown-hermit` | ? |  |
+`aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
 `aarch64-unknown-netbsd` | ✓ | ✓ |
 `aarch64-unknown-openbsd` | ✓ | ✓ | ARM64 OpenBSD
 `aarch64-unknown-redox` | ? |  | ARM64 Redox OS
 `aarch64-uwp-windows-msvc` | ? |  |
 `aarch64-wrs-vxworks` | ? |  |
+`aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
+`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
 `armv4t-unknown-linux-gnueabi` | ? |  |
 `armv5te-unknown-linux-uclibceabi` | ? |  | ARMv5TE Linux with uClibc
 `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
diff --git a/src/llvm-project b/src/llvm-project
index f9a8d70b6e036..70d09f218d1c8 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit f9a8d70b6e0365ac2172ca6b7f1de0341297458d
+Subproject commit 70d09f218d1c84fedabdb74881e214dacd5b0c3d
diff --git a/src/test/ui/associated-types/issue-24159.rs b/src/test/ui/associated-types/issue-24159.rs
new file mode 100644
index 0000000000000..49753e7bf1660
--- /dev/null
+++ b/src/test/ui/associated-types/issue-24159.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+#![allow(unused)]
+
+trait Bar<T> {
+    fn dummy(&self);
+}
+
+trait Foo {
+    type A;
+    type B: Bar<Self::A>;
+
+    fn get_b(&self) -> &Self::B;
+}
+
+fn test_bar<A, B: Bar<A>>(_: &B) {}
+
+fn test<A, F: Foo<A = A>>(f: &F) {
+    test_bar(f.get_b());
+}
+
+trait Bar1<T> {}
+trait Caz1 {
+    type A;
+    type B: Bar1<Self::A>;
+}
+
+fn test1<T, U>() where T: Caz1, U: Caz1<A = T::A> {}
+
+trait Bar2<T> {}
+trait Caz2 {
+    type A;
+    type B: Bar2<Self::A>;
+}
+fn test2<T: Caz2<A = ()>>() {}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-37808.rs b/src/test/ui/associated-types/issue-37808.rs
new file mode 100644
index 0000000000000..3701c37d0c86f
--- /dev/null
+++ b/src/test/ui/associated-types/issue-37808.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+trait Parent {
+    type Ty;
+    type Assoc: Child<Self::Ty>;
+}
+
+trait Child<T> {}
+
+struct ChildWrapper<T>(T);
+impl<A, T> Child<A> for ChildWrapper<T> where T: Child<A> {}
+
+struct ParentWrapper<T>(T);
+impl<A, T: Parent<Ty = A>> Parent for ParentWrapper<T> {
+    type Ty = A;
+    type Assoc = ChildWrapper<T::Assoc>;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-37883.rs b/src/test/ui/associated-types/issue-37883.rs
new file mode 100644
index 0000000000000..d854f6af3ea94
--- /dev/null
+++ b/src/test/ui/associated-types/issue-37883.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+use std::ops::Mul;
+
+fn main() {}
+
+trait Ring {}
+trait Real: Ring {}
+
+trait Module: Sized + Mul<<Self as Module>::Ring, Output = Self> {
+    type Ring: Ring;
+}
+
+trait EuclideanSpace {
+    type Coordinates: Module<Ring = Self::Real>;
+    type Real: Real;
+}
+
+trait Translation<E: EuclideanSpace> {
+    fn to_vector(&self) -> E::Coordinates;
+
+    fn powf(&self, n: <E::Coordinates as Module>::Ring) -> E::Coordinates {
+        self.to_vector() * n
+    }
+}
diff --git a/src/test/ui/associated-types/issue-39532.rs b/src/test/ui/associated-types/issue-39532.rs
new file mode 100644
index 0000000000000..52652cedec961
--- /dev/null
+++ b/src/test/ui/associated-types/issue-39532.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#![allow(unused)]
+
+trait Foo {
+    type Bar;
+    type Baz: Bar<Self::Bar>;
+}
+
+trait Bar<T> {}
+
+fn x<T: Foo<Bar = U>, U>(t: &T) {}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-62097.nll.stderr b/src/test/ui/async-await/issues/issue-62097.nll.stderr
index 2a399540e5296..ab10e5f1810bd 100644
--- a/src/test/ui/async-await/issues/issue-62097.nll.stderr
+++ b/src/test/ui/async-await/issues/issue-62097.nll.stderr
@@ -26,4 +26,5 @@ LL |         foo(|| self.bar()).await;
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0373`.
+Some errors have detailed explanations: E0373, E0521.
+For more information about an error, try `rustc --explain E0373`.
diff --git a/src/test/ui/borrowck/issue-45983.stderr b/src/test/ui/borrowck/issue-45983.stderr
index efd414a2d44ff..feb098c598588 100644
--- a/src/test/ui/borrowck/issue-45983.stderr
+++ b/src/test/ui/borrowck/issue-45983.stderr
@@ -10,3 +10,4 @@ LL |     give_any(|y| x = Some(y));
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/borrowck/issue-7573.stderr b/src/test/ui/borrowck/issue-7573.stderr
index 815419db833e5..9d86286b8676c 100644
--- a/src/test/ui/borrowck/issue-7573.stderr
+++ b/src/test/ui/borrowck/issue-7573.stderr
@@ -12,3 +12,4 @@ LL |         lines_to_use.push(installed_id);
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr
index 1dc60bb155452..14393bc8eeede 100644
--- a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr
+++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr
@@ -10,3 +10,4 @@ LL |     with_int(|y| x = Some(y));
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.stderr
index 5c548ec2876a3..a23fdacdee641 100644
--- a/src/test/ui/borrowck/regions-escape-bound-fn.stderr
+++ b/src/test/ui/borrowck/regions-escape-bound-fn.stderr
@@ -10,3 +10,4 @@ LL |     with_int(|y| x = Some(y));
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr
index f2a49e70d2716..153f77c8913ac 100644
--- a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr
+++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr
@@ -10,3 +10,4 @@ LL |     with_int(&mut |y| x = Some(y));
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr
index 213071abfffc3..0d97fa7e23014 100644
--- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr
+++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr
@@ -20,3 +20,4 @@ LL |         f = Some(x);
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
index 8a298b47fffa7..92547ca4796a4 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
@@ -4,7 +4,7 @@ error: unconstrained generic constant
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: consider adding a `where` bound for this expression
+help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::<T>() - 1]: Sized
   --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
    |
 LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
@@ -16,7 +16,7 @@ error: unconstrained generic constant
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: consider adding a `where` bound for this expression
+help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::<T>() - 1]: Sized
   --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27
    |
 LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
@@ -28,7 +28,7 @@ error: unconstrained generic constant
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: consider adding a `where` bound for this expression
+help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::<T>() - 1]: Sized
   --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
    |
 LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
@@ -40,7 +40,7 @@ error: unconstrained generic constant
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: consider adding a `where` bound for this expression
+help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::<T>() - 1]: Sized
   --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27
    |
 LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr
index 1f6dddb04e56c..00efb61000401 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr
@@ -4,7 +4,7 @@ error: unconstrained generic constant
 LL |     [0; size_of::<Foo<T>>()]
    |         ^^^^^^^^^^^^^^^^^^^
    |
-help: consider adding a `where` bound for this expression
+help: try adding a `where` bound using this expression: where [u8; size_of::<Foo<T>>()]: Sized
   --> $DIR/different-fn.rs:10:9
    |
 LL |     [0; size_of::<Foo<T>>()]
diff --git a/src/test/ui/const_evaluatable/needs_where_clause.rs b/src/test/ui/const_evaluatable/needs_where_clause.rs
new file mode 100644
index 0000000000000..498a2ae753361
--- /dev/null
+++ b/src/test/ui/const_evaluatable/needs_where_clause.rs
@@ -0,0 +1,14 @@
+#![crate_type = "lib"]
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+const fn complex_maths<T>(n : usize) -> usize {
+  2 * n + 1
+}
+
+struct Example<T, const N: usize> {
+  a: [f32; N],
+  b: [f32; complex_maths::<T>(N)],
+  //~^ ERROR unconstrained
+  c: T,
+}
diff --git a/src/test/ui/const_evaluatable/needs_where_clause.stderr b/src/test/ui/const_evaluatable/needs_where_clause.stderr
new file mode 100644
index 0000000000000..e991c508c03f3
--- /dev/null
+++ b/src/test/ui/const_evaluatable/needs_where_clause.stderr
@@ -0,0 +1,14 @@
+error: unconstrained generic constant
+  --> $DIR/needs_where_clause.rs:11:6
+   |
+LL |   b: [f32; complex_maths::<T>(N)],
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try adding a `where` bound using this expression: where [u8; complex_maths::<T>(N)]: Sized
+  --> $DIR/needs_where_clause.rs:11:12
+   |
+LL |   b: [f32; complex_maths::<T>(N)],
+   |            ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const_evaluatable/no_where_clause.rs b/src/test/ui/const_evaluatable/no_where_clause.rs
new file mode 100644
index 0000000000000..12f4a22038ef7
--- /dev/null
+++ b/src/test/ui/const_evaluatable/no_where_clause.rs
@@ -0,0 +1,29 @@
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features, unused)]
+
+const fn complex_maths(n : usize) -> usize {
+  2 * n + 1
+}
+
+pub struct Example<const N: usize> {
+  a: [f32; N],
+  b: [f32; complex_maths(N)],
+  //~^ ERROR unconstrained generic
+}
+
+impl<const N: usize> Example<N> {
+  pub fn new() -> Self {
+    Self {
+      a: [0.; N],
+      b: [0.; complex_maths(N)],
+    }
+  }
+}
+
+impl Example<2> {
+  pub fn sum(&self) -> f32 {
+    self.a.iter().sum::<f32>() + self.b.iter().sum::<f32>()
+  }
+}
+
+fn main() {}
diff --git a/src/test/ui/const_evaluatable/no_where_clause.stderr b/src/test/ui/const_evaluatable/no_where_clause.stderr
new file mode 100644
index 0000000000000..65100909e53d5
--- /dev/null
+++ b/src/test/ui/const_evaluatable/no_where_clause.stderr
@@ -0,0 +1,14 @@
+error: unconstrained generic constant
+  --> $DIR/no_where_clause.rs:10:6
+   |
+LL |   b: [f32; complex_maths(N)],
+   |      ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try adding a `where` bound using this expression: where [u8; complex_maths(N)]: Sized
+  --> $DIR/no_where_clause.rs:10:12
+   |
+LL |   b: [f32; complex_maths(N)],
+   |            ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr
index 9986220218e28..5fc8100409822 100644
--- a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr
+++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr
@@ -12,3 +12,4 @@ LL |         a = &b;
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr b/src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr
index 8e660d6814c43..d72435bc63111 100644
--- a/src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr
+++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr
@@ -10,3 +10,4 @@ LL |     static_val(x);
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/issues/issue-16683.nll.stderr b/src/test/ui/issues/issue-16683.nll.stderr
index b82b0b552e2dd..51d86eaf9e60c 100644
--- a/src/test/ui/issues/issue-16683.nll.stderr
+++ b/src/test/ui/issues/issue-16683.nll.stderr
@@ -8,3 +8,4 @@ LL |         self.a();
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/issues/issue-17758.nll.stderr b/src/test/ui/issues/issue-17758.nll.stderr
index 23557b4d956aa..075c141ed7af6 100644
--- a/src/test/ui/issues/issue-17758.nll.stderr
+++ b/src/test/ui/issues/issue-17758.nll.stderr
@@ -8,3 +8,4 @@ LL |         self.foo();
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr b/src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr
index 60420973e1ee0..57dab46df6b6a 100644
--- a/src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr
+++ b/src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr
@@ -22,3 +22,4 @@ LL |     lib::ref_obj(x)
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index 0115f5412f21d..0932f9415480c 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -83,4 +83,5 @@ LL | }
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0597`.
+Some errors have detailed explanations: E0521, E0597.
+For more information about an error, try `rustc --explain E0521`.
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index e55d033d2c763..bf6e2a922ed08 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -51,3 +51,4 @@ LL | |     });
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index ac4a4579c9cd2..a3d993848cbaa 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -51,3 +51,4 @@ LL | |     });
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/nll/outlives-suggestion-simple.stderr b/src/test/ui/nll/outlives-suggestion-simple.stderr
index 6300ea66511fb..bfe98a71a99b1 100644
--- a/src/test/ui/nll/outlives-suggestion-simple.stderr
+++ b/src/test/ui/nll/outlives-suggestion-simple.stderr
@@ -106,3 +106,4 @@ LL |         Bar2::new(&self)
 
 error: aborting due to 9 previous errors
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/nll/user-annotations/closure-substs.stderr b/src/test/ui/nll/user-annotations/closure-substs.stderr
index e3e294106d168..37e751aeb67b7 100644
--- a/src/test/ui/nll/user-annotations/closure-substs.stderr
+++ b/src/test/ui/nll/user-annotations/closure-substs.stderr
@@ -38,3 +38,4 @@ LL |         b(x);
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr
index d871eb5327d22..42dae7e40dbb3 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr
@@ -23,3 +23,4 @@ LL |     load0(ss)
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/panics/panic-2021.rs b/src/test/ui/panics/panic-2021.rs
new file mode 100644
index 0000000000000..e606612e10862
--- /dev/null
+++ b/src/test/ui/panics/panic-2021.rs
@@ -0,0 +1,9 @@
+// edition:2021
+
+fn main() {
+    panic!(123); //~ ERROR: format argument must be a string literal
+    panic!("{}"); //~ ERROR: 1 positional argument in format string
+    core::panic!("{}"); //~ ERROR: 1 positional argument in format string
+    assert!(false, 123); //~ ERROR: format argument must be a string literal
+    assert!(false, "{}"); //~ ERROR: 1 positional argument in format string
+}
diff --git a/src/test/ui/panics/panic-2021.stderr b/src/test/ui/panics/panic-2021.stderr
new file mode 100644
index 0000000000000..59b1e4f7a9858
--- /dev/null
+++ b/src/test/ui/panics/panic-2021.stderr
@@ -0,0 +1,42 @@
+error: format argument must be a string literal
+  --> $DIR/panic-2021.rs:4:12
+   |
+LL |     panic!(123);
+   |            ^^^
+   |
+help: you might be missing a string literal to format with
+   |
+LL |     panic!("{}", 123);
+   |            ^^^^^
+
+error: 1 positional argument in format string, but no arguments were given
+  --> $DIR/panic-2021.rs:5:13
+   |
+LL |     panic!("{}");
+   |             ^^
+
+error: 1 positional argument in format string, but no arguments were given
+  --> $DIR/panic-2021.rs:6:19
+   |
+LL |     core::panic!("{}");
+   |                   ^^
+
+error: format argument must be a string literal
+  --> $DIR/panic-2021.rs:7:20
+   |
+LL |     assert!(false, 123);
+   |                    ^^^
+   |
+help: you might be missing a string literal to format with
+   |
+LL |     assert!(false, "{}", 123);
+   |                    ^^^^^
+
+error: 1 positional argument in format string, but no arguments were given
+  --> $DIR/panic-2021.rs:8:21
+   |
+LL |     assert!(false, "{}");
+   |                     ^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/regions/issue-78262.nll.stderr b/src/test/ui/regions/issue-78262.nll.stderr
index 4607dbad4220b..fafff35e4155f 100644
--- a/src/test/ui/regions/issue-78262.nll.stderr
+++ b/src/test/ui/regions/issue-78262.nll.stderr
@@ -8,3 +8,4 @@ LL |     let f = |x: &dyn TT| x.func();
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr b/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr
index d941030d82474..89a22adc8f021 100644
--- a/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr
+++ b/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr
@@ -11,3 +11,4 @@ LL |         x.unwrap()
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr
index 92a3942c916b7..ed7b17c207c30 100644
--- a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr
+++ b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr
@@ -13,3 +13,4 @@ LL |     f.method(b);
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/regions/regions-nested-fns.nll.stderr b/src/test/ui/regions/regions-nested-fns.nll.stderr
index 9d966486f98d1..60754f4c2284c 100644
--- a/src/test/ui/regions/regions-nested-fns.nll.stderr
+++ b/src/test/ui/regions/regions-nested-fns.nll.stderr
@@ -50,4 +50,5 @@ LL |         if false { return x; }
 
 error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0597`.
+Some errors have detailed explanations: E0521, E0597.
+For more information about an error, try `rustc --explain E0521`.
diff --git a/src/test/ui/suggestions/field-access.fixed b/src/test/ui/suggestions/field-access.fixed
index 05a4a0eb1266d..ed9aef6e37444 100644
--- a/src/test/ui/suggestions/field-access.fixed
+++ b/src/test/ui/suggestions/field-access.fixed
@@ -18,17 +18,17 @@ union Foo {
 fn main() {
     let a = A { b: B::Fst };
     if let B::Fst = a.b {}; //~ ERROR mismatched types [E0308]
-    //~^ HELP you might have meant to use field `b` of type `B`
+    //~^ HELP you might have meant to use field `b` whose type is `B`
     match a.b {
-        //~^ HELP you might have meant to use field `b` of type `B`
-        //~| HELP you might have meant to use field `b` of type `B`
+        //~^ HELP you might have meant to use field `b` whose type is `B`
+        //~| HELP you might have meant to use field `b` whose type is `B`
         B::Fst => (), //~ ERROR mismatched types [E0308]
         B::Snd => (), //~ ERROR mismatched types [E0308]
     }
 
     let foo = Foo { bar: 42 };
     match unsafe { foo.bar } {
-        //~^ HELP you might have meant to use field `bar` of type `u32`
+        //~^ HELP you might have meant to use field `bar` whose type is `u32`
         1u32 => (), //~ ERROR mismatched types [E0308]
         _ => (),
     }
diff --git a/src/test/ui/suggestions/field-access.rs b/src/test/ui/suggestions/field-access.rs
index ad23c0ffa2e74..d80488e8a45f5 100644
--- a/src/test/ui/suggestions/field-access.rs
+++ b/src/test/ui/suggestions/field-access.rs
@@ -18,17 +18,17 @@ union Foo {
 fn main() {
     let a = A { b: B::Fst };
     if let B::Fst = a {}; //~ ERROR mismatched types [E0308]
-    //~^ HELP you might have meant to use field `b` of type `B`
+    //~^ HELP you might have meant to use field `b` whose type is `B`
     match a {
-        //~^ HELP you might have meant to use field `b` of type `B`
-        //~| HELP you might have meant to use field `b` of type `B`
+        //~^ HELP you might have meant to use field `b` whose type is `B`
+        //~| HELP you might have meant to use field `b` whose type is `B`
         B::Fst => (), //~ ERROR mismatched types [E0308]
         B::Snd => (), //~ ERROR mismatched types [E0308]
     }
 
     let foo = Foo { bar: 42 };
     match foo {
-        //~^ HELP you might have meant to use field `bar` of type `u32`
+        //~^ HELP you might have meant to use field `bar` whose type is `u32`
         1u32 => (), //~ ERROR mismatched types [E0308]
         _ => (),
     }
diff --git a/src/test/ui/suggestions/field-access.stderr b/src/test/ui/suggestions/field-access.stderr
index aad9872032a2a..b113b3746d87e 100644
--- a/src/test/ui/suggestions/field-access.stderr
+++ b/src/test/ui/suggestions/field-access.stderr
@@ -9,7 +9,7 @@ LL |     if let B::Fst = a {};
    |            |
    |            expected struct `A`, found enum `B`
    |
-help: you might have meant to use field `b` of type `B`
+help: you might have meant to use field `b` whose type is `B`
    |
 LL |     if let B::Fst = a.b {};
    |                     ^^^
@@ -26,7 +26,7 @@ LL |     match a {
 LL |         B::Fst => (),
    |         ^^^^^^ expected struct `A`, found enum `B`
    |
-help: you might have meant to use field `b` of type `B`
+help: you might have meant to use field `b` whose type is `B`
    |
 LL |     match a.b {
    |           ^^^
@@ -43,7 +43,7 @@ LL |     match a {
 LL |         B::Snd => (),
    |         ^^^^^^ expected struct `A`, found enum `B`
    |
-help: you might have meant to use field `b` of type `B`
+help: you might have meant to use field `b` whose type is `B`
    |
 LL |     match a.b {
    |           ^^^
@@ -57,7 +57,7 @@ LL |
 LL |         1u32 => (),
    |         ^^^^ expected union `Foo`, found `u32`
    |
-help: you might have meant to use field `bar` of type `u32`
+help: you might have meant to use field `bar` whose type is `u32`
    |
 LL |     match unsafe { foo.bar } {
    |           ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.nll.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.nll.stderr
index 697467dc3a630..6c235ae8f0277 100644
--- a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.nll.stderr
+++ b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.nll.stderr
@@ -40,3 +40,4 @@ LL |         MyTrait::use_self(val)
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/tools/clippy/.editorconfig b/src/tools/clippy/.editorconfig
index a13173544d80a..ec6e107d547f0 100644
--- a/src/tools/clippy/.editorconfig
+++ b/src/tools/clippy/.editorconfig
@@ -13,6 +13,8 @@ indent_style = space
 indent_size = 4
 
 [*.md]
+# double whitespace at end of line
+# denotes a line break in Markdown
 trim_trailing_whitespace = false
 
 [*.yml]
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 1647df8044ccc..292850bd9e277 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -38,6 +38,7 @@ const OS_TABLE: &[(&str, &str)] = &[
 
 const ARCH_TABLE: &[(&str, &str)] = &[
     ("aarch64", "aarch64"),
+    ("aarch64_be", "aarch64"),
     ("amd64", "x86_64"),
     ("arm", "arm"),
     ("arm64", "aarch64"),
@@ -110,6 +111,7 @@ pub const TSAN_SUPPORTED_TARGETS: &[&str] = &[
 ];
 
 const BIG_ENDIAN: &[&str] = &[
+    "aarch64_be",
     "armebv7r",
     "mips",
     "mips64",
@@ -160,7 +162,9 @@ pub fn matches_env(triple: &str, name: &str) -> bool {
 }
 
 pub fn get_pointer_width(triple: &str) -> &'static str {
-    if (triple.contains("64") && !triple.ends_with("gnux32")) || triple.starts_with("s390x") {
+    if (triple.contains("64") && !triple.ends_with("gnux32") && !triple.ends_with("gnu_ilp32"))
+        || triple.starts_with("s390x")
+    {
         "64bit"
     } else if triple.starts_with("avr") {
         "16bit"