about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
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/rustc_hir_analysis/src
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/rustc_hir_analysis/src')
-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
9 files changed, 156 insertions, 153 deletions
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);