summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir/src/def.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir/src/def.rs')
-rw-r--r--compiler/rustc_hir/src/def.rs125
1 files changed, 75 insertions, 50 deletions
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index e7c26bd72..4ef4aad90 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -314,74 +314,75 @@ pub enum Res<Id = hir::HirId> {
/// **Belongs to the type namespace.**
PrimTy(hir::PrimTy),
- /// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and
- /// optionally with the [`DefId`] of the item introducing the `Self` type alias.
+ /// The `Self` type, as used within a trait.
+ ///
+ /// **Belongs to the type namespace.**
+ ///
+ /// See the examples on [`Res::SelfTyAlias`] for details.
+ SelfTyParam {
+ /// The trait this `Self` is a generic parameter for.
+ trait_: DefId,
+ },
+
+ /// The `Self` type, as used somewhere other than within a trait.
///
/// **Belongs to the type namespace.**
///
/// Examples:
/// ```
- /// struct Bar(Box<Self>);
- /// // `Res::SelfTy { trait_: None, alias_of: Some(Bar) }`
+ /// struct Bar(Box<Self>); // SelfTyAlias
///
/// trait Foo {
- /// fn foo() -> Box<Self>;
- /// // `Res::SelfTy { trait_: Some(Foo), alias_of: None }`
+ /// fn foo() -> Box<Self>; // SelfTyParam
/// }
///
/// impl Bar {
/// fn blah() {
- /// let _: Self;
- /// // `Res::SelfTy { trait_: None, alias_of: Some(::{impl#0}) }`
+ /// let _: Self; // SelfTyAlias
/// }
/// }
///
/// impl Foo for Bar {
- /// fn foo() -> Box<Self> {
- /// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
- /// let _: Self;
- /// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
+ /// fn foo() -> Box<Self> { // SelfTyAlias
+ /// let _: Self; // SelfTyAlias
///
/// todo!()
/// }
/// }
/// ```
- ///
/// *See also [`Res::SelfCtor`].*
///
- /// -----
- ///
- /// HACK(min_const_generics): self types also have an optional requirement to **not** mention
- /// any generic parameters to allow the following with `min_const_generics`:
- /// ```
- /// # struct Foo;
- /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
- ///
- /// struct Bar([u8; baz::<Self>()]);
- /// const fn baz<T>() -> usize { 10 }
- /// ```
- /// We do however allow `Self` in repeat expression even if it is generic to not break code
- /// which already works on stable while causing the `const_evaluatable_unchecked` future compat
- /// lint:
- /// ```
- /// fn foo<T>() {
- /// let _bar = [1_u8; std::mem::size_of::<*mut T>()];
- /// }
- /// ```
- // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
- SelfTy {
- /// The trait this `Self` is a generic arg for.
- trait_: Option<DefId>,
+ SelfTyAlias {
/// The item introducing the `Self` type alias. Can be used in the `type_of` query
- /// to get the underlying type. Additionally whether the `Self` type is disallowed
- /// from mentioning generics (i.e. when used in an anonymous constant).
- alias_to: Option<(DefId, bool)>,
- },
+ /// to get the underlying type.
+ alias_to: DefId,
- /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
- ///
- /// **Belongs to the type namespace.**
- ToolMod,
+ /// Whether the `Self` type is disallowed from mentioning generics (i.e. when used in an
+ /// anonymous constant).
+ ///
+ /// HACK(min_const_generics): self types also have an optional requirement to **not**
+ /// mention any generic parameters to allow the following with `min_const_generics`:
+ /// ```
+ /// # struct Foo;
+ /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
+ ///
+ /// struct Bar([u8; baz::<Self>()]);
+ /// const fn baz<T>() -> usize { 10 }
+ /// ```
+ /// We do however allow `Self` in repeat expression even if it is generic to not break code
+ /// which already works on stable while causing the `const_evaluatable_unchecked` future
+ /// compat lint:
+ /// ```
+ /// fn foo<T>() {
+ /// let _bar = [1_u8; std::mem::size_of::<*mut T>()];
+ /// }
+ /// ```
+ // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
+ forbid_generic: bool,
+
+ /// Is this within an `impl Foo for bar`?
+ is_trait_impl: bool,
+ },
// Value namespace
/// The `Self` constructor, along with the [`DefId`]
@@ -389,7 +390,7 @@ pub enum Res<Id = hir::HirId> {
///
/// **Belongs to the value namespace.**
///
- /// *See also [`Res::SelfTy`].*
+ /// *See also [`Res::SelfTyParam`] and [`Res::SelfTyAlias`].*
SelfCtor(DefId),
/// A local variable or function parameter.
@@ -397,6 +398,11 @@ pub enum Res<Id = hir::HirId> {
/// **Belongs to the value namespace.**
Local(Id),
+ /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
+ ///
+ /// **Belongs to the type namespace.**
+ ToolMod,
+
// Macro namespace
/// An attribute that is *not* implemented via macro.
/// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
@@ -458,6 +464,16 @@ impl PartialRes {
pub fn unresolved_segments(&self) -> usize {
self.unresolved_segments
}
+
+ #[inline]
+ pub fn full_res(&self) -> Option<Res<NodeId>> {
+ (self.unresolved_segments == 0).then_some(self.base_res)
+ }
+
+ #[inline]
+ pub fn expect_full_res(&self) -> Res<NodeId> {
+ self.full_res().expect("unexpected unresolved segments")
+ }
}
/// Different kinds of symbols can coexist even if they share the same textual name.
@@ -606,7 +622,8 @@ impl<Id> Res<Id> {
Res::Local(..)
| Res::PrimTy(..)
- | Res::SelfTy { .. }
+ | Res::SelfTyParam { .. }
+ | Res::SelfTyAlias { .. }
| Res::SelfCtor(..)
| Res::ToolMod
| Res::NonMacroAttr(..)
@@ -629,7 +646,7 @@ impl<Id> Res<Id> {
Res::SelfCtor(..) => "self constructor",
Res::PrimTy(..) => "builtin type",
Res::Local(..) => "local variable",
- Res::SelfTy { .. } => "self type",
+ Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type",
Res::ToolMod => "tool module",
Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
Res::Err => "unresolved item",
@@ -652,7 +669,10 @@ impl<Id> Res<Id> {
Res::SelfCtor(id) => Res::SelfCtor(id),
Res::PrimTy(id) => Res::PrimTy(id),
Res::Local(id) => Res::Local(map(id)),
- Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
+ Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
+ Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
+ Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
+ }
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
@@ -665,7 +685,10 @@ impl<Id> Res<Id> {
Res::SelfCtor(id) => Res::SelfCtor(id),
Res::PrimTy(id) => Res::PrimTy(id),
Res::Local(id) => Res::Local(map(id)?),
- Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
+ Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
+ Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
+ Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
+ }
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
@@ -692,7 +715,9 @@ impl<Id> Res<Id> {
pub fn ns(&self) -> Option<Namespace> {
match self {
Res::Def(kind, ..) => kind.ns(),
- Res::PrimTy(..) | Res::SelfTy { .. } | Res::ToolMod => Some(Namespace::TypeNS),
+ Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => {
+ Some(Namespace::TypeNS)
+ }
Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
Res::Err => None,