about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2025-04-14 13:15:01 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2025-04-15 08:07:15 +1000
commit78599d83e7ab9f8cd4cbb9e982ddf12f258d6b18 (patch)
treec1c0488e6609360dba87b88a8e390b3ebfce939a /compiler/rustc_middle/src
parent89e93a51c81b521a9601b365e3325d31e44e9198 (diff)
downloadrust-78599d83e7ab9f8cd4cbb9e982ddf12f258d6b18.tar.gz
rust-78599d83e7ab9f8cd4cbb9e982ddf12f258d6b18.zip
Move `name` field from `AssocItem` to `AssocKind` variants.
To accurately reflect that RPITIT assoc items don't have a name. This
avoids the use of `kw::Empty` to mean "no name", which is error prone.

Helps with #137978.
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs101
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs5
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs6
3 files changed, 72 insertions, 40 deletions
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index 6138157d836..0c44fd2758d 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -18,7 +18,6 @@ pub enum AssocItemContainer {
 #[derive(Copy, Clone, Debug, PartialEq, HashStable, Eq, Hash, Encodable, Decodable)]
 pub struct AssocItem {
     pub def_id: DefId,
-    pub name: Symbol,
     pub kind: AssocKind,
     pub container: AssocItemContainer,
 
@@ -28,8 +27,24 @@ pub struct AssocItem {
 }
 
 impl AssocItem {
+    // Gets the identifier, if it has one.
+    pub fn opt_name(&self) -> Option<Symbol> {
+        match self.kind {
+            ty::AssocKind::Type { data: AssocTypeData::Normal(name) } => Some(name),
+            ty::AssocKind::Type { data: AssocTypeData::Rpitit(_) } => None,
+            ty::AssocKind::Const { name } => Some(name),
+            ty::AssocKind::Fn { name, .. } => Some(name),
+        }
+    }
+
+    // Gets the identifier name. Aborts if it lacks one, i.e. is an RPITIT
+    // associated type.
+    pub fn name(&self) -> Symbol {
+        self.opt_name().expect("name of non-Rpitit assoc item")
+    }
+
     pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
-        Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
+        Ident::new(self.name(), tcx.def_ident_span(self.def_id).unwrap())
     }
 
     /// Gets the defaultness of the associated item.
@@ -76,22 +91,18 @@ impl AssocItem {
                 // regions just fine, showing `fn(&MyType)`.
                 tcx.fn_sig(self.def_id).instantiate_identity().skip_binder().to_string()
             }
-            ty::AssocKind::Type { .. } => format!("type {};", self.name),
-            ty::AssocKind::Const => {
-                format!(
-                    "const {}: {:?};",
-                    self.name,
-                    tcx.type_of(self.def_id).instantiate_identity()
-                )
+            ty::AssocKind::Type { .. } => format!("type {};", self.name()),
+            ty::AssocKind::Const { name } => {
+                format!("const {}: {:?};", name, tcx.type_of(self.def_id).instantiate_identity())
             }
         }
     }
 
     pub fn descr(&self) -> &'static str {
         match self.kind {
-            ty::AssocKind::Const => "associated const",
-            ty::AssocKind::Fn { has_self: true } => "method",
-            ty::AssocKind::Fn { has_self: false } => "associated function",
+            ty::AssocKind::Const { .. } => "associated const",
+            ty::AssocKind::Fn { has_self: true, .. } => "method",
+            ty::AssocKind::Fn { has_self: false, .. } => "associated function",
             ty::AssocKind::Type { .. } => "associated type",
         }
     }
