]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_hir/src/def.rs
Rollup merge of #84531 - Smittyvb:foo-not-feature, r=Mark-Simulacrum
[rust.git] / compiler / rustc_hir / src / def.rs
index a81eb747a335a48de92e185d6c698b90806af56b..de10d88c1d250b8e6e6462a2e3fc0b8e2b3b96c6 100644 (file)
@@ -20,6 +20,7 @@ pub enum CtorOf {
     Variant,
 }
 
+/// What kind of constructor something is.
 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum CtorKind {
@@ -31,6 +32,7 @@ pub enum CtorKind {
     Fictive,
 }
 
+/// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.
 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum NonMacroAttrKind {
@@ -47,33 +49,51 @@ pub enum NonMacroAttrKind {
     Registered,
 }
 
+/// What kind of definition something is; e.g., `mod` vs `struct`.
 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum DefKind {
     // Type namespace
     Mod,
-    /// Refers to the struct itself, `DefKind::Ctor` refers to its constructor if it exists.
+    /// Refers to the struct itself, [`DefKind::Ctor`] refers to its constructor if it exists.
     Struct,
     Union,
     Enum,
-    /// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists.
+    /// Refers to the variant itself, [`DefKind::Ctor`] refers to its constructor if it exists.
     Variant,
     Trait,
-    /// `type Foo = Bar;`
+    /// Type alias: `type Foo = Bar;`
     TyAlias,
+    /// Type from an `extern` block.
     ForeignTy,
+    /// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
     TraitAlias,
+    /// Associated type: `trait MyTrait { type Assoc; }`
     AssocTy,
+    /// Type parameter: the `T` in `struct Vec<T> { ... }`
     TyParam,
 
     // Value namespace
     Fn,
     Const,
+    /// Constant generic parameter: `struct Foo<const N: usize> { ... }`
     ConstParam,
     Static,
     /// Refers to the struct or enum variant's constructor.
+    ///
+    /// The reason `Ctor` exists in addition to [`DefKind::Struct`] and
+    /// [`DefKind::Variant`] is because structs and enum variants exist
+    /// in the *type* namespace, whereas struct and enum variant *constructors*
+    /// exist in the *value* namespace.
+    ///
+    /// You may wonder why enum variants exist in the type namespace as opposed
+    /// to the value namespace. Check out [RFC 2593] for intuition on why that is.
+    ///
+    /// [RFC 2593]: https://github.com/rust-lang/rfcs/pull/2593
     Ctor(CtorOf, CtorKind),
+    /// Associated function: `impl MyStruct { fn associated() {} }`
     AssocFn,
+    /// Associated constant: `trait MyTrait { const ASSOC: usize; }`
     AssocConst,
 
     // Macro namespace
@@ -82,11 +102,16 @@ pub enum DefKind {
     // Not namespaced (or they are, but we don't treat them so)
     ExternCrate,
     Use,
+    /// An `extern` block.
     ForeignMod,
+    /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`, or `const { 1 + 2}`
     AnonConst,
+    /// Opaque type, aka `impl Trait`.
     OpaqueTy,
     Field,
+    /// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
     LifetimeParam,
+    /// A use of [`global_asm!`].
     GlobalAsm,
     Impl,
     Closure,
@@ -196,35 +221,130 @@ pub fn ns(&self) -> Option<Namespace> {
 }
 
 /// The resolution of a path or export.
+///
+/// For every path or identifier in Rust, the compiler must determine
+/// what the path refers to. This process is called name resolution,
+/// and `Res` is the primary result of name resolution.
+///
+/// For example, everything prefixed with `/* Res */` in this example has
+/// an associated `Res`:
+///
+/// ```
+/// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
+///     /* Res */ String::from(/* Res */ s)
+/// }
+///
+/// /* Res */ str_to_string("hello");
+/// ```
+///
+/// The associated `Res`s will be:
+///
+/// - `str` will resolve to [`Res::PrimTy`];
+/// - `String` will resolve to [`Res::Def`], and the `Res` will include the [`DefId`]
+///   for `String` as defined in the standard library;
+/// - `String::from` will also resolve to [`Res::Def`], with the [`DefId`]
+///   pointing to `String::from`;
+/// - `s` will resolve to [`Res::Local`];
+/// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`]
+///   pointing to the definition of `str_to_string` in the current crate.
+//
 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum Res<Id = hir::HirId> {
+    /// Definition having a unique ID (`DefId`), corresponds to something defined in user code.
+    ///
+    /// **Not bound to a specific namespace.**
     Def(DefKind, DefId),
 
     // Type namespace
+    /// A primitive type such as `i32` or `str`.
+    ///
+    /// **Belongs to the type namespace.**
     PrimTy(hir::PrimTy),
-    /// `Self`, with both an optional trait and impl `DefId`.
+    /// The `Self` type, optionally with the trait it is associated with
+    /// and optionally with the [`DefId`] of the impl it is associated with.
+    ///
+    /// **Belongs to the type namespace.**
+    ///
+    /// For example, the `Self` in
     ///
-    /// HACK(min_const_generics): impl self types also have an optional requirement to not mention
+    /// ```
+    /// trait Foo {
+    ///     fn foo() -> Box<Self>;
+    /// }
+    /// ```
+    ///
+    /// would have the [`DefId`] of `Foo` associated with it. The `Self` in
+    ///
+    /// ```
+    /// struct Bar;
+    ///
+    /// impl Bar {
+    ///     fn new() -> Self { Bar }
+    /// }
+    /// ```
+    ///
+    /// would have the [`DefId`] of the impl associated with it. Finally, the `Self` in
+    ///
+    /// ```
+    /// impl Foo for Bar {
+    ///     fn foo() -> Box<Self> { Box::new(Bar) }
+    /// }
+    /// ```
+    ///
+    /// would have both the [`DefId`] of `Foo` and the [`DefId`] of the impl
+    /// associated with it.
+    ///
+    /// *See also [`Res::SelfCtor`].*
+    ///
+    /// -----
+    ///
+    /// HACK(min_const_generics): impl self types also have an optional requirement to **not** mention
     /// any generic parameters to allow the following with `min_const_generics`:
-    /// ```rust
-    /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] {} }
+    /// ```
+    /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
     /// ```
     /// 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.
     ///
     /// FIXME(lazy_normalization_consts): Remove this bodge once that feature is stable.
-    SelfTy(Option<DefId> /* trait */, Option<(DefId, bool)> /* impl */),
-    ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
+    SelfTy(
+        /// Optionally, the trait associated with this `Self` type.
+        Option<DefId>,
+        /// Optionally, the impl associated with this `Self` type.
+        Option<(DefId, bool)>,
+    ),
+    /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
+    ///
+    /// **Belongs to the type namespace.**
+    ToolMod,
 
     // Value namespace
-    SelfCtor(DefId /* impl */), // `DefId` refers to the impl
+    /// The `Self` constructor, along with the [`DefId`]
+    /// of the impl it is associated with.
+    ///
+    /// **Belongs to the value namespace.**
+    ///
+    /// *See also [`Res::SelfTy`].*
+    SelfCtor(DefId),
+    /// A local variable or function parameter.
+    ///
+    /// **Belongs to the value namespace.**
     Local(Id),
 
     // Macro namespace
+    /// An attribute that is *not* implemented via macro.
+    /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
+    /// as opposed to `#[test]`, which is a builtin macro.
+    ///
+    /// **Belongs to the macro namespace.**
     NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
 
     // All namespaces
+    /// Name resolution failed. We use a dummy `Res` variant so later phases
+    /// of the compiler won't crash and can instead report more errors.
+    ///
+    /// **Not bound to a specific namespace.**
     Err,
 }
 
@@ -275,17 +395,26 @@ pub fn unresolved_segments(&self) -> usize {
     }
 }
 
-/// Different kinds of symbols don't influence each other.
-///
-/// Therefore, they have a separate universe (namespace).
+/// Different kinds of symbols can coexist even if they share the same textual name.
+/// Therefore, they each have a separate universe (known as a "namespace").
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 pub enum Namespace {
+    /// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s
+    /// (and, by extension, crates).
+    ///
+    /// Note that the type namespace includes other items; this is not an
+    /// exhaustive list.
     TypeNS,
+    /// The value namespace includes `fn`s, `const`s, `static`s, and local variables (including function arguments).
     ValueNS,
+    /// The macro namespace includes `macro_rules!` macros, declarative `macro`s,
+    /// procedural macros, attribute macros, `derive` macros, and non-macro attributes
+    /// like `#[inline]` and `#[rustfmt::skip]`.
     MacroNS,
 }
 
 impl Namespace {
+    /// The English description of the namespace.
     pub fn descr(self) -> &'static str {
         match self {
             Self::TypeNS => "type",