about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-06 23:39:38 +0000
committerbors <bors@rust-lang.org>2025-03-06 23:39:38 +0000
commit98a48781feb1220c0cf2feea23f9ef92cdfa7437 (patch)
tree81bce0037094da6e658bb51e00f5ef929e3e6361 /compiler
parentb74da9613a8cb5ba67a985f71325be0b7b16c0dd (diff)
parent071bc4688076e6d18cbba3778af2e171dbf8f4c1 (diff)
downloadrust-98a48781feb1220c0cf2feea23f9ef92cdfa7437.tar.gz
rust-98a48781feb1220c0cf2feea23f9ef92cdfa7437.zip
Auto merge of #138114 - compiler-errors:rollup-7xr4b69, r=compiler-errors
Rollup of 25 pull requests

Successful merges:

 - #135733 (Implement `&pin const self` and `&pin mut self` sugars)
 - #135895 (Document workings of successors more clearly)
 - #136922 (Pattern types: Avoid having to handle an Option for range ends in the type system or the HIR)
 - #137303 (Remove `MaybeForgetReturn` suggestion)
 - #137327 (Undeprecate env::home_dir)
 - #137358 (Match Ergonomics 2024: add context and examples to the unstable book)
 - #137534 ([rustdoc] hide item that is not marked as doc(inline) and whose src is doc(hidden))
 - #137565 (Try to point of macro expansion from resolver and method errors if it involves macro var)
 - #137637 (Check dyn flavor before registering upcast goal on wide pointer cast in MIR typeck)
 - #137643 (Add DWARF test case for non-C-like `repr128` enums)
 - #137744 (Re-add `Clone`-derive on `Thir`)
 - #137758 (fix usage of ty decl macro fragments in attributes)
 - #137764 (Ensure that negative auto impls are always applicable)
 - #137772 (Fix char count in `Display` for `ByteStr`)
 - #137798 (ci: use ubuntu 24 on arm large runner)
 - #137802 (miri native-call support: all previously exposed provenance is accessible to the callee)
 - #137805 (adjust Layout debug printing to match the internal field name)
 - #137808 (Do not require that unsafe fields lack drop glue)
 - #137820 (Clarify why InhabitedPredicate::instantiate_opt exists)
 - #137825 (Provide more context on resolve error caused from incorrect RTN)
 - #137834 (rustc_fluent_macro: use CARGO_CRATE_NAME instead of CARGO_PKG_NAME)
 - #137868 (Add minimal platform support documentation for powerpc-unknown-linux-gnuspe)
 - #137910 (Improve error message for `AsyncFn` trait failure for RPIT)
 - #137920 (interpret/provenance_map: consistently use range_is_empty)
 - #138038 (Update `compiler-builtins` to 0.1.151)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_abi/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/ast.rs21
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs5
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs122
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs7
-rw-r--r--compiler/rustc_attr_parsing/src/parser.rs9
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch4
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs15
-rw-r--r--compiler/rustc_data_structures/src/marker.rs10
-rw-r--r--compiler/rustc_errors/src/lib.rs1
-rw-r--r--compiler/rustc_fluent_macro/src/fluent.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs4
-rw-r--r--compiler/rustc_hir/src/intravisit.rs6
-rw-r--r--compiler/rustc_hir/src/lang_items.rs3
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl12
-rw-r--r--compiler/rustc_hir_analysis/src/check/always_applicable.rs (renamed from compiler/rustc_hir_analysis/src/check/dropck.rs)151
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs32
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs26
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs27
-rw-r--r--compiler/rustc_hir_analysis/src/errors/pattern_types.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs40
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs10
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs35
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs60
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs24
-rw-r--r--compiler/rustc_lint/src/types.rs28
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs42
-rw-r--r--compiler/rustc_middle/src/thir.rs47
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs10
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs10
-rw-r--r--compiler/rustc_middle/src/ty/pattern.rs36
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs20
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs1
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs6
-rw-r--r--compiler/rustc_parse/src/parser/item.rs62
-rw-r--r--compiler/rustc_resolve/src/late.rs18
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs47
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs7
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs9
-rw-r--r--compiler/rustc_span/src/hygiene.rs3
-rw-r--r--compiler/rustc_span/src/lib.rs31
-rw-r--r--compiler/rustc_span/src/symbol.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs8
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs8
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs115
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs10
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs23
57 files changed, 719 insertions, 521 deletions
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 2197dd68eaf..a59dc870aa3 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1812,7 +1812,7 @@ where
         f.debug_struct("Layout")
             .field("size", size)
             .field("align", align)
-            .field("abi", backend_repr)
+            .field("backend_repr", backend_repr)
             .field("fields", fields)
             .field("largest_niche", largest_niche)
             .field("uninhabited", uninhabited)
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index fb6b36e1a09..11fc409cf43 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2641,6 +2641,8 @@ pub enum SelfKind {
     Value(Mutability),
     /// `&'lt self`, `&'lt mut self`
     Region(Option<Lifetime>, Mutability),
+    /// `&'lt pin const self`, `&'lt pin mut self`
+    Pinned(Option<Lifetime>, Mutability),
     /// `self: TYPE`, `mut self: TYPE`
     Explicit(P<Ty>, Mutability),
 }