@@ -99,13 +110,13 @@ impl AssocItem {
     pub fn namespace(&self) -> Namespace {
         match self.kind {
             ty::AssocKind::Type { .. } => Namespace::TypeNS,
-            ty::AssocKind::Const | ty::AssocKind::Fn { .. } => Namespace::ValueNS,
+            ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => Namespace::ValueNS,
         }
     }
 
     pub fn as_def_kind(&self) -> DefKind {
         match self.kind {
-            AssocKind::Const => DefKind::AssocConst,
+            AssocKind::Const { .. } => DefKind::AssocConst,
             AssocKind::Fn { .. } => DefKind::AssocFn,
             AssocKind::Type { .. } => DefKind::AssocTy,
         }
@@ -119,19 +130,19 @@ impl AssocItem {
     }
 
     pub fn is_method(&self) -> bool {
-        matches!(self.kind, ty::AssocKind::Fn { has_self: true })
+        matches!(self.kind, ty::AssocKind::Fn { has_self: true, .. })
     }
 
     pub fn as_tag(&self) -> AssocTag {
         match self.kind {
-            AssocKind::Const => AssocTag::Const,
+            AssocKind::Const { .. } => AssocTag::Const,
             AssocKind::Fn { .. } => AssocTag::Fn,
             AssocKind::Type { .. } => AssocTag::Type,
         }
     }
 
     pub fn is_impl_trait_in_trait(&self) -> bool {
-        matches!(self.kind, AssocKind::Type { opt_rpitit_info: Some(_) })
+        matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
     }
 
     /// Returns true if:
@@ -139,7 +150,7 @@ impl AssocItem {
     /// - If it is in a trait impl, the item from the original trait has this attribute, or
     /// - It is an inherent assoc const.
     pub fn is_type_const_capable(&self, tcx: TyCtxt<'_>) -> bool {
-        if self.kind != ty::AssocKind::Const {
+        if !matches!(self.kind, ty::AssocKind::Const { .. }) {
             return false;
         }
 
@@ -154,25 +165,44 @@ impl AssocItem {
 }
 
 #[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)]
+pub enum AssocTypeData {
+    Normal(Symbol),
+    /// The associated type comes from an RPITIT. It has no name, and the
+    /// `ImplTraitInTraitData` provides additional information about its
+    /// source.
+    Rpitit(ty::ImplTraitInTraitData),
+}
+
+#[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)]
 pub enum AssocKind {
-    Const,
-    Fn {
-        has_self: bool,
-    },
-    Type {
-        /// `Some` if the associated type comes from an RPITIT. The
-        /// `ImplTraitInTraitData` provides additional information about its
-        /// source.
-        opt_rpitit_info: Option<ty::ImplTraitInTraitData>,
-    },
+    Const { name: Symbol },
+    Fn { name: Symbol, has_self: bool },
+    Type { data: AssocTypeData },
+}
+
+impl AssocKind {
+    pub fn namespace(&self) -> Namespace {
+        match *self {
+            ty::AssocKind::Type { .. } => Namespace::TypeNS,
+            ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => Namespace::ValueNS,
+        }
+    }
+
+    pub fn as_def_kind(&self) -> DefKind {
+        match self {
+            AssocKind::Const { .. } => DefKind::AssocConst,
+            AssocKind::Fn { .. } => DefKind::AssocFn,
+            AssocKind::Type { .. } => DefKind::AssocTy,
+        }
+    }
 }
 
 impl std::fmt::Display for AssocKind {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
-            AssocKind::Fn { has_self: true } => write!(f, "method"),
-            AssocKind::Fn { has_self: false } => write!(f, "associated function"),
-            AssocKind::Const => write!(f, "associated const"),
+            AssocKind::Fn { has_self: true, .. } => write!(f, "method"),
+            AssocKind::Fn { has_self: false, .. } => write!(f, "associated function"),
+            AssocKind::Const { .. } => write!(f, "associated const"),
             AssocKind::Type { .. } => write!(f, "associated type"),
         }
     }
@@ -193,17 +223,17 @@ pub enum AssocTag {
 /// done only on items with the same name.
 #[derive(Debug, Clone, PartialEq, HashStable)]
 pub struct AssocItems {
-    items: SortedIndexMultiMap<u32, Symbol, ty::AssocItem>,
+    items: SortedIndexMultiMap<u32, Option<Symbol>, ty::AssocItem>,
 }
 
 impl AssocItems {
     /// Constructs an `AssociatedItems` map from a series of `ty::AssocItem`s in definition order.
     pub fn new(items_in_def_order: impl IntoIterator<Item = ty::AssocItem>) -> Self {
-        let items = items_in_def_order.into_iter().map(|item| (item.name, item)).collect();
+        let items = items_in_def_order.into_iter().map(|item| (item.opt_name(), item)).collect();
         AssocItems { items }
     }
 
-    /// Returns a slice of associated items in the order they were defined.
+    /// Returns an iterator over associated items in the order they were defined.
     ///
     /// New code should avoid relying on definition order. If you need a particular associated item
     /// for a known trait, make that trait a lang item instead of indexing this array.
@@ -220,7 +250,8 @@ impl AssocItems {
         &self,
         name: Symbol,
     ) -> impl '_ + Iterator<Item = &ty::AssocItem> {
-        self.items.get_by_key(name)
+        assert!(!name.is_empty());
+        self.items.get_by_key(Some(name))
     }
 
     /// Returns the associated item with the given identifier and `AssocKind`, if one exists.
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 395d2ec4814..1945538b1c2 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1611,9 +1611,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// about where that RPITIT came from.
     pub fn opt_rpitit_info(self, def_id: DefId) -> Option<ImplTraitInTraitData> {
         if let DefKind::AssocTy = self.def_kind(def_id)
-            && let AssocKind::Type { opt_rpitit_info } = self.associated_item(def_id).kind
+            && let AssocKind::Type { data: AssocTypeData::Rpitit(rpitit_info) } =
+                self.associated_item(def_id).kind
         {
-            opt_rpitit_info
+            Some(rpitit_info)
         } else {
             None
         }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 2f93197bcef..d739218af5e 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1214,7 +1214,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                             && assoc
                                 .trait_container(tcx)
                                 .is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Coroutine))
-                            && assoc.name == rustc_span::sym::Return
+                            && assoc.opt_name() == Some(rustc_span::sym::Return)
                         {
                             if let ty::Coroutine(_, args) = args.type_at(0).kind() {
                                 let return_ty = args.as_coroutine().return_ty();
@@ -1237,7 +1237,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                             p!(", ");
                         }
 
-                        p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name));
+                        p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name()));
 
                         match term.unpack() {
                             TermKind::Ty(ty) => p!(print(ty)),
@@ -3291,7 +3291,7 @@ define_print! {
     }
 
     ty::ExistentialProjection<'tcx> {
-        let name = cx.tcx().associated_item(self.def_id).name;
+        let name = cx.tcx().associated_item(self.def_id).name();
         // The args don't contain the self ty (as it has been erased) but the corresp.
         // generics do as the trait always has a self ty param. We need to offset.
         let args = &self.args[cx.tcx().generics_of(self.def_id).parent_count - 1..];