about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs50
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs41
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs15
3 files changed, 59 insertions, 47 deletions
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index 8a2f62ce833..60181783f9b 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -5,7 +5,7 @@ use rustc_hir::def::{DefKind, Namespace};
 use rustc_hir::def_id::DefId;
 use rustc_hir::find_attr;
 use rustc_macros::{Decodable, Encodable, HashStable};
-use rustc_span::{Ident, Symbol};
+use rustc_span::{ErrorGuaranteed, Ident, Symbol};
 
 use super::{TyCtxt, Visibility};
 use crate::ty;
@@ -13,7 +13,9 @@ use crate::ty;
 #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash, Encodable, Decodable)]
 pub enum AssocContainer {
     Trait,
-    Impl,
+    InherentImpl,
+    /// The `DefId` points to the trait item being implemented.
+    TraitImpl(Result<DefId, ErrorGuaranteed>),
 }
 
 /// Information about an associated item
@@ -22,10 +24,6 @@ pub struct AssocItem {
     pub def_id: DefId,
     pub kind: AssocKind,
     pub container: AssocContainer,
-
-    /// If this is an item in an impl of a trait then this is the `DefId` of
-    /// the associated item on the trait that this implements.
-    pub trait_item_def_id: Option<DefId>,
 }
 
 impl AssocItem {
@@ -58,6 +56,30 @@ impl AssocItem {
         tcx.defaultness(self.def_id)
     }
 
+    pub fn expect_trait_impl(&self) -> Result<DefId, ErrorGuaranteed> {
+        let AssocContainer::TraitImpl(trait_item_id) = self.container else {
+            bug!("expected item to be in a trait impl: {:?}", self.def_id);
+        };
+        trait_item_id
+    }
+
+    /// If this is a trait impl item, returns the `DefId` of the trait item this implements.
+    /// Otherwise, returns `DefId` for self. Returns an Err in case the trait item was not
+    /// resolved successfully.
+    pub fn trait_item_or_self(&self) -> Result<DefId, ErrorGuaranteed> {
+        match self.container {
+            AssocContainer::TraitImpl(id) => id,
+            AssocContainer::Trait | AssocContainer::InherentImpl => Ok(self.def_id),
+        }
+    }
+
+    pub fn trait_item_def_id(&self) -> Option<DefId> {
+        match self.container {
+            AssocContainer::TraitImpl(Ok(id)) => Some(id),
+            _ => None,
+        }
+    }
+
     #[inline]
     pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility<DefId> {
         tcx.visibility(self.def_id)
@@ -71,7 +93,7 @@ impl AssocItem {
     #[inline]
     pub fn trait_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
         match self.container {
-            AssocContainer::Impl => None,
+            AssocContainer::InherentImpl | AssocContainer::TraitImpl(_) => None,
             AssocContainer::Trait => Some(tcx.parent(self.def_id)),
         }
     }
@@ -79,7 +101,9 @@ impl AssocItem {
     #[inline]
     pub fn impl_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
         match self.container {
-            AssocContainer::Impl => Some(tcx.parent(self.def_id)),
+            AssocContainer::InherentImpl | AssocContainer::TraitImpl(_) => {
+                Some(tcx.parent(self.def_id))
+            }
             AssocContainer::Trait => None,
         }
     }
@@ -156,11 +180,11 @@ impl AssocItem {
             return false;
         }
 
-        let def_id = match (self.container, self.trait_item_def_id) {
-            (AssocContainer::Trait, _) => self.def_id,
-            (AssocContainer::Impl, Some(trait_item_did)) => trait_item_did,
-            // Inherent impl but this attr is only applied to trait assoc items.
-            (AssocContainer::Impl, None) => return true,
+        let def_id = match self.container {
+            AssocContainer::Trait => self.def_id,
+            AssocContainer::TraitImpl(Ok(trait_item_did)) => trait_item_did,
+            AssocContainer::TraitImpl(Err(_)) => return false,
+            AssocContainer::InherentImpl => return true,
         };
         find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_))
     }
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index ec2a23bfebe..34ead91b4f6 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -18,8 +18,8 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::ty::normalize_erasing_regions::NormalizationError;
 use crate::ty::print::{FmtPrinter, Print};
 use crate::ty::{
-    self, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
-    TypeVisitable, TypeVisitableExt, TypeVisitor,
+    self, AssocContainer, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable,
+    TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
 
 /// An `InstanceKind` along with the args that are needed to substitute the instance.
@@ -611,26 +611,23 @@ impl<'tcx> Instance<'tcx> {
                     debug!(" => fn pointer created for virtual call");
                     resolved.def = InstanceKind::ReifyShim(def_id, reason);
                 }
-                // Reify `Trait::method` implementations if KCFI is enabled
-                // FIXME(maurer) only reify it if it is a vtable-safe function
-                _ if tcx.sess.is_sanitizer_kcfi_enabled()
-                    && tcx
-                        .opt_associated_item(def_id)
-                        .and_then(|assoc| assoc.trait_item_def_id)
-                        .is_some() =>
-                {
-                    // If this function could also go in a vtable, we need to `ReifyShim` it with
-                    // KCFI because it can only attach one type per function.
-                    resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason)
-                }
-                // Reify `::call`-like method implementations if KCFI is enabled
-                _ if tcx.sess.is_sanitizer_kcfi_enabled()
-                    && tcx.is_closure_like(resolved.def_id()) =>
-                {
-                    // Reroute through a reify via the *unresolved* instance. The resolved one can't
-                    // be directly reified because it's closure-like. The reify can handle the
-                    // unresolved instance.
-                    resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
+                _ if tcx.sess.is_sanitizer_kcfi_enabled() => {
+                    // Reify `::call`-like method implementations
+                    if tcx.is_closure_like(resolved.def_id()) {
+                        // Reroute through a reify via the *unresolved* instance. The resolved one can't
+                        // be directly reified because it's closure-like. The reify can handle the
+                        // unresolved instance.
+                        resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
+                    // Reify `Trait::method` implementations
+                    // FIXME(maurer) only reify it if it is a vtable-safe function
+                    } else if let Some(assoc) = tcx.opt_associated_item(def_id)
+                        && let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) =
+                            assoc.container
+                    {
+                        // If this function could also go in a vtable, we need to `ReifyShim` it with
+                        // KCFI because it can only attach one type per function.
+                        resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason)
+                    }
                 }
                 _ => {}
             }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index a34bf9b5297..d4c001f625e 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1936,11 +1936,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Returns the trait item that is implemented by the given item `DefId`.
     pub fn trait_item_of(self, def_id: impl IntoQueryParam<DefId>) -> Option<DefId> {
-        let assoc = self.opt_associated_item(def_id.into_query_param())?;
-        if assoc.container != AssocContainer::Impl {
-            return None;
-        }
-        assoc.trait_item_def_id
+        self.opt_associated_item(def_id.into_query_param())?.trait_item_def_id()
     }
 
     /// If the given `DefId` is an associated item of a trait,
@@ -2158,17 +2154,12 @@ impl<'tcx> TyCtxt<'tcx> {
         let Some(item) = self.opt_associated_item(def_id) else {
             return false;
         };
-        if item.container != ty::AssocContainer::Impl {
-            return false;
-        }
 
-        let Some(trait_item_def_id) = item.trait_item_def_id else {
+        let AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container else {
             return false;
         };
 
-        return !self
-            .associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
-            .is_empty();
+        !self.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id).is_empty()
     }
 }