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/mir/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/adjustment.rs4
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs62
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/util.rs4
6 files changed, 42 insertions, 36 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 4dfb362f3a2..db19c858e7c 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1636,8 +1636,8 @@ pub fn find_self_call<'tcx>(
         &body[block].terminator
         && let Operand::Constant(box ConstOperand { const_, .. }) = func
         && let ty::FnDef(def_id, fn_args) = *const_.ty().kind()
-        && let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
-            tcx.opt_associated_item(def_id)
+        && let Some(item) = tcx.opt_associated_item(def_id)
+        && item.is_method()
         && let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] =
             **args
     {
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs
index f8ab555305f..3425da48559 100644
--- a/compiler/rustc_middle/src/ty/adjustment.rs
+++ b/compiler/rustc_middle/src/ty/adjustment.rs
@@ -5,7 +5,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_span::Span;
 
-use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::{Ty, TyCtxt};
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
 pub enum PointerCoercion {
@@ -133,7 +133,7 @@ impl OverloadedDeref {
         };
         tcx.associated_items(trait_def_id)
             .in_definition_order()
-            .find(|m| m.kind == ty::AssocKind::Fn)
+            .find(|item| item.is_fn())
             .unwrap()
             .def_id
     }
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index bbaf735fbdb..3c1e5ed9e11 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -26,10 +26,6 @@ pub struct AssocItem {
     /// the associated item on the trait that this implements.
     pub trait_item_def_id: Option<DefId>,
 
-    /// Whether this is a method with an explicit self
-    /// as its first parameter, allowing method calls.
-    pub fn_has_self_parameter: bool,
-
     /// `Some` if the associated item (an associated type) comes from the
     /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData`
     /// provides additional information about its source.
@@ -78,7 +74,7 @@ impl AssocItem {
 
     pub fn signature(&self, tcx: TyCtxt<'_>) -> String {
         match self.kind {
-            ty::AssocKind::Fn => {
+            ty::AssocKind::Fn { .. } => {
                 // We skip the binder here because the binder would deanonymize all
                 // late-bound regions, and we don't want method signatures to show up
                 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
@@ -99,12 +95,28 @@ impl AssocItem {
     pub fn descr(&self) -> &'static str {
         match self.kind {
             ty::AssocKind::Const => "associated const",
-            ty::AssocKind::Fn if self.fn_has_self_parameter => "method",
-            ty::AssocKind::Fn => "associated function",
+            ty::AssocKind::Fn { has_self: true } => "method",
+            ty::AssocKind::Fn { has_self: false } => "associated function",
             ty::AssocKind::Type => "associated type",
         }
     }
 
+    pub fn is_fn(&self) -> bool {
+        matches!(self.kind, ty::AssocKind::Fn { .. })
+    }
+
+    pub fn is_method(&self) -> bool {
+        matches!(self.kind, ty::AssocKind::Fn { has_self: true })
+    }
+
+    pub fn as_tag(&self) -> AssocTag {
+        match self.kind {
+            AssocKind::Const => AssocTag::Const,
+            AssocKind::Fn { .. } => AssocTag::Fn,
+            AssocKind::Type => AssocTag::Type,
+        }
+    }
+
     pub fn is_impl_trait_in_trait(&self) -> bool {
         self.opt_rpitit_info.is_some()
     }
@@ -131,7 +143,7 @@ impl AssocItem {
 #[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)]
 pub enum AssocKind {
     Const,
-    Fn,
+    Fn { has_self: bool },
     Type,
 }
 
@@ -139,14 +151,14 @@ impl AssocKind {
     pub fn namespace(&self) -> Namespace {
         match *self {
             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 {
             AssocKind::Const => DefKind::AssocConst,
-            AssocKind::Fn => DefKind::AssocFn,
+            AssocKind::Fn { .. } => DefKind::AssocFn,
             AssocKind::Type => DefKind::AssocTy,
         }
     }
@@ -155,15 +167,22 @@ impl AssocKind {
 impl std::fmt::Display for AssocKind {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
-            // FIXME: fails to distinguish between "associated function" and
-            // "method" because `has_self` isn't known here.
-            AssocKind::Fn => write!(f, "method"),
+            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"),
         }
     }
 }
 
+// Like `AssocKind`, but just the tag, no fields. Used in various kinds of matching.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum AssocTag {
+    Const,
+    Fn,
+    Type,
+}
+
 /// A list of `ty::AssocItem`s in definition order that allows for efficient lookup by name.
 ///
 /// When doing lookup by name, we try to postpone hygienic comparison for as long as possible since
@@ -207,27 +226,14 @@ impl AssocItems {
         &self,
         tcx: TyCtxt<'_>,
         ident: Ident,
-        kind: AssocKind,
+        assoc_tag: AssocTag,
         parent_def_id: DefId,
     ) -> Option<&ty::AssocItem> {
         self.filter_by_name_unhygienic(ident.name)
-            .filter(|item| item.kind == kind)
+            .filter(|item| item.as_tag() == assoc_tag)
             .find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id))
     }
 
-    /// Returns the associated item with the given identifier and any of `AssocKind`, if one
-    /// exists. The identifier is matched hygienically.
-    pub fn find_by_ident_and_kinds(
-        &self,
-        tcx: TyCtxt<'_>,
-        ident: Ident,
-        // Sorted in order of what kinds to look at
-        kinds: &[AssocKind],
-        parent_def_id: DefId,
-    ) -> Option<&ty::AssocItem> {
-        kinds.iter().find_map(|kind| self.find_by_ident_and_kind(tcx, ident, *kind, parent_def_id))
-    }
-
     /// Returns the associated item with the given identifier in the given `Namespace`, if one
     /// exists. The identifier is matched hygienically.
     pub fn find_by_ident_and_namespace(
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 07f2a602f2b..faad0a82acb 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -746,7 +746,7 @@ impl<'tcx> Instance<'tcx> {
         let call_once = tcx
             .associated_items(fn_once)
             .in_definition_order()
-            .find(|it| it.kind == ty::AssocKind::Fn)
+            .find(|it| it.is_fn())
             .unwrap()
             .def_id;
         let track_caller =
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index a2b3acac3f2..30c889c39d9 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1464,7 +1464,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
         self.associated_items(id)
             .in_definition_order()
-            .filter(move |item| item.kind == AssocKind::Fn && item.defaultness(self).has_value())
+            .filter(move |item| item.is_fn() && item.defaultness(self).has_value())
     }
 
     pub fn repr_options_of_def(self, did: LocalDefId) -> ReprOptions {
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 857b462b9eb..dfc11de283d 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -819,7 +819,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Get an English description for the item's kind.
     pub fn def_kind_descr(self, def_kind: DefKind, def_id: DefId) -> &'static str {
         match def_kind {
-            DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "method",
+            DefKind::AssocFn if self.associated_item(def_id).is_method() => "method",
             DefKind::Closure if let Some(coroutine_kind) = self.coroutine_kind(def_id) => {
                 match coroutine_kind {
                     hir::CoroutineKind::Desugared(
@@ -873,7 +873,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Gets an English article for the [`TyCtxt::def_kind_descr`].
     pub fn def_kind_descr_article(self, def_kind: DefKind, def_id: DefId) -> &'static str {
         match def_kind {
-            DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "a",
+            DefKind::AssocFn if self.associated_item(def_id).is_method() => "a",
             DefKind::Closure if let Some(coroutine_kind) = self.coroutine_kind(def_id) => {
                 match coroutine_kind {
                     hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, ..) => "an",