@@ -2650,6 +2652,8 @@ impl SelfKind {
         match self {
             SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
             SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
+            SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
+            SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
             SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
                 unreachable!("if we had an explicit self, we wouldn't be here")
             }
@@ -2666,11 +2670,13 @@ impl Param {
             if ident.name == kw::SelfLower {
                 return match self.ty.kind {
                     TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
-                    TyKind::Ref(lt, MutTy { ref ty, mutbl })
-                    | TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
+                    TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
+                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
+                    }
+                    TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
                         if ty.kind.is_implicit_self() =>
                     {
-                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
+                        Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
                     }
                     _ => Some(respan(
                         self.pat.span.to(self.ty.span),
@@ -2712,6 +2718,15 @@ impl Param {
                     tokens: None,
                 }),
             ),
+            SelfKind::Pinned(lt, mutbl) => (
+                mutbl,
+                P(Ty {
+                    id: DUMMY_NODE_ID,
+                    kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
+                    span,
+                    tokens: None,
+                }),
+            ),
         };
         Param {
             attrs,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index c0188dde565..f5832068028 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -136,6 +136,7 @@ struct LoweringContext<'a, 'hir> {
 
     allow_try_trait: Arc<[Symbol]>,
     allow_gen_future: Arc<[Symbol]>,
+    allow_pattern_type: Arc<[Symbol]>,
     allow_async_iterator: Arc<[Symbol]>,
     allow_for_await: Arc<[Symbol]>,
     allow_async_fn_traits: Arc<[Symbol]>,
@@ -176,6 +177,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             impl_trait_defs: Vec::new(),
             impl_trait_bounds: Vec::new(),
             allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
+            allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
             allow_gen_future: if tcx.features().async_fn_track_caller() {
                 [sym::gen_future, sym::closure_track_caller].into()
             } else {
@@ -926,7 +928,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     if let Some(first_char) = constraint.ident.as_str().chars().next()
                         && first_char.is_ascii_lowercase()
                     {
-                        tracing::info!(?data, ?data.inputs);
                         let err = match (&data.inputs[..], &data.output) {
                             ([_, ..], FnRetTy::Default(_)) => {
                                 errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
@@ -1365,7 +1366,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }
             }
             TyKind::Pat(ty, pat) => {
-                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
+                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
             }
             TyKind::MacCall(_) => {
                 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2dcfe7c745d..728981dea5f 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -3,11 +3,11 @@ use std::sync::Arc;
 use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_hir as hir;
-use rustc_hir::def::Res;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{self as hir, LangItem};
 use rustc_middle::span_bug;
 use rustc_span::source_map::{Spanned, respan};
-use rustc_span::{Ident, Span};
+use rustc_span::{DesugaringKind, Ident, Span, kw};
 
 use super::errors::{
     ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
@@ -430,22 +430,124 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
     }
 
-    pub(crate) fn lower_ty_pat(&mut self, pattern: &TyPat) -> &'hir hir::TyPat<'hir> {
-        self.arena.alloc(self.lower_ty_pat_mut(pattern))
+    pub(crate) fn lower_ty_pat(
+        &mut self,
+        pattern: &TyPat,
+        base_type: Span,
+    ) -> &'hir hir::TyPat<'hir> {
+        self.arena.alloc(self.lower_ty_pat_mut(pattern, base_type))
     }
 
-    fn lower_ty_pat_mut(&mut self, pattern: &TyPat) -> hir::TyPat<'hir> {
+    fn lower_ty_pat_mut(&mut self, pattern: &TyPat, base_type: Span) -> hir::TyPat<'hir> {
         // loop here to avoid recursion
         let pat_hir_id = self.lower_node_id(pattern.id);
         let node = match &pattern.kind {
-            TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range(
-                e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
-                e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
-                self.lower_range_end(end, e2.is_some()),
+            TyPatKind::Range(e1, e2, Spanned { node: end, span }) => hir::TyPatKind::Range(
+                e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)).unwrap_or_else(|| {
+                    self.lower_ty_pat_range_end(
+                        hir::LangItem::RangeMin,
+                        span.shrink_to_lo(),
+                        base_type,
+                    )
+                }),
+                e2.as_deref()
+                    .map(|e| match end {
+                        RangeEnd::Included(..) => self.lower_anon_const_to_const_arg(e),
+                        RangeEnd::Excluded => self.lower_excluded_range_end(e),
+                    })
+                    .unwrap_or_else(|| {
+                        self.lower_ty_pat_range_end(
+                            hir::LangItem::RangeMax,
+                            span.shrink_to_hi(),
+                            base_type,
+                        )
+                    }),
             ),
             TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
         };
 
         hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
     }
+
+    /// Lowers the range end of an exclusive range (`2..5`) to an inclusive range 2..=(5 - 1).
+    /// This way the type system doesn't have to handle the distinction between inclusive/exclusive ranges.
+    fn lower_excluded_range_end(&mut self, e: &AnonConst) -> &'hir hir::ConstArg<'hir> {
+        let span = self.lower_span(e.value.span);
+        let unstable_span = self.mark_span_with_reason(
+            DesugaringKind::PatTyRange,
+            span,
+            Some(Arc::clone(&self.allow_pattern_type)),
+        );
+        let anon_const = self.with_new_scopes(span, |this| {
+            let def_id = this.local_def_id(e.id);
+            let hir_id = this.lower_node_id(e.id);
+            let body = this.lower_body(|this| {
+                // Need to use a custom function as we can't just subtract `1` from a `char`.
+                let kind = hir::ExprKind::Path(this.make_lang_item_qpath(
+                    hir::LangItem::RangeSub,
+                    unstable_span,
+                    None,
+                ));
+                let fn_def = this.arena.alloc(hir::Expr { hir_id: this.next_id(), kind, span });
+                let args = this.arena.alloc([this.lower_expr_mut(&e.value)]);
+                (
+                    &[],
+                    hir::Expr {
+                        hir_id: this.next_id(),
+                        kind: hir::ExprKind::Call(fn_def, args),
+                        span,
+                    },
+                )
+            });
+            hir::AnonConst { def_id, hir_id, body, span }
+        });
+        self.arena.alloc(hir::ConstArg {
+            hir_id: self.next_id(),
+            kind: hir::ConstArgKind::Anon(self.arena.alloc(anon_const)),
+        })
+    }
+
+    /// When a range has no end specified (`1..` or `1..=`) or no start specified (`..5` or `..=5`),
+    /// we instead use a constant of the MAX/MIN of the type.
+    /// This way the type system does not have to handle the lack of a start/end.
+    fn lower_ty_pat_range_end(
+        &mut self,
+        lang_item: LangItem,
+        span: Span,
+        base_type: Span,
+    ) -> &'hir hir::ConstArg<'hir> {
+        let parent_def_id = self.current_hir_id_owner.def_id;
+        let node_id = self.next_node_id();
+
+        // Add a definition for the in-band const def.
+        // We're generating a range end that didn't exist in the AST,
+        // so the def collector didn't create the def ahead of time. That's why we have to do
+        // it here.
+        let def_id = self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span);
+        let hir_id = self.lower_node_id(node_id);
+
+        let unstable_span = self.mark_span_with_reason(
+            DesugaringKind::PatTyRange,
+            self.lower_span(span),
+            Some(Arc::clone(&self.allow_pattern_type)),
+        );
+        let span = self.lower_span(base_type);
+
+        let path_expr = hir::Expr {
+            hir_id: self.next_id(),
+            kind: hir::ExprKind::Path(self.make_lang_item_qpath(lang_item, unstable_span, None)),
+            span,
+        };
+
+        let ct = self.with_new_scopes(span, |this| {
+            self.arena.alloc(hir::AnonConst {
+                def_id,
+                hir_id,
+                body: this.lower_body(|_this| (&[], path_expr)),
+                span,
+            })
+        });
+        let hir_id = self.next_id();
+        self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id })
+    }
 }
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 6b6244b05aa..d00c797755f 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -268,7 +268,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }
                 GenericArgs::Parenthesized(data) => match generic_args_mode {
                     GenericArgsMode::ReturnTypeNotation => {
-                        tracing::info!(?data, ?data.inputs);
                         let err = match (&data.inputs[..], &data.output) {
                             ([_, ..], FnRetTy::Default(_)) => {
                                 BadReturnTypeNotation::Inputs { span: data.inputs_span }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index d747237f76d..01fc272a458 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1783,6 +1783,13 @@ impl<'a> State<'a> {
                 self.print_mutability(*m, false);
                 self.word("self")
             }
+            SelfKind::Pinned(lt, m) => {
+                self.word("&");
+                self.print_opt_lifetime(lt);
+                self.word("pin ");
+                self.print_mutability(*m, true);
+                self.word("self")
+            }
             SelfKind::Explicit(typ, m) => {
                 self.print_mutability(*m, false);
                 self.word("self");
diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs
index 96fc9d7d9ac..f0cce26f4e2 100644
--- a/compiler/rustc_attr_parsing/src/parser.rs
+++ b/compiler/rustc_attr_parsing/src/parser.rs
@@ -473,6 +473,15 @@ impl<'a> MetaItemListParserContext<'a> {
         {
             self.inside_delimiters.next();
             return Some(MetaItemOrLitParser::Lit(lit));
+        } else if let Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) =
+            self.inside_delimiters.peek()
+        {
+            self.inside_delimiters.next();
+            return MetaItemListParserContext {
+                inside_delimiters: inner_tokens.iter().peekable(),
+                dcx: self.dcx,
+            }
+            .next();
         }
 
         // or a path.
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6d05696e146..480d90932b9 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2120,8 +2120,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                                 //
                                 // Note that other checks (such as denying `dyn Send` -> `dyn
                                 // Debug`) are in `rustc_hir_typeck`.
-                                if let ty::Dynamic(src_tty, _src_lt, _) = *src_tail.kind()
-                                    && let ty::Dynamic(dst_tty, dst_lt, _) = *dst_tail.kind()
+                                if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) = *src_tail.kind()
+                                    && let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) = *dst_tail.kind()
                                     && src_tty.principal().is_some()
                                     && dst_tty.principal().is_some()
                                 {
diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
index d8db7d63f2d..c2027863b00 100644
--- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
@@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644
  
  [dependencies]
  core = { path = "../core", public = true }
--compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] }
-+compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std', 'no-f16-f128'] }
+-compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] }
++compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std', 'no-f16-f128'] }
  
  [dev-dependencies]
  rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 4f4b6785844..ce0b5a350e0 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -955,18 +955,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     /// Handle the effect an FFI call might have on the state of allocations.
     /// This overapproximates the modifications which external code might make to memory:
-    /// We set all reachable allocations as initialized, mark all provenances as exposed
+    /// We set all reachable allocations as initialized, mark all reachable provenances as exposed
     /// and overwrite them with `Provenance::WILDCARD`.
-    pub fn prepare_for_native_call(
-        &mut self,
-        id: AllocId,
-        initial_prov: M::Provenance,
-    ) -> InterpResult<'tcx> {
-        // Expose provenance of the root allocation.
-        M::expose_provenance(self, initial_prov)?;
-
+    ///
+    /// The allocations in `ids` are assumed to be already exposed.
+    pub fn prepare_for_native_call(&mut self, ids: Vec<AllocId>) -> InterpResult<'tcx> {
         let mut done = FxHashSet::default();
-        let mut todo = vec![id];
+        let mut todo = ids;
         while let Some(id) = todo.pop() {
             if !done.insert(id) {
                 // We already saw this allocation before, don't process it again.
diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs
index 6ae97222f77..4cacc269709 100644
--- a/compiler/rustc_data_structures/src/marker.rs
+++ b/compiler/rustc_data_structures/src/marker.rs
@@ -1,3 +1,5 @@
+use std::alloc::Allocator;
+
 #[rustc_on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \
             Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`")]
 // This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()`
@@ -28,8 +30,8 @@ impls_dyn_send_neg!(
     [*const T where T: ?Sized]
     [*mut T where T: ?Sized]
     [std::ptr::NonNull<T> where T: ?Sized]
-    [std::rc::Rc<T> where T: ?Sized]
-    [std::rc::Weak<T> where T: ?Sized]
+    [std::rc::Rc<T, A> where T: ?Sized, A: Allocator]
+    [std::rc::Weak<T, A> where T: ?Sized, A: Allocator]
     [std::sync::MutexGuard<'_, T> where T: ?Sized]
     [std::sync::RwLockReadGuard<'_, T> where T: ?Sized]
     [std::sync::RwLockWriteGuard<'_, T> where T: ?Sized]
@@ -96,8 +98,8 @@ impls_dyn_sync_neg!(
     [std::cell::RefCell<T> where T: ?Sized]
     [std::cell::UnsafeCell<T> where T: ?Sized]
     [std::ptr::NonNull<T> where T: ?Sized]
-    [std::rc::Rc<T> where T: ?Sized]
-    [std::rc::Weak<T> where T: ?Sized]
+    [std::rc::Rc<T, A> where T: ?Sized, A: Allocator]
+    [std::rc::Weak<T, A> where T: ?Sized, A: Allocator]
     [std::cell::OnceCell<T> where T]
     [std::sync::mpsc::Receiver<T> where T]
     [std::sync::mpsc::Sender<T> where T]
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index f2b133f5677..f69e756a3e1 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -626,7 +626,6 @@ pub enum StashKey {
     MaybeFruTypo,
     CallAssocMethod,
     AssociatedTypeSuggestion,
-    MaybeForgetReturn,
     /// Query cycle detected, stashing in favor of a better error.
     Cycle,
     UndeterminedMacroResolution,
diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs
index d4604c27e6d..b04fd1b48f7 100644
--- a/compiler/rustc_fluent_macro/src/fluent.rs
+++ b/compiler/rustc_fluent_macro/src/fluent.rs
@@ -78,8 +78,8 @@ fn failed(crate_name: &Ident) -> proc_macro::TokenStream {
 
 /// See [rustc_fluent_macro::fluent_messages].
 pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-    let crate_name = std::env::var("CARGO_PKG_NAME")
-        // If `CARGO_PKG_NAME` is missing, then we're probably running in a test, so use
+    let crate_name = std::env::var("CARGO_CRATE_NAME")
+        // If `CARGO_CRATE_NAME` is missing, then we're probably running in a test, so use
         // `no_crate`.
         .unwrap_or_else(|_| "no_crate".to_string())
         .replace("rustc_", "");
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 399f1f4b237..df305e6e769 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1600,7 +1600,7 @@ pub struct PatField<'hir> {
     pub span: Span,
 }
 
-#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic, Hash, Eq, Encodable, Decodable)]
 pub enum RangeEnd {
     Included,
     Excluded,
@@ -1668,7 +1668,7 @@ pub enum PatExprKind<'hir> {
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum TyPatKind<'hir> {
     /// A range pattern (e.g., `1..=2` or `1..2`).
-    Range(Option<&'hir ConstArg<'hir>>, Option<&'hir ConstArg<'hir>>, RangeEnd),
+    Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
 
     /// A placeholder for a pattern that wasn't well formed in some way.
     Err(ErrorGuaranteed),
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index e349e23f7dc..41eb5b45bd1 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -708,9 +708,9 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Res
 pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) -> V::Result {
     try_visit!(visitor.visit_id(pattern.hir_id));
     match pattern.kind {
-        TyPatKind::Range(lower_bound, upper_bound, _) => {
-            visit_opt!(visitor, visit_const_arg_unambig, lower_bound);
-            visit_opt!(visitor, visit_const_arg_unambig, upper_bound);
+        TyPatKind::Range(lower_bound, upper_bound) => {
+            try_visit!(visitor.visit_const_arg_unambig(lower_bound));
+            try_visit!(visitor.visit_const_arg_unambig(upper_bound));
         }
         TyPatKind::Err(_) => (),
     }
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index f5626937ec4..c3b14a4e06c 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -418,6 +418,9 @@ language_item_table! {
     Range,                   sym::Range,               range_struct,               Target::Struct,         GenericRequirement::None;
     RangeToInclusive,        sym::RangeToInclusive,    range_to_inclusive_struct,  Target::Struct,         GenericRequirement::None;
     RangeTo,                 sym::RangeTo,             range_to_struct,            Target::Struct,         GenericRequirement::None;
+    RangeMax,                sym::RangeMax,            range_max,                  Target::AssocConst,     GenericRequirement::Exact(0);
+    RangeMin,                sym::RangeMin,            range_min,                  Target::AssocConst,     GenericRequirement::Exact(0);
+    RangeSub,                sym::RangeSub,            range_sub,                  Target::Method(MethodKind::Trait { body: false }),     GenericRequirement::Exact(0);
 
     // `new_range` types that are `Copy + IntoIterator`
     RangeFromCopy,           sym::RangeFromCopy,       range_from_copy_struct,     Target::Struct,         GenericRequirement::None;
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 3f75cce0092..935f4de6c58 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -244,9 +244,6 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a
     .help = consider moving this inherent impl into the crate defining the type if possible
     .span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
 
-hir_analysis_invalid_base_type = `{$ty}` is not a valid base type for range patterns
-    .note = range patterns only support integers
-
 hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}`
     .note = type of `self` must not be a method generic parameter type
 
@@ -278,13 +275,6 @@ hir_analysis_invalid_union_field =
 hir_analysis_invalid_union_field_sugg =
     wrap the field type in `ManuallyDrop<...>`
 
-hir_analysis_invalid_unsafe_field =
-    field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe
-    .note = unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
-
-hir_analysis_invalid_unsafe_field_sugg =
-    wrap the field type in `ManuallyDrop<...>`
-
 hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
     .label = const parameter declared here
 
@@ -620,6 +610,8 @@ hir_analysis_variances_of = {$variances}
 hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause
     .label = `main` cannot have a `where` clause
 
+hir_analysis_within_macro = due to this macro variable
+
 hir_analysis_wrong_number_of_generic_arguments_to_intrinsic =
     intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected}
     .label = expected {$expected} {$descr} {$expected ->
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs
index d7dfe482da4..ba5b61d3fce 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs
@@ -1,8 +1,15 @@
+//! This module contains methods that assist in checking that impls are general
+//! enough, i.e. that they always apply to every valid instantaiton of the ADT
+//! they're implemented for.
+//!
+//! This is necessary for `Drop` and negative impls to be well-formed.
+
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::codes::*;
 use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
 use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
 use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
+use rustc_middle::span_bug;
 use rustc_middle::ty::util::CheckRegions;
 use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypingMode};
 use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -27,11 +34,12 @@ use crate::hir::def_id::{DefId, LocalDefId};
 /// 3. Any bounds on the generic parameters must be reflected in the
 ///    struct/enum definition for the nominal type itself (i.e.
 ///    cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
-///
 pub(crate) fn check_drop_impl(
     tcx: TyCtxt<'_>,
     drop_impl_did: DefId,
 ) -> Result<(), ErrorGuaranteed> {
+    let drop_impl_did = drop_impl_did.expect_local();
+
     match tcx.impl_polarity(drop_impl_did) {
         ty::ImplPolarity::Positive => {}
         ty::ImplPolarity::Negative => {
@@ -45,55 +53,107 @@ pub(crate) fn check_drop_impl(
             }));
         }
     }
-    let dtor_self_type = tcx.type_of(drop_impl_did).instantiate_identity();
-    match dtor_self_type.kind() {
+
+    tcx.ensure_ok().orphan_check_impl(drop_impl_did)?;
+
+    let dtor_impl_trait_ref = tcx.impl_trait_ref(drop_impl_did).unwrap().instantiate_identity();
+
+    match dtor_impl_trait_ref.self_ty().kind() {
         ty::Adt(adt_def, adt_to_impl_args) => {
-            ensure_drop_params_and_item_params_correspond(
+            ensure_impl_params_and_item_params_correspond(
                 tcx,
-                drop_impl_did.expect_local(),
+                drop_impl_did,
                 adt_def.did(),
                 adt_to_impl_args,
             )?;
 
-            ensure_drop_predicates_are_implied_by_item_defn(
+            ensure_impl_predicates_are_implied_by_item_defn(
                 tcx,
-                drop_impl_did.expect_local(),
-                adt_def.did().expect_local(),
+                drop_impl_did,
+                adt_def.did(),
                 adt_to_impl_args,
             )
         }
         _ => {
-            // Destructors only work on nominal types. This was
-            // already checked by coherence, but compilation may
-            // not have been terminated.
-            let span = tcx.def_span(drop_impl_did);
-            let reported = tcx.dcx().span_delayed_bug(
-                span,
-                format!("should have been rejected by coherence check: {dtor_self_type}"),
-            );
-            Err(reported)
+            span_bug!(tcx.def_span(drop_impl_did), "incoherent impl of Drop");
         }
     }
 }
 
-fn ensure_drop_params_and_item_params_correspond<'tcx>(
+pub(crate) fn check_negative_auto_trait_impl<'tcx>(
     tcx: TyCtxt<'tcx>,
-    drop_impl_did: LocalDefId,
-    self_type_did: DefId,
+    impl_def_id: LocalDefId,
+    impl_trait_ref: ty::TraitRef<'tcx>,
+    polarity: ty::ImplPolarity,
+) -> Result<(), ErrorGuaranteed> {
+    let ty::ImplPolarity::Negative = polarity else {
+        return Ok(());
+    };
+
+    if !tcx.trait_is_auto(impl_trait_ref.def_id) {
+        return Ok(());
+    }
+
+    if tcx.defaultness(impl_def_id).is_default() {
+        tcx.dcx().span_delayed_bug(tcx.def_span(impl_def_id), "default impl cannot be negative");
+    }
+
+    tcx.ensure_ok().orphan_check_impl(impl_def_id)?;
+
+    match impl_trait_ref.self_ty().kind() {
+        ty::Adt(adt_def, adt_to_impl_args) => {
+            ensure_impl_params_and_item_params_correspond(
+                tcx,
+                impl_def_id,
+                adt_def.did(),
+                adt_to_impl_args,
+            )?;
+
+            ensure_impl_predicates_are_implied_by_item_defn(
+                tcx,
+                impl_def_id,
+                adt_def.did(),
+                adt_to_impl_args,
+            )
+        }
+        _ => {
+            if tcx.features().auto_traits() {
+                // NOTE: We ignore the applicability check for negative auto impls
+                // defined in libcore. In the (almost impossible) future where we
+                // stabilize auto impls, then the proper applicability check MUST
+                // be implemented here to handle non-ADT rigid types.
+                Ok(())
+            } else {
+                span_bug!(tcx.def_span(impl_def_id), "incoherent impl of negative auto trait");
+            }
+        }
+    }
+}
+
+fn ensure_impl_params_and_item_params_correspond<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    impl_def_id: LocalDefId,
+    adt_def_id: DefId,
     adt_to_impl_args: GenericArgsRef<'tcx>,
 ) -> Result<(), ErrorGuaranteed> {
     let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyParam) else {
         return Ok(());
     };
 
-    let drop_impl_span = tcx.def_span(drop_impl_did);
-    let item_span = tcx.def_span(self_type_did);
-    let self_descr = tcx.def_descr(self_type_did);
+    let impl_span = tcx.def_span(impl_def_id);
+    let item_span = tcx.def_span(adt_def_id);
+    let self_descr = tcx.def_descr(adt_def_id);
+    let polarity = match tcx.impl_polarity(impl_def_id) {
+        ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
+        ty::ImplPolarity::Negative => "!",
+    };
+    let trait_name = tcx
+        .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait"));
     let mut err = struct_span_code_err!(
         tcx.dcx(),
-        drop_impl_span,
+        impl_span,
         E0366,
-        "`Drop` impls cannot be specialized"
+        "`{polarity}{trait_name}` impls cannot be specialized",
     );
     match arg {
         ty::util::NotUniqueParam::DuplicateParam(arg) => {
@@ -116,17 +176,22 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
 /// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be
 /// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are
 /// implied by the ADT being well formed.
-fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
+fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>(
     tcx: TyCtxt<'tcx>,
-    drop_impl_def_id: LocalDefId,
-    adt_def_id: LocalDefId,
+    impl_def_id: LocalDefId,
+    adt_def_id: DefId,
     adt_to_impl_args: GenericArgsRef<'tcx>,
 ) -> Result<(), ErrorGuaranteed> {
     let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
     let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
 
-    let impl_span = tcx.def_span(drop_impl_def_id.to_def_id());
-
+    let impl_span = tcx.def_span(impl_def_id.to_def_id());
+    let trait_name = tcx
+        .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait"));
+    let polarity = match tcx.impl_polarity(impl_def_id) {
+        ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
+        ty::ImplPolarity::Negative => "!",
+    };
     // Take the param-env of the adt and instantiate the args that show up in
     // the implementation's self type. This gives us the assumptions that the
     // self ty of the implementation is allowed to know just from it being a
@@ -145,17 +210,21 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
     let adt_env =
         ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args);
 
-    let fresh_impl_args = infcx.fresh_args_for_item(impl_span, drop_impl_def_id.to_def_id());
+    let fresh_impl_args = infcx.fresh_args_for_item(impl_span, impl_def_id.to_def_id());
     let fresh_adt_ty =
-        tcx.impl_trait_ref(drop_impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty();
+        tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty();
 
     ocx.eq(&ObligationCause::dummy_with_span(impl_span), adt_env, fresh_adt_ty, impl_adt_ty)
-        .unwrap();
+        .expect("equating fully generic trait ref should never fail");
 
-    for (clause, span) in tcx.predicates_of(drop_impl_def_id).instantiate(tcx, fresh_impl_args) {
-        let normalize_cause = traits::ObligationCause::misc(span, adt_def_id);
+    for (clause, span) in tcx.predicates_of(impl_def_id).instantiate(tcx, fresh_impl_args) {
+        let normalize_cause = traits::ObligationCause::misc(span, impl_def_id);
         let pred = ocx.normalize(&normalize_cause, adt_env, clause);
-        let cause = traits::ObligationCause::new(span, adt_def_id, ObligationCauseCode::DropImpl);
+        let cause = traits::ObligationCause::new(
+            span,
+            impl_def_id,
+            ObligationCauseCode::AlwaysApplicableImpl,
+        );
         ocx.register_obligation(traits::Obligation::new(tcx, cause, adt_env, pred));
     }
 
@@ -173,13 +242,13 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
             let root_predicate = error.root_obligation.predicate;
             if root_predicates.insert(root_predicate) {
                 let item_span = tcx.def_span(adt_def_id);
-                let self_descr = tcx.def_descr(adt_def_id.to_def_id());
+                let self_descr = tcx.def_descr(adt_def_id);
                 guar = Some(
                     struct_span_code_err!(
                         tcx.dcx(),
                         error.root_obligation.cause.span,
                         E0367,
-                        "`Drop` impl requires `{root_predicate}` \
+                        "`{polarity}{trait_name}` impl requires `{root_predicate}` \
                         but the {self_descr} it is implemented for does not",
                     )
                     .with_span_note(item_span, "the implementor must specify the same requirement")
@@ -190,12 +259,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
         return Err(guar.unwrap());
     }
 
-    let errors = ocx.infcx.resolve_regions(adt_def_id, adt_env, []);
+    let errors = ocx.infcx.resolve_regions(impl_def_id, adt_env, []);
     if !errors.is_empty() {
         let mut guar = None;
         for error in errors {
             let item_span = tcx.def_span(adt_def_id);
-            let self_descr = tcx.def_descr(adt_def_id.to_def_id());
+            let self_descr = tcx.def_descr(adt_def_id);
             let outlives = match error {
                 RegionResolutionError::ConcreteFailure(_, a, b) => format!("{b}: {a}"),
                 RegionResolutionError::GenericBoundFailure(_, generic, r) => {
@@ -212,7 +281,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
                     tcx.dcx(),
                     error.origin().span(),
                     E0367,
-                    "`Drop` impl requires `{outlives}` \
+                    "`{polarity}{trait_name}` impl requires `{outlives}` \
                     but the {self_descr} it is implemented for does not",
                 )
                 .with_span_note(item_span, "the implementor must specify the same requirement")
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index f89f41aaf8a..8f9997cb62c 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -70,7 +70,6 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     check_transparent(tcx, def);
     check_packed(tcx, span, def);
-    check_unsafe_fields(tcx, def_id);
 }
 
 fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
@@ -144,36 +143,6 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
     true
 }
 
-/// Check that the unsafe fields do not need dropping.
-fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) {
-    let span = tcx.def_span(item_def_id);
-    let def = tcx.adt_def(item_def_id);
-
-    let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
-    let args = ty::GenericArgs::identity_for_item(tcx, item_def_id);
-
-    for field in def.all_fields() {
-        if !field.safety.is_unsafe() {
-            continue;
-        }
-
-        if !allowed_union_or_unsafe_field(tcx, field.ty(tcx, args), typing_env, span) {
-            let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.expect_local()) else {
-                unreachable!("field has to correspond to hir field")
-            };
-            let ty_span = field.ty.span;
-            tcx.dcx().emit_err(errors::InvalidUnsafeField {
-                field_span: field.span,
-                sugg: errors::InvalidUnsafeFieldSuggestion {
-                    lo: ty_span.shrink_to_lo(),
-                    hi: ty_span.shrink_to_hi(),
-                },
-                note: (),
-            });
-        }
-    }
-}
-
 /// Check that a `static` is inhabited.
 fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     // Make sure statics are inhabited.
@@ -1512,7 +1481,6 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     detect_discriminant_duplicate(tcx, def);
     check_transparent(tcx, def);
-    check_unsafe_fields(tcx, def_id);
 }
 
 /// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 89a759f7dda..9c28fac809d 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -62,9 +62,9 @@ a type parameter).
 
 */
 
+pub mod always_applicable;
 mod check;
 mod compare_impl_item;
-pub mod dropck;
 mod entry;
 pub mod intrinsic;
 pub mod intrinsicck;
@@ -113,11 +113,11 @@ pub fn provide(providers: &mut Providers) {
 }
 
 fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Destructor> {
-    tcx.calculate_dtor(def_id.to_def_id(), dropck::check_drop_impl)
+    tcx.calculate_dtor(def_id.to_def_id(), always_applicable::check_drop_impl)
 }
 
 fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::AsyncDestructor> {
-    tcx.calculate_async_dtor(def_id.to_def_id(), dropck::check_drop_impl)
+    tcx.calculate_async_dtor(def_id.to_def_id(), always_applicable::check_drop_impl)
 }
 
 /// Given a `DefId` for an opaque type in return position, find its parent item's return
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index 0245d4c9fe4..b5c6c2f3861 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -16,6 +16,7 @@ use rustc_span::{ErrorGuaranteed, sym};
 use rustc_type_ir::elaborate;
 use tracing::debug;
 
+use crate::check::always_applicable;
 use crate::errors;
 
 mod builtin;
@@ -24,11 +25,12 @@ mod inherent_impls_overlap;
 mod orphan;
 mod unsafety;
 
-fn check_impl(
-    tcx: TyCtxt<'_>,
+fn check_impl<'tcx>(
+    tcx: TyCtxt<'tcx>,
     impl_def_id: LocalDefId,
-    trait_ref: ty::TraitRef<'_>,
-    trait_def: &ty::TraitDef,
+    trait_ref: ty::TraitRef<'tcx>,
+    trait_def: &'tcx ty::TraitDef,
+    polarity: ty::ImplPolarity,
 ) -> Result<(), ErrorGuaranteed> {
     debug!(
         "(checking implementation) adding impl for trait '{:?}', item '{}'",
@@ -44,6 +46,12 @@ fn check_impl(
 
     enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id, trait_def)
         .and(enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id, trait_def))
+        .and(always_applicable::check_negative_auto_trait_impl(
+            tcx,
+            impl_def_id,
+            trait_ref,
+            polarity,
+        ))
 }
 
 fn enforce_trait_manually_implementable(
@@ -154,16 +162,16 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
     let mut res = tcx.ensure_ok().specialization_graph_of(def_id);
 
     for &impl_def_id in impls {
-        let trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
-        let trait_ref = trait_header.trait_ref.instantiate_identity();
+        let impl_header = tcx.impl_trait_header(impl_def_id).unwrap();
+        let trait_ref = impl_header.trait_ref.instantiate_identity();
         let trait_def = tcx.trait_def(trait_ref.def_id);
 
         res = res
-            .and(check_impl(tcx, impl_def_id, trait_ref, trait_def))
+            .and(check_impl(tcx, impl_def_id, trait_ref, trait_def, impl_header.polarity))
             .and(check_object_overlap(tcx, impl_def_id, trait_ref))
-            .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def))
+            .and(unsafety::check_item(tcx, impl_def_id, impl_header, trait_def))
             .and(tcx.ensure_ok().orphan_check_impl(impl_def_id))
-            .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header));
+            .and(builtin::check_trait(tcx, def_id, impl_def_id, impl_header));
     }
 
     res
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 852533ff5c9..4c6c2504126 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -11,8 +11,6 @@ use rustc_middle::ty::Ty;
 use rustc_span::{Ident, Span, Symbol};
 
 use crate::fluent_generated as fluent;
-mod pattern_types;
-pub(crate) use pattern_types::*;
 pub(crate) mod wrong_number_of_generic_args;
 
 mod precise_captures;
@@ -84,6 +82,8 @@ pub(crate) struct AssocItemNotFound<'a> {
     pub label: Option<AssocItemNotFoundLabel<'a>>,
     #[subdiagnostic]
     pub sugg: Option<AssocItemNotFoundSugg<'a>>,
+    #[label(hir_analysis_within_macro)]
+    pub within_macro_span: Option<Span>,
 }
 
 #[derive(Subdiagnostic)]
@@ -711,17 +711,6 @@ pub(crate) struct InvalidUnionField {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_invalid_unsafe_field, code = E0740)]
-pub(crate) struct InvalidUnsafeField {
-    #[primary_span]
-    pub field_span: Span,
-    #[subdiagnostic]
-    pub sugg: InvalidUnsafeFieldSuggestion,
-    #[note]
-    pub note: (),
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_analysis_return_type_notation_on_non_rpitit)]
 pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> {
     #[primary_span]
@@ -742,18 +731,6 @@ pub(crate) struct InvalidUnionFieldSuggestion {
     pub hi: Span,
 }
 
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(
-    hir_analysis_invalid_unsafe_field_sugg,
-    applicability = "machine-applicable"
-)]
-pub(crate) struct InvalidUnsafeFieldSuggestion {
-    #[suggestion_part(code = "std::mem::ManuallyDrop<")]
-    pub lo: Span,
-    #[suggestion_part(code = ">")]
-    pub hi: Span,
-}
-
 #[derive(Diagnostic)]
 #[diag(hir_analysis_return_type_notation_equality_bound)]
 pub(crate) struct ReturnTypeNotationEqualityBound {
diff --git a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
deleted file mode 100644
index ec7b3aaa1c1..00000000000
--- a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use rustc_macros::Diagnostic;
-use rustc_middle::ty::Ty;
-use rustc_span::Span;
-
-#[derive(Diagnostic)]
-#[diag(hir_analysis_invalid_base_type)]
-pub(crate) struct InvalidBaseType<'tcx> {
-    pub ty: Ty<'tcx>,
-    #[primary_span]
-    pub ty_span: Span,
-    pub pat: &'static str,
-    #[note]
-    pub pat_span: Span,
-}
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index d51fd7f7e78..ace5e34b382 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -151,6 +151,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             qself: &qself_str,
             label: None,
             sugg: None,
+            // Try to get the span of the identifier within the path's syntax context
+            // (if that's different).
+            within_macro_span: assoc_name.span.within_macro(span, tcx.sess.source_map()),
         };
 
         if is_dummy {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index d044688246f..dd6c40bfbb8 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -55,9 +55,7 @@ use tracing::{debug, instrument};
 
 use self::errors::assoc_kind_str;
 use crate::check::check_abi_fn_ptr;
-use crate::errors::{
-    AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, NoVariantNamed,
-};
+use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, NoVariantNamed};
 use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
 use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
 use crate::middle::resolve_bound_vars as rbv;
@@ -2692,28 +2690,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let ty_span = ty.span;
                 let ty = self.lower_ty(ty);
                 let pat_ty = match pat.kind {
-                    hir::TyPatKind::Range(start, end, include_end) => {
-                        let ty = match ty.kind() {
-                            ty::Int(_) | ty::Uint(_) | ty::Char => ty,
-                            _ => Ty::new_error(
-                                tcx,
-                                self.dcx().emit_err(InvalidBaseType {
-                                    ty,
-                                    pat: "range",
+                    hir::TyPatKind::Range(start, end) => {
+                        let (ty, start, end) = match ty.kind() {
+                            // Keep this list of types in sync with the list of types that
+                            // the `RangePattern` trait is implemented for.
+                            ty::Int(_) | ty::Uint(_) | ty::Char => {
+                                let start = self.lower_const_arg(start, FeedConstTy::No);
+                                let end = self.lower_const_arg(end, FeedConstTy::No);
+                                (ty, start, end)
+                            }
+                            _ => {
+                                let guar = self.dcx().span_delayed_bug(
                                     ty_span,
-                                    pat_span: pat.span,
-                                }),
-                            ),
-                        };
-                        let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
-                        let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
-
-                        let include_end = match include_end {
-                            hir::RangeEnd::Included => true,
-                            hir::RangeEnd::Excluded => false,
+                                    "invalid base type for range pattern",
+                                );
+                                let errc = ty::Const::new_error(tcx, guar);
+                                (Ty::new_error(tcx, guar), errc, errc)
+                            }
                         };
 
-                        let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
+                        let pat = tcx.mk_pat(ty::PatternKind::Range { start, end });
                         Ty::new_pat(tcx, ty, pat)
                     }
                     hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index e954d2b9ea4..8475903c68f 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -252,13 +252,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
             ty::Pat(typ, pat) => {
                 match *pat {
-                    ty::PatternKind::Range { start, end, include_end: _ } => {
-                        if let Some(start) = start {
-                            self.add_constraints_from_const(current, start, variance);
-                        }
-                        if let Some(end) = end {
-                            self.add_constraints_from_const(current, end, variance);
-                        }
+                    ty::PatternKind::Range { start, end } => {
+                        self.add_constraints_from_const(current, start, variance);
+                        self.add_constraints_from_const(current, end, variance);
                     }
                 }
                 self.add_constraints_from_ty(current, typ, variance);
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 1658c8dac67..147b42c0490 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1943,17 +1943,10 @@ impl<'a> State<'a> {
         // Pat isn't normalized, but the beauty of it
         // is that it doesn't matter
         match pat.kind {
-            TyPatKind::Range(begin, end, end_kind) => {
-                if let Some(expr) = begin {
-                    self.print_const_arg(expr);
-                }
-                match end_kind {
-                    RangeEnd::Included => self.word("..."),
-                    RangeEnd::Excluded => self.word(".."),
-                }
-                if let Some(expr) = end {
-                    self.print_const_arg(expr);
-                }
+            TyPatKind::Range(begin, end) => {
+                self.print_const_arg(begin);
+                self.word("..=");
+                self.print_const_arg(end);
             }
             TyPatKind::Err(_) => {
                 self.popen();
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index cbe677171a0..2a89a03e0aa 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3069,7 +3069,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}",
             ident, base, expr, base_ty
         );
-        let mut err = self.no_such_field_err(ident, base_ty, base.hir_id);
+        let mut err = self.no_such_field_err(ident, base_ty, expr);
 
         match *base_ty.peel_refs().kind() {
             ty::Array(_, len) => {
@@ -3282,18 +3282,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         );
     }
 
-    fn no_such_field_err(&self, field: Ident, expr_t: Ty<'tcx>, id: HirId) -> Diag<'_> {
+    fn no_such_field_err(
+        &self,
+        field: Ident,
+        base_ty: Ty<'tcx>,
+        expr: &hir::Expr<'tcx>,
+    ) -> Diag<'_> {
         let span = field.span;
-        debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t);
+        debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, base_ty);
 
-        let mut err = self.dcx().create_err(NoFieldOnType { span, ty: expr_t, field });
-        if expr_t.references_error() {
+        let mut err = self.dcx().create_err(NoFieldOnType { span, ty: base_ty, field });
+        if base_ty.references_error() {
             err.downgrade_to_delayed_bug();
         }
 
+        if let Some(within_macro_span) = span.within_macro(expr.span, self.tcx.sess.source_map()) {
+            err.span_label(within_macro_span, "due to this macro variable");
+        }
+
         // try to add a suggestion in case the field is a nested field of a field of the Adt
-        let mod_id = self.tcx.parent_module(id).to_def_id();
-        let (ty, unwrap) = if let ty::Adt(def, args) = expr_t.kind()
+        let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id();
+        let (ty, unwrap) = if let ty::Adt(def, args) = base_ty.kind()
             && (self.tcx.is_diagnostic_item(sym::Result, def.did())
                 || self.tcx.is_diagnostic_item(sym::Option, def.did()))
             && let Some(arg) = args.get(0)
@@ -3301,10 +3310,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             (ty, "unwrap().")
         } else {
-            (expr_t, "")
+            (base_ty, "")
         };
         for (found_fields, args) in
-            self.get_field_candidates_considering_privacy_for_diag(span, ty, mod_id, id)
+            self.get_field_candidates_considering_privacy_for_diag(span, ty, mod_id, expr.hir_id)
         {
             let field_names = found_fields.iter().map(|field| field.name).collect::<Vec<_>>();
             let mut candidate_fields: Vec<_> = found_fields
@@ -3317,7 +3326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         args,
                         vec![],
                         mod_id,
-                        id,
+                        expr.hir_id,
                     )
                 })
                 .map(|mut field_path| {
@@ -3328,7 +3337,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             candidate_fields.sort();
 
             let len = candidate_fields.len();
-            if len > 0 {
+            // Don't suggest `.field` if the base expr is from a different
+            // syntax context than the field.
+            if len > 0 && expr.span.eq_ctxt(field.span) {
                 err.span_suggestions(
                     field.span.shrink_to_lo(),
                     format!(
@@ -3963,7 +3974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 _ => (),
             };
 
-            self.no_such_field_err(field, container, expr.hir_id).emit();
+            self.no_such_field_err(field, container, expr).emit();
 
             break;
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 054e3bcb67c..c46a42c5de1 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -669,12 +669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if !errors.is_empty() {
             self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
-            let errors_causecode = errors
-                .iter()
-                .map(|e| (e.obligation.cause.span, e.root_obligation.cause.code().clone()))
-                .collect::<Vec<_>>();
             self.err_ctxt().report_fulfillment_errors(errors);
-            self.collect_unused_stmts_for_coerce_return_ty(errors_causecode);
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 82e99ca7afa..db947b6744d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -3,9 +3,7 @@ use std::{fmt, iter, mem};
 use itertools::Itertools;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::codes::*;
-use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, a_or_an, listify, pluralize,
-};
+use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, a_or_an, listify, pluralize};
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
@@ -2193,62 +2191,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub(super) fn collect_unused_stmts_for_coerce_return_ty(
-        &self,
-        errors_causecode: Vec<(Span, ObligationCauseCode<'tcx>)>,
-    ) {
-        for (span, code) in errors_causecode {
-            self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| {
-                if let Some(fn_sig) = self.body_fn_sig()
-                    && let ObligationCauseCode::WhereClauseInExpr(_, _, binding_hir_id, ..) = code
-                    && !fn_sig.output().is_unit()
-                {
-                    let mut block_num = 0;
-                    let mut found_semi = false;
-                    for (hir_id, node) in self.tcx.hir_parent_iter(binding_hir_id) {
-                        // Don't proceed into parent bodies
-                        if hir_id.owner != binding_hir_id.owner {
-                            break;
-                        }
-                        match node {
-                            hir::Node::Stmt(stmt) => {
-                                if let hir::StmtKind::Semi(expr) = stmt.kind {
-                                    let expr_ty = self.typeck_results.borrow().expr_ty(expr);
-                                    let return_ty = fn_sig.output();
-                                    if !matches!(expr.kind, hir::ExprKind::Ret(..))
-                                        && self.may_coerce(expr_ty, return_ty)
-                                    {
-                                        found_semi = true;
-                                    }
-                                }
-                            }
-                            hir::Node::Block(_block) => {
-                                if found_semi {
-                                    block_num += 1;
-                                }
-                            }
-                            hir::Node::Item(item) => {
-                                if let hir::ItemKind::Fn { .. } = item.kind {
-                                    break;
-                                }
-                            }
-                            _ => {}
-                        }
-                    }
-                    if block_num > 1 && found_semi {
-                        err.span_suggestion_verbose(
-                            // use the span of the *whole* expr
-                            self.tcx.hir().span(binding_hir_id).shrink_to_lo(),
-                            "you might have meant to return this to infer its type parameters",
-                            "return ",
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                }
-            });
-        }
-    }
-
     /// Given a vector of fulfillment errors, try to adjust the spans of the
     /// errors to more accurately point at the cause of the failure.
     ///
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 18218a7a0a6..cb1e89fb9e5 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -158,7 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.typeck_results.borrow_mut().used_trait_imports.insert(import_id);
         }
 
-        let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
+        let (span, expr_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
             hir::Node::Expr(&hir::Expr {
                 kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
                 span,
@@ -194,6 +194,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             node => unreachable!("{node:?}"),
         };
 
+        // Try to get the span of the identifier within the expression's syntax context
+        // (if that's different).
+        let within_macro_span = span.within_macro(expr_span, self.tcx.sess.source_map());
+
         // Avoid suggestions when we don't know what's going on.
         if let Err(guar) = rcvr_ty.error_reported() {
             return guar;
@@ -207,10 +211,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 call_id,
                 source,
                 args,
-                sugg_span,
+                expr_span,
                 &mut no_match_data,
                 expected,
                 trait_missing_method,
+                within_macro_span,
             ),
 
             MethodError::Ambiguity(mut sources) => {
@@ -221,6 +226,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     "multiple applicable items in scope"
                 );
                 err.span_label(item_name.span, format!("multiple `{item_name}` found"));
+                if let Some(within_macro_span) = within_macro_span {
+                    err.span_label(within_macro_span, "due to this macro variable");
+                }
 
                 self.note_candidates_on_method_error(
                     rcvr_ty,
@@ -230,7 +238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     span,
                     &mut err,
                     &mut sources,
-                    Some(sugg_span),
+                    Some(expr_span),
                 );
                 err.emit()
             }
@@ -252,6 +260,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .span_if_local(def_id)
                     .unwrap_or_else(|| self.tcx.def_span(def_id));
                 err.span_label(sp, format!("private {kind} defined here"));
+                if let Some(within_macro_span) = within_macro_span {
+                    err.span_label(within_macro_span, "due to this macro variable");
+                }
                 self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true);
                 err.emit()
             }
@@ -268,6 +279,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if !needs_mut {
                     err.span_label(bound_span, "this has a `Sized` requirement");
                 }
+                if let Some(within_macro_span) = within_macro_span {
+                    err.span_label(within_macro_span, "due to this macro variable");
+                }
                 if !candidates.is_empty() {
                     let help = format!(
                         "{an}other candidate{s} {were} found in the following trait{s}",
@@ -581,6 +595,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         no_match_data: &mut NoMatchData<'tcx>,
         expected: Expectation<'tcx>,
         trait_missing_method: bool,
+        within_macro_span: Option<Span>,
     ) -> ErrorGuaranteed {
         let mode = no_match_data.mode;
         let tcx = self.tcx;
@@ -721,6 +736,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if tcx.sess.source_map().is_multiline(sugg_span) {
             err.span_label(sugg_span.with_hi(span.lo()), "");
         }
+        if let Some(within_macro_span) = within_macro_span {
+            err.span_label(within_macro_span, "due to this macro variable");
+        }
 
         if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 {
             ty_str = short_ty_str;
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index d2b08eab479..fcadbfc3c4a 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -882,27 +882,13 @@ fn ty_is_known_nonnull<'tcx>(
                 || Option::unwrap_or_default(
                     try {
                         match **pat {
-                            ty::PatternKind::Range { start, end, include_end } => {
-                                match (start, end) {
-                                    (Some(start), None) => {
-                                        start.try_to_value()?.try_to_bits(tcx, typing_env)? > 0
-                                    }
-                                    (Some(start), Some(end)) => {
-                                        let start =
-                                            start.try_to_value()?.try_to_bits(tcx, typing_env)?;
-                                        let end =
-                                            end.try_to_value()?.try_to_bits(tcx, typing_env)?;
-
-                                        if include_end {
-                                            // This also works for negative numbers, as we just need
-                                            // to ensure we aren't wrapping over zero.
-                                            start > 0 && end >= start
-                                        } else {
-                                            start > 0 && end > start
-                                        }
-                                    }
-                                    _ => false,
-                                }
+                            ty::PatternKind::Range { start, end } => {
+                                let start = start.try_to_value()?.try_to_bits(tcx, typing_env)?;
+                                let end = end.try_to_value()?.try_to_bits(tcx, typing_env)?;
+
+                                // This also works for negative numbers, as we just need
+                                // to ensure we aren't wrapping over zero.
+                                start > 0 && end >= start
                             }
                         }
                     },
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 697a0e6592d..ba65a711815 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -470,7 +470,7 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
             // Find the provenance.
             let (offset, _prov) = self
                 .provenance
-                .range_get_ptrs(range, cx)
+                .range_ptrs_get(range, cx)
                 .first()
                 .copied()
                 .expect("there must be provenance somewhere here");
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
index 82fb5f33b4c..c9525df1f79 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
@@ -67,7 +67,7 @@ impl ProvenanceMap {
 }
 
 impl<Prov: Provenance> ProvenanceMap<Prov> {
-    fn adjusted_range(range: AllocRange, cx: &impl HasDataLayout) -> Range<Size> {
+    fn adjusted_range_ptrs(range: AllocRange, cx: &impl HasDataLayout) -> Range<Size> {
         // We have to go back `pointer_size - 1` bytes, as that one would still overlap with
         // the beginning of this range.
         let adjusted_start = Size::from_bytes(
@@ -79,26 +79,21 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
     /// Returns all ptr-sized provenance in the given range.
     /// If the range has length 0, returns provenance that crosses the edge between `start-1` and
     /// `start`.
-    pub(super) fn range_get_ptrs(
+    pub(super) fn range_ptrs_get(
         &self,
         range: AllocRange,
         cx: &impl HasDataLayout,
     ) -> &[(Size, Prov)] {
-        self.ptrs.range(Self::adjusted_range(range, cx))
+        self.ptrs.range(Self::adjusted_range_ptrs(range, cx))
     }
 
-    /// `pm.range_get_ptrs_is_empty(r, cx)` == `pm.range_get_ptrs(r, cx).is_empty()`, but is
-    /// faster.
-    pub(super) fn range_get_ptrs_is_empty(
-        &self,
-        range: AllocRange,
-        cx: &impl HasDataLayout,
-    ) -> bool {
-        self.ptrs.range_is_empty(Self::adjusted_range(range, cx))
+    /// `pm.range_ptrs_is_empty(r, cx)` == `pm.range_ptrs_get(r, cx).is_empty()`, but is faster.
+    pub(super) fn range_ptrs_is_empty(&self, range: AllocRange, cx: &impl HasDataLayout) -> bool {
+        self.ptrs.range_is_empty(Self::adjusted_range_ptrs(range, cx))
     }
 
     /// Returns all byte-wise provenance in the given range.
-    fn range_get_bytes(&self, range: AllocRange) -> &[(Size, Prov)] {
+    fn range_bytes_get(&self, range: AllocRange) -> &[(Size, Prov)] {
         if let Some(bytes) = self.bytes.as_ref() {
             bytes.range(range.start..range.end())
         } else {
@@ -106,9 +101,14 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
         }
     }
 
+    /// Same as `range_bytes_get(range).is_empty()`, but faster.
+    fn range_bytes_is_empty(&self, range: AllocRange) -> bool {
+        self.bytes.as_ref().is_none_or(|bytes| bytes.range_is_empty(range.start..range.end()))
+    }
+
     /// Get the provenance of a single byte.
     pub fn get(&self, offset: Size, cx: &impl HasDataLayout) -> Option<Prov> {
-        let prov = self.range_get_ptrs(alloc_range(offset, Size::from_bytes(1)), cx);
+        let prov = self.range_ptrs_get(alloc_range(offset, Size::from_bytes(1)), cx);
         debug_assert!(prov.len() <= 1);
         if let Some(entry) = prov.first() {
             // If it overlaps with this byte, it is on this byte.
@@ -132,7 +132,7 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
     /// limit access to provenance outside of the `Allocation` abstraction.
     ///
     pub fn range_empty(&self, range: AllocRange, cx: &impl HasDataLayout) -> bool {
-        self.range_get_ptrs_is_empty(range, cx) && self.range_get_bytes(range).is_empty()
+        self.range_ptrs_is_empty(range, cx) && self.range_bytes_is_empty(range)
     }
 
     /// Yields all the provenances stored in this map.
@@ -164,14 +164,14 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
         // provenance that overlaps with the given range.
         let (first, last) = {
             // Find all provenance overlapping the given range.
-            if self.range_get_ptrs_is_empty(range, cx) {
+            if self.range_ptrs_is_empty(range, cx) {
                 // No provenance in this range, we are done. This is the common case.
                 return Ok(());
             }
 
             // This redoes some of the work of `range_get_ptrs_is_empty`, but this path is much
             // colder than the early return above, so it's worth it.
-            let provenance = self.range_get_ptrs(range, cx);
+            let provenance = self.range_ptrs_get(range, cx);
             (
                 provenance.first().unwrap().0,
                 provenance.last().unwrap().0 + cx.data_layout().pointer_size,
@@ -284,8 +284,8 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
         // This includes the existing bytewise provenance in the range, and ptr provenance
         // that overlaps with the begin/end of the range.
         let mut dest_bytes_box = None;
-        let begin_overlap = self.range_get_ptrs(alloc_range(src.start, Size::ZERO), cx).first();
-        let end_overlap = self.range_get_ptrs(alloc_range(src.end(), Size::ZERO), cx).first();
+        let begin_overlap = self.range_ptrs_get(alloc_range(src.start, Size::ZERO), cx).first();
+        let end_overlap = self.range_ptrs_get(alloc_range(src.end(), Size::ZERO), cx).first();
         if !Prov::OFFSET_IS_ADDR {
             // There can't be any bytewise provenance, and we cannot split up the begin/end overlap.
             if let Some(entry) = begin_overlap {
@@ -308,10 +308,10 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
             } else {
                 trace!("no start overlapping entry");
             }
+
             // Then the main part, bytewise provenance from `self.bytes`.
-            if let Some(all_bytes) = self.bytes.as_ref() {
-                bytes.extend(all_bytes.range(src.start..src.end()));
-            }
+            bytes.extend(self.range_bytes_get(src));
+
             // And finally possibly parts of a pointer at the end.
             if let Some(entry) = end_overlap {
                 trace!("end overlapping entry: {entry:?}");
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index e5592de81cd..72f31cec008 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -19,7 +19,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
 use rustc_index::{IndexVec, newtype_index};
-use rustc_macros::{HashStable, TypeVisitable};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{ErrorGuaranteed, Span, Symbol};
 use rustc_target::asm::InlineAsmRegOrRegClass;
@@ -49,10 +49,13 @@ macro_rules! thir_with_elements {
             }
         )*
 
+        // Note: Making `Thir` implement `Clone` is useful for external tools that need access to
+        // THIR bodies even after the `Steal` query result has been stolen.
+        // One such tool is https://github.com/rust-corpus/qrates/.
         /// A container for a THIR body.
         ///
         /// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
-        #[derive(Debug, HashStable)]
+        #[derive(Debug, HashStable, Clone)]
         pub struct Thir<'tcx> {
             pub body_type: BodyTy<'tcx>,
             $(
@@ -90,7 +93,7 @@ thir_with_elements! {
     params: ParamId => Param<'tcx> => "p{}",
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Debug, HashStable, Clone)]
 pub enum BodyTy<'tcx> {
     Const(Ty<'tcx>),
     Fn(FnSig<'tcx>),
@@ -98,7 +101,7 @@ pub enum BodyTy<'tcx> {
 }
 
 /// Description of a type-checked function parameter.
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Param<'tcx> {
     /// The pattern that appears in the parameter list, or None for implicit parameters.
     pub pat: Option<Box<Pat<'tcx>>>,
@@ -118,7 +121,7 @@ pub enum LintLevel {
     Explicit(HirId),
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Block {
     /// Whether the block itself has a label. Used by `label: {}`
     /// and `try` blocks.
@@ -138,7 +141,7 @@ pub struct Block {
 
 type UserTy<'tcx> = Option<Box<CanonicalUserType<'tcx>>>;
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct AdtExpr<'tcx> {
     /// The ADT we're constructing.
     pub adt_def: AdtDef<'tcx>,
@@ -155,7 +158,7 @@ pub struct AdtExpr<'tcx> {
     pub base: AdtExprBase<'tcx>,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub enum AdtExprBase<'tcx> {
     /// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`.
     None,
@@ -168,7 +171,7 @@ pub enum AdtExprBase<'tcx> {
     DefaultFields(Box<[Ty<'tcx>]>),
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct ClosureExpr<'tcx> {
     pub closure_id: LocalDefId,
     pub args: UpvarArgs<'tcx>,
@@ -177,7 +180,7 @@ pub struct ClosureExpr<'tcx> {
     pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct InlineAsmExpr<'tcx> {
     pub asm_macro: AsmMacro,
     pub template: &'tcx [InlineAsmTemplatePiece],
@@ -195,12 +198,12 @@ pub enum BlockSafety {
     ExplicitUnsafe(HirId),
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Stmt<'tcx> {
     pub kind: StmtKind<'tcx>,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub enum StmtKind<'tcx> {
     /// An expression with a trailing semicolon.
     Expr {
@@ -240,11 +243,11 @@ pub enum StmtKind<'tcx> {
     },
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, HashStable)]
+#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
 pub struct LocalVarId(pub HirId);
 
 /// A THIR expression.
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Expr<'tcx> {
     /// kind of expression
     pub kind: ExprKind<'tcx>,
@@ -271,7 +274,7 @@ pub struct TempLifetime {
     pub backwards_incompatible: Option<region::Scope>,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub enum ExprKind<'tcx> {
     /// `Scope`s are used to explicitly mark destruction scopes,
     /// and to track the `HirId` of the expressions within the scope.
@@ -548,20 +551,20 @@ pub enum ExprKind<'tcx> {
 /// Represents the association of a field identifier and an expression.
 ///
 /// This is used in struct constructors.
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct FieldExpr {
     pub name: FieldIdx,
     pub expr: ExprId,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct FruInfo<'tcx> {
     pub base: ExprId,
     pub field_types: Box<[Ty<'tcx>]>,
 }
 
 /// A `match` arm.
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Arm<'tcx> {
     pub pattern: Box<Pat<'tcx>>,
     pub guard: Option<ExprId>,
@@ -579,7 +582,7 @@ pub enum LogicalOp {
     Or,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub enum InlineAsmOperand<'tcx> {
     In {
         reg: InlineAsmRegOrRegClass,
@@ -616,13 +619,13 @@ pub enum InlineAsmOperand<'tcx> {
     },
 }
 
-#[derive(Debug, HashStable, TypeVisitable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub struct FieldPat<'tcx> {
     pub field: FieldIdx,
     pub pattern: Pat<'tcx>,
 }
 
-#[derive(Debug, HashStable, TypeVisitable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub struct Pat<'tcx> {
     pub ty: Ty<'tcx>,
     pub span: Span,
@@ -729,7 +732,7 @@ impl<'tcx> Pat<'tcx> {
     }
 }
 
-#[derive(Debug, HashStable, TypeVisitable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub struct Ascription<'tcx> {
     pub annotation: CanonicalUserTypeAnnotation<'tcx>,
     /// Variance to use when relating the `user_ty` to the **type of the value being
@@ -753,7 +756,7 @@ pub struct Ascription<'tcx> {
     pub variance: ty::Variance,
 }
 
-#[derive(Debug, HashStable, TypeVisitable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub enum PatKind<'tcx> {
     /// A wildcard pattern: `_`.
     Wild,
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index b8698aa8233..53f233f20eb 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -397,9 +397,9 @@ pub enum ObligationCauseCode<'tcx> {
 
     RustCall,
 
-    /// Obligations to prove that a `std::ops::Drop` impl is not stronger than
+    /// Obligations to prove that a `Drop` or negative auto trait impl is not stronger than
     /// the ADT it's being implemented for.
-    DropImpl,
+    AlwaysApplicableImpl,
 
     /// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy`
     ConstParam(Ty<'tcx>),
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index ec0498b168c..0b8f0e8cd41 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -220,13 +220,9 @@ impl FlagComputation {
             &ty::Pat(ty, pat) => {
                 self.add_ty(ty);
                 match *pat {
-                    ty::PatternKind::Range { start, end, include_end: _ } => {
-                        if let Some(start) = start {
-                            self.add_const(start)
-                        }
-                        if let Some(end) = end {
-                            self.add_const(end)
-                        }
+                    ty::PatternKind::Range { start, end } => {
+                        self.add_const(start);
+                        self.add_const(end);
                     }
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
index 505c7278176..953ad62be0a 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
@@ -236,6 +236,11 @@ impl<'tcx> InhabitedPredicate<'tcx> {
         self.instantiate_opt(tcx, args).unwrap_or(self)
     }
 
+    /// Same as [`Self::instantiate`], but if there is no generics to
+    /// instantiate, returns `None`. This is useful because it lets us avoid
+    /// allocating a recursive copy of everything when the result is unchanged.
+    ///
+    /// Only used to implement `instantiate` itself.
     fn instantiate_opt(self, tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> Option<Self> {
         match self {
             Self::ConstIsZero(c) => {
@@ -260,7 +265,10 @@ impl<'tcx> InhabitedPredicate<'tcx> {
                 Some(InhabitedPredicate::True) => Some(InhabitedPredicate::True),
                 Some(a) => Some(a.or(tcx, b.instantiate_opt(tcx, args).unwrap_or(b))),
             },
-            _ => None,
+            Self::True | Self::False | Self::NotInModule(_) => None,
+            Self::OpaqueType(_) => {
+                bug!("unexpected OpaqueType in InhabitedPredicate");
+            }
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs
index e604aedd05e..4cad1ab2099 100644
--- a/compiler/rustc_middle/src/ty/pattern.rs
+++ b/compiler/rustc_middle/src/ty/pattern.rs
@@ -26,18 +26,30 @@ impl<'tcx> fmt::Debug for Pattern<'tcx> {
 impl<'tcx> fmt::Debug for PatternKind<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
-            PatternKind::Range { start, end, include_end } => {
-                if let Some(start) = start {
-                    write!(f, "{start}")?;
+            PatternKind::Range { start, end } => {
+                write!(f, "{start}")?;
+
+                if let Some(c) = end.try_to_value() {
+                    let end = c.valtree.unwrap_leaf();
+                    let size = end.size();
+                    let max = match c.ty.kind() {
+                        ty::Int(_) => {
+                            Some(ty::ScalarInt::truncate_from_int(size.signed_int_max(), size))
+                        }
+                        ty::Uint(_) => {
+                            Some(ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size))
+                        }
+                        ty::Char => Some(ty::ScalarInt::truncate_from_uint(char::MAX, size)),
+                        _ => None,
+                    };
+                    if let Some((max, _)) = max
+                        && end == max
+                    {
+                        return write!(f, "..");
+                    }
                 }
-                write!(f, "..")?;
-                if include_end {
-                    write!(f, "=")?;
-                }
-                if let Some(end) = end {
-                    write!(f, "{end}")?;
-                }
-                Ok(())
+
+                write!(f, "..={end}")
             }
         }
     }
@@ -46,5 +58,5 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> {
 #[derive(Clone, PartialEq, Eq, Hash)]
 #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
 pub enum PatternKind<'tcx> {
-    Range { start: Option<ty::Const<'tcx>>, end: Option<ty::Const<'tcx>>, include_end: bool },
+    Range { start: ty::Const<'tcx>, end: ty::Const<'tcx> },
 }
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 839c1c346a4..b1dfcb80bde 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -51,22 +51,12 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for ty::Pattern<'tcx> {
     ) -> RelateResult<'tcx, Self> {
         match (&*a, &*b) {
             (
-                &ty::PatternKind::Range { start: start_a, end: end_a, include_end: inc_a },
-                &ty::PatternKind::Range { start: start_b, end: end_b, include_end: inc_b },
+                &ty::PatternKind::Range { start: start_a, end: end_a },
+                &ty::PatternKind::Range { start: start_b, end: end_b },
             ) => {
-                // FIXME(pattern_types): make equal patterns equal (`0..=` is the same as `..=`).
-                let mut relate_opt_const = |a, b| match (a, b) {
-                    (None, None) => Ok(None),
-                    (Some(a), Some(b)) => relation.relate(a, b).map(Some),
-                    // FIXME(pattern_types): report a better error
-                    _ => Err(TypeError::Mismatch),
-                };
-                let start = relate_opt_const(start_a, start_b)?;
-                let end = relate_opt_const(end_a, end_b)?;
-                if inc_a != inc_b {
-                    todo!()
-                }
-                Ok(relation.cx().mk_pat(ty::PatternKind::Range { start, end, include_end: inc_a }))
+                let start = relation.relate(start_a, start_b)?;
+                let end = relation.relate(end_a, end_b)?;
+                Ok(relation.cx().mk_pat(ty::PatternKind::Range { start, end }))
             }
         }
     }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index db9e9fbc643..6c62c04f42e 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -284,6 +284,7 @@ TrivialTypeTraversalImpls! {
     rustc_hir::def_id::LocalDefId,
     rustc_hir::HirId,
     rustc_hir::MatchSource,
+    rustc_hir::RangeEnd,
     rustc_span::Ident,
     rustc_span::Span,
     rustc_span::Symbol,
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 3e8a3d1a289..a23316ae6fc 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -137,9 +137,9 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
 
             ty::Pat(ty, pat) => {
                 match *pat {
-                    ty::PatternKind::Range { start, end, include_end: _ } => {
-                        stack.extend(end.map(Into::into));
-                        stack.extend(start.map(Into::into));
+                    ty::PatternKind::Range { start, end } => {
+                        stack.push(end.into());
+                        stack.push(start.into());
                     }
                 }
                 stack.push(ty.into());
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 3f642a7ac1f..c3b1956ad2e 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2954,14 +2954,27 @@ impl<'a> Parser<'a> {
             }
             _ => unreachable!(),
         };
+        // is lifetime `n` tokens ahead?
+        let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
         // Is `self` `n` tokens ahead?
         let is_isolated_self = |this: &Self, n| {
             this.is_keyword_ahead(n, &[kw::SelfLower])
                 && this.look_ahead(n + 1, |t| t != &token::PathSep)
         };
+        // Is `pin const self` `n` tokens ahead?
+        let is_isolated_pin_const_self = |this: &Self, n| {
+            this.look_ahead(n, |token| token.is_ident_named(sym::pin))
+                && this.is_keyword_ahead(n + 1, &[kw::Const])
+                && is_isolated_self(this, n + 2)
+        };
         // Is `mut self` `n` tokens ahead?
         let is_isolated_mut_self =
             |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
+        // Is `pin mut self` `n` tokens ahead?
+        let is_isolated_pin_mut_self = |this: &Self, n| {
+            this.look_ahead(n, |token| token.is_ident_named(sym::pin))
+                && is_isolated_mut_self(this, n + 1)
+        };
         // Parse `self` or `self: TYPE`. We already know the current token is `self`.
         let parse_self_possibly_typed = |this: &mut Self, m| {
             let eself_ident = expect_self_ident(this);
@@ -3012,26 +3025,35 @@ impl<'a> Parser<'a> {
         let eself_lo = self.token.span;
         let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
             token::And => {
-                let eself = if is_isolated_self(self, 1) {
-                    // `&self`
-                    self.bump();
-                    SelfKind::Region(None, Mutability::Not)
-                } else if is_isolated_mut_self(self, 1) {
-                    // `&mut self`
-                    self.bump();
-                    self.bump();
-                    SelfKind::Region(None, Mutability::Mut)
-                } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
-                    // `&'lt self`
-                    self.bump();
-                    let lt = self.expect_lifetime();
-                    SelfKind::Region(Some(lt), Mutability::Not)
-                } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
-                    // `&'lt mut self`
-                    self.bump();
-                    let lt = self.expect_lifetime();
-                    self.bump();
-                    SelfKind::Region(Some(lt), Mutability::Mut)
+                let has_lifetime = is_lifetime(self, 1);
+                let skip_lifetime_count = has_lifetime as usize;
+                let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
+                    // `&{'lt} self`
+                    self.bump(); // &
+                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
+                    SelfKind::Region(lifetime, Mutability::Not)
+                } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
+                    // `&{'lt} mut self`
+                    self.bump(); // &
+                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
+                    self.bump(); // mut
+                    SelfKind::Region(lifetime, Mutability::Mut)
+                } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
+                    // `&{'lt} pin const self`
+                    self.bump(); // &
+                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
+                    self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
+                    self.bump(); // pin
+                    self.bump(); // const
+                    SelfKind::Pinned(lifetime, Mutability::Not)
+                } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
+                    // `&{'lt} pin mut self`
+                    self.bump(); // &
+                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
+                    self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
+                    self.bump(); // pin
+                    self.bump(); // mut
+                    SelfKind::Pinned(lifetime, Mutability::Mut)
                 } else {
                     // `&not_self`
                     return Ok(None);
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 29b606b7a59..92f5fba1f9b 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -624,7 +624,7 @@ pub(crate) struct UnnecessaryQualification<'ra> {
     pub removal_span: Span,
 }
 
-#[derive(Default)]
+#[derive(Default, Debug)]
 struct DiagMetadata<'ast> {
     /// The current trait's associated items' ident, used for diagnostic suggestions.
     current_trait_assoc_items: Option<&'ast [P<AssocItem>]>,
@@ -3147,6 +3147,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 PathSource::Trait(AliasPossibility::No),
                 Finalize::new(trait_ref.ref_id, trait_ref.path.span),
                 RecordPartialRes::Yes,
+                None,
             );
             self.diag_metadata.currently_processing_impl_trait = None;
             if let Some(def_id) = res.expect_full_res().opt_def_id() {
@@ -4073,6 +4074,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             source,
             Finalize::new(id, path.span),
             RecordPartialRes::Yes,
+            None,
         );
     }
 
@@ -4084,14 +4086,21 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         source: PathSource<'ast>,
         finalize: Finalize,
         record_partial_res: RecordPartialRes,
+        parent_qself: Option<&QSelf>,
     ) -> PartialRes {
         let ns = source.namespace();
 
         let Finalize { node_id, path_span, .. } = finalize;
         let report_errors = |this: &mut Self, res: Option<Res>| {
             if this.should_report_errs() {
-                let (err, candidates) =
-                    this.smart_resolve_report_errors(path, None, path_span, source, res);
+                let (err, candidates) = this.smart_resolve_report_errors(
+                    path,
+                    None,
+                    path_span,
+                    source,
+                    res,
+                    parent_qself,
+                );
 
                 let def_id = this.parent_scope.module.nearest_parent_mod();
                 let instead = res.is_some();
@@ -4160,6 +4169,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                     path_span,
                     PathSource::Type,
                     None,
+                    parent_qself,
                 );
 
                 // There are two different error messages user might receive at
@@ -4437,6 +4447,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 PathSource::Trait(AliasPossibility::No),
                 Finalize::new(finalize.node_id, qself.path_span),
                 RecordPartialRes::No,
+                Some(&qself),
             );
 
             if trait_res.expect_full_res() == Res::Err {
@@ -4461,6 +4472,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 PathSource::TraitItem(ns),
                 Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span),
                 RecordPartialRes::No,
+                Some(&qself),
             );
 
             // The remaining segments (the `C` in our example) will
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 42be92c0f8f..67024f988a4 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -35,7 +35,7 @@ use super::NoConstantGenericsReason;
 use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
 use crate::late::{
     AliasPossibility, LateResolutionVisitor, LifetimeBinderKind, LifetimeRes, LifetimeRibKind,
-    LifetimeUseSet, RibKind,
+    LifetimeUseSet, QSelf, RibKind,
 };
 use crate::ty::fast_reject::SimplifiedType;
 use crate::{
@@ -421,6 +421,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         span: Span,
         source: PathSource<'_>,
         res: Option<Res>,
+        qself: Option<&QSelf>,
     ) -> (Diag<'tcx>, Vec<ImportSuggestion>) {
         debug!(?res, ?source);
         let base_error = self.make_base_error(path, span, source, res);
@@ -429,6 +430,14 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         let mut err = self.r.dcx().struct_span_err(base_error.span, base_error.msg.clone());
         err.code(code);
 
+        // Try to get the span of the identifier within the path's syntax context
+        // (if that's different).
+        if let Some(within_macro_span) =
+            base_error.span.within_macro(span, self.r.tcx.sess.source_map())
+        {
+            err.span_label(within_macro_span, "due to this macro variable");
+        }
+
         self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg);
         self.suggest_at_operator_in_slice_pat_with_range(&mut err, path);
         self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
@@ -453,6 +462,15 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
 
         self.suggest_self_or_self_ref(&mut err, path, span);
         self.detect_assoc_type_constraint_meant_as_path(&mut err, &base_error);
+        self.detect_rtn_with_fully_qualified_path(
+            &mut err,
+            path,
+            following_seg,
+            span,
+            source,
+            res,
+            qself,
+        );
         if self.suggest_self_ty(&mut err, source, path, span)
             || self.suggest_self_value(&mut err, source, path, span)
         {
@@ -501,6 +519,33 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         (err, candidates)
     }
 
+    fn detect_rtn_with_fully_qualified_path(
+        &self,
+        err: &mut Diag<'_>,
+        path: &[Segment],
+        following_seg: Option<&Segment>,
+        span: Span,
+        source: PathSource<'_>,
+        res: Option<Res>,
+        qself: Option<&QSelf>,
+    ) {
+        if let Some(Res::Def(DefKind::AssocFn, _)) = res
+            && let PathSource::TraitItem(TypeNS) = source
+            && let None = following_seg
+            && let Some(qself) = qself
+            && let TyKind::Path(None, ty_path) = &qself.ty.kind
+            && ty_path.segments.len() == 1
+            && self.diag_metadata.current_where_predicate.is_some()
+        {
+            err.span_suggestion_verbose(
+                span,
+                "you might have meant to use the return type notation syntax",
+                format!("{}::{}(..)", ty_path.segments[0].ident, path[path.len() - 1].ident),
+                Applicability::MaybeIncorrect,
+            );
+        }
+    }
+
     fn detect_assoc_type_constraint_meant_as_path(
         &self,
         err: &mut Diag<'_>,
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index 50cf605ba2a..bb2b2dea2f3 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -88,10 +88,9 @@ impl RustcInternal for Pattern {
     type T<'tcx> = rustc_ty::Pattern<'tcx>;
     fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
         tcx.mk_pat(match self {
-            Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range {
-                start: start.as_ref().map(|c| c.internal(tables, tcx)),
-                end: end.as_ref().map(|c| c.internal(tables, tcx)),
-                include_end: *include_end,
+            Pattern::Range { start, end, include_end: _ } => rustc_ty::PatternKind::Range {
+                start: start.as_ref().unwrap().internal(tables, tcx),
+                end: end.as_ref().unwrap().internal(tables, tcx),
             },
         })
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index a0faf20c79a..aa0eac628dd 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -405,10 +405,11 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
 
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
         match **self {
-            ty::PatternKind::Range { start, end, include_end } => stable_mir::ty::Pattern::Range {
-                start: start.stable(tables),
-                end: end.stable(tables),
-                include_end,
+            ty::PatternKind::Range { start, end } => stable_mir::ty::Pattern::Range {
+                // FIXME(SMIR): update data structures to not have an Option here anymore
+                start: Some(start.stable(tables)),
+                end: Some(end.stable(tables)),
+                include_end: true,
             },
         }
     }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 84e89ff4b7d..64982b858c6 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1173,6 +1173,8 @@ pub enum DesugaringKind {
     BoundModifier,
     /// Calls to contract checks (`#[requires]` to precond, `#[ensures]` to postcond)
     Contract,
+    /// A pattern type range start/end
+    PatTyRange,
 }
 
 impl DesugaringKind {
@@ -1190,6 +1192,7 @@ impl DesugaringKind {
             DesugaringKind::WhileLoop => "`while` loop",
             DesugaringKind::BoundModifier => "trait bound modifier",
             DesugaringKind::Contract => "contract check",
+            DesugaringKind::PatTyRange => "pattern type",
         }
     }
 }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index bca9323a50d..798e186a94b 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -1057,6 +1057,37 @@ impl Span {
         }
     }
 
+    /// Returns the `Span` within the syntax context of "within". This is useful when
+    /// "self" is an expansion from a macro variable, since this can be used for
+    /// providing extra macro expansion context for certain errors.
+    ///
+    /// ```text
+    /// macro_rules! m {
+    ///     ($ident:ident) => { ($ident,) }
+    /// }
+    ///
+    /// m!(outer_ident);
+    /// ```
+    ///
+    /// If "self" is the span of the outer_ident, and "within" is the span of the `($ident,)`
+    /// expr, then this will return the span of the `$ident` macro variable.
+    pub fn within_macro(self, within: Span, sm: &SourceMap) -> Option<Span> {
+        match Span::prepare_to_combine(self, within) {
+            // Only return something if it doesn't overlap with the original span,
+            // and the span isn't "imported" (i.e. from unavailable sources).
+            // FIXME: This does limit the usefulness of the error when the macro is
+            // from a foreign crate; we could also take into account `-Zmacro-backtrace`,
+            // which doesn't redact this span (but that would mean passing in even more
+            // args to this function, lol).
+            Ok((self_, _, parent))
+                if self_.hi < self.lo() || self.hi() < self_.lo && !sm.is_imported(within) =>
+            {
+                Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent))
+            }
+            _ => None,
+        }
+    }
+
     pub fn from_inner(self, inner: InnerSpan) -> Span {
         let span = self.data();
         Span::new(
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 522bccb1acb..573c65a772c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -308,6 +308,9 @@ symbols! {
         RangeFull,
         RangeInclusive,
         RangeInclusiveCopy,
+        RangeMax,
+        RangeMin,
+        RangeSub,
         RangeTo,
         RangeToInclusive,
         Rc,
@@ -1522,6 +1525,7 @@ symbols! {
         pattern_complexity_limit,
         pattern_parentheses,
         pattern_type,
+        pattern_type_range_trait,
         pattern_types,
         permissions_from_mode,
         phantom_data,
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index a11f6f0df1c..bc3923e4b4d 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -413,12 +413,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             }
 
             ty::Pat(ty, pat) => match *pat {
-                ty::PatternKind::Range { start, end, include_end } => {
-                    let consts = [
-                        start.unwrap_or(self.tcx.consts.unit),
-                        end.unwrap_or(self.tcx.consts.unit),
-                        ty::Const::from_bool(self.tcx, include_end),
-                    ];
+                ty::PatternKind::Range { start, end } => {
+                    let consts = [start, end];
                     // HACK: Represent as tuple until we have something better.
                     // HACK: constants are used in arrays, even if the types don't match.
                     self.push("T");
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
index f15f1b78b52..d673e5672a0 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
@@ -1,8 +1,6 @@
 use std::ops::ControlFlow;
 
-use rustc_errors::{
-    Applicability, Diag, E0283, E0284, E0790, MultiSpan, StashKey, struct_span_code_err,
-};
+use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::LangItem;
 use rustc_hir::def::{DefKind, Res};
@@ -197,7 +195,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 // be ignoring the fact that we don't KNOW the type works
                 // out. Though even that would probably be harmless, given that
                 // we're only talking about builtin traits, which are known to be
-                // inhabited. We used to check for `self.tcx.sess.has_errors()` to
+                // inhabited. We used to check for `self.tainted_by_errors()` to
                 // avoid inundating the user with unnecessary errors, but we now
                 // check upstream for type errors and don't add the obligations to
                 // begin with in those cases.
@@ -211,7 +209,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                                 TypeAnnotationNeeded::E0282,
                                 false,
                             );
-                            return err.stash(span, StashKey::MaybeForgetReturn).unwrap();
+                            return err.emit();
                         }
                         Some(e) => return e,
                     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 8c1df9b5113..e2bdd52ba7c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -829,7 +829,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 && let ty::Closure(closure_def_id, _) | ty::CoroutineClosure(closure_def_id, _) =
                     *typeck_results.node_type(arg_hir_id).kind()
             {
-                // Otherwise, extract the closure kind from the obligation.
+                // Otherwise, extract the closure kind from the obligation,
+                // but only if we actually have an argument to deduce the
+                // closure type from...
                 let mut err = self.report_closure_error(
                     &obligation,
                     closure_def_id,
@@ -844,63 +846,72 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         let self_ty = trait_pred.self_ty().skip_binder();
 
-        if let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) {
-            let (closure_def_id, found_args, by_ref_captures) = match *self_ty.kind() {
-                ty::Closure(def_id, args) => {
-                    (def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), None)
-                }
-                ty::CoroutineClosure(def_id, args) => (
-                    def_id,
-                    args.as_coroutine_closure()
-                        .coroutine_closure_sig()
-                        .map_bound(|sig| sig.tupled_inputs_ty),
-                    Some(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
-                ),
-                _ => return None,
+        let (expected_kind, trait_prefix) =
+            if let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) {
+                (expected_kind, "")
+            } else if let Some(expected_kind) =
+                self.tcx.async_fn_trait_kind_from_def_id(trait_pred.def_id())
+            {
+                (expected_kind, "Async")
+            } else {
+                return None;
             };
 
-            let expected_args =
-                trait_pred.map_bound(|trait_pred| trait_pred.trait_ref.args.type_at(1));
-
-            // Verify that the arguments are compatible. If the signature is
-            // mismatched, then we have a totally different error to report.
-            if self.enter_forall(found_args, |found_args| {
-                self.enter_forall(expected_args, |expected_args| {
-                    !self.can_eq(obligation.param_env, expected_args, found_args)
-                })
-            }) {
-                return None;
+        let (closure_def_id, found_args, by_ref_captures) = match *self_ty.kind() {
+            ty::Closure(def_id, args) => {
+                (def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), None)
             }
+            ty::CoroutineClosure(def_id, args) => (
+                def_id,
+                args.as_coroutine_closure()
+                    .coroutine_closure_sig()
+                    .map_bound(|sig| sig.tupled_inputs_ty),
+                Some(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
+            ),
+            _ => return None,
+        };
 
-            if let Some(found_kind) = self.closure_kind(self_ty)
-                && !found_kind.extends(expected_kind)
-            {
-                let mut err = self.report_closure_error(
-                    &obligation,
-                    closure_def_id,
-                    found_kind,
-                    expected_kind,
-                    "",
-                );
-                self.note_obligation_cause(&mut err, &obligation);
-                return Some(err.emit());
-            }
+        let expected_args = trait_pred.map_bound(|trait_pred| trait_pred.trait_ref.args.type_at(1));
 
-            // If the closure has captures, then perhaps the reason that the trait
-            // is unimplemented is because async closures don't implement `Fn`/`FnMut`
-            // if they have captures.
-            if let Some(by_ref_captures) = by_ref_captures
-                && let ty::FnPtr(sig_tys, _) = by_ref_captures.kind()
-                && !sig_tys.skip_binder().output().is_unit()
-            {
-                let mut err = self.dcx().create_err(AsyncClosureNotFn {
-                    span: self.tcx.def_span(closure_def_id),
-                    kind: expected_kind.as_str(),
-                });
-                self.note_obligation_cause(&mut err, &obligation);
-                return Some(err.emit());
-            }
+        // Verify that the arguments are compatible. If the signature is
+        // mismatched, then we have a totally different error to report.
+        if self.enter_forall(found_args, |found_args| {
+            self.enter_forall(expected_args, |expected_args| {
+                !self.can_eq(obligation.param_env, expected_args, found_args)
+            })
+        }) {
+            return None;
         }
+
+        if let Some(found_kind) = self.closure_kind(self_ty)
+            && !found_kind.extends(expected_kind)
+        {
+            let mut err = self.report_closure_error(
+                &obligation,
+                closure_def_id,
+                found_kind,
+                expected_kind,
+                trait_prefix,
+            );
+            self.note_obligation_cause(&mut err, &obligation);
+            return Some(err.emit());
+        }
+
+        // If the closure has captures, then perhaps the reason that the trait
+        // is unimplemented is because async closures don't implement `Fn`/`FnMut`
+        // if they have captures.
+        if let Some(by_ref_captures) = by_ref_captures
+            && let ty::FnPtr(sig_tys, _) = by_ref_captures.kind()
+            && !sig_tys.skip_binder().output().is_unit()
+        {
+            let mut err = self.dcx().create_err(AsyncClosureNotFn {
+                span: self.tcx.def_span(closure_def_id),
+                kind: expected_kind.as_str(),
+            });
+            self.note_obligation_cause(&mut err, &obligation);
+            return Some(err.emit());
+        }
+
         None
     }
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index d180c0be9d5..ad46a15a5ac 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -2695,7 +2695,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             | ObligationCauseCode::LetElse
             | ObligationCauseCode::BinOp { .. }
             | ObligationCauseCode::AscribeUserTypeProvePredicate(..)
-            | ObligationCauseCode::DropImpl
+            | ObligationCauseCode::AlwaysApplicableImpl
             | ObligationCauseCode::ConstParam(_)
             | ObligationCauseCode::ReferenceOutlivesReferent(..)
             | ObligationCauseCode::ObjectTypeBound(..) => {}
@@ -3191,7 +3191,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     false
                 };
 
-                if !is_upvar_tys_infer_tuple {
+                let is_builtin_async_fn_trait =
+                    tcx.async_fn_trait_kind_from_def_id(data.parent_trait_pred.def_id()).is_some();
+
+                if !is_upvar_tys_infer_tuple && !is_builtin_async_fn_trait {
                     let ty_str = tcx.short_string(ty, err.long_ty_path());
                     let msg = format!("required because it appears within the type `{ty_str}`");
                     match ty.kind() {
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 6669d8525fa..6db97fc321a 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -983,8 +983,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 return Err(SelectionError::Unimplemented);
             }
         } else {
-            nested.push(obligation.with(
+            nested.push(Obligation::new(
                 self.tcx(),
+                obligation.derived_cause(ObligationCauseCode::BuiltinDerived),
+                obligation.param_env,
                 ty::TraitRef::new(
                     self.tcx(),
                     self.tcx().require_lang_item(
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 18906a6a8ce..54b6c22b2d8 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -708,7 +708,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
             ty::Pat(subty, pat) => {
                 self.require_sized(subty, ObligationCauseCode::Misc);
                 match *pat {
-                    ty::PatternKind::Range { start, end, include_end: _ } => {
+                    ty::PatternKind::Range { start, end } => {
                         let mut check = |c| {
                             let cause = self.cause(ObligationCauseCode::Misc);
                             self.out.push(traits::Obligation::with_depth(
@@ -738,12 +738,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                                 }
                             }
                         };
-                        if let Some(start) = start {
-                            check(start)
-                        }
-                        if let Some(end) = end {
-                            check(end)
-                        }
+                        check(start);
+                        check(end);
                     }
                 }
             }
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 852d3fc58d8..a53f0538c58 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -205,24 +205,17 @@ fn layout_of_uncached<'tcx>(
             let layout = cx.layout_of(ty)?.layout;
             let mut layout = LayoutData::clone(&layout.0);
             match *pat {
-                ty::PatternKind::Range { start, end, include_end } => {
+                ty::PatternKind::Range { start, end } => {
                     if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
                         &mut layout.backend_repr
                     {
-                        if let Some(start) = start {
-                            scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
-                                .try_to_bits(tcx, cx.typing_env)
-                                .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
-                        }
-                        if let Some(end) = end {
-                            let mut end = extract_const_value(cx, ty, end)?
-                                .try_to_bits(tcx, cx.typing_env)
-                                .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
-                            if !include_end {
-                                end = end.wrapping_sub(1);
-                            }
-                            scalar.valid_range_mut().end = end;
-                        }
+                        scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
+                            .try_to_bits(tcx, cx.typing_env)
+                            .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
+
+                        scalar.valid_range_mut().end = extract_const_value(cx, ty, end)?
+                            .try_to_bits(tcx, cx.typing_env)
+                            .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
 
                         let niche = Niche {
                             offset: Size::ZERO,