Document Res
and its friends
This commit is contained in:
parent
3a5d45f68c
commit
8563a19384
1 changed files with 143 additions and 14 deletions
|
@ -20,6 +20,7 @@ pub enum CtorOf {
|
||||||
Variant,
|
Variant,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// What kind of constructor something is.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
||||||
#[derive(HashStable_Generic)]
|
#[derive(HashStable_Generic)]
|
||||||
pub enum CtorKind {
|
pub enum CtorKind {
|
||||||
|
@ -31,6 +32,7 @@ pub enum CtorKind {
|
||||||
Fictive,
|
Fictive,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
||||||
#[derive(HashStable_Generic)]
|
#[derive(HashStable_Generic)]
|
||||||
pub enum NonMacroAttrKind {
|
pub enum NonMacroAttrKind {
|
||||||
|
@ -47,33 +49,51 @@ pub enum NonMacroAttrKind {
|
||||||
Registered,
|
Registered,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// What kind of definition something is; e.g., `mod` vs `struct`.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
||||||
#[derive(HashStable_Generic)]
|
#[derive(HashStable_Generic)]
|
||||||
pub enum DefKind {
|
pub enum DefKind {
|
||||||
// Type namespace
|
// Type namespace
|
||||||
Mod,
|
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,
|
Struct,
|
||||||
Union,
|
Union,
|
||||||
Enum,
|
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,
|
Variant,
|
||||||
Trait,
|
Trait,
|
||||||
/// `type Foo = Bar;`
|
/// Type alias: `type Foo = Bar;`
|
||||||
TyAlias,
|
TyAlias,
|
||||||
|
/// Type from an `extern` block.
|
||||||
ForeignTy,
|
ForeignTy,
|
||||||
|
/// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
|
||||||
TraitAlias,
|
TraitAlias,
|
||||||
|
/// Associated type: `trait MyTrait { type Assoc; }`
|
||||||
AssocTy,
|
AssocTy,
|
||||||
|
/// Type parameter: the `T` in `struct Vec<T> { ... }`
|
||||||
TyParam,
|
TyParam,
|
||||||
|
|
||||||
// Value namespace
|
// Value namespace
|
||||||
Fn,
|
Fn,
|
||||||
Const,
|
Const,
|
||||||
|
/// Constant generic parameter: `struct Foo<const N: usize> { ... }`
|
||||||
ConstParam,
|
ConstParam,
|
||||||
Static,
|
Static,
|
||||||
/// Refers to the struct or enum variant's constructor.
|
/// 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),
|
Ctor(CtorOf, CtorKind),
|
||||||
|
/// Associated function: `impl MyStruct { fn associated() {} }`
|
||||||
AssocFn,
|
AssocFn,
|
||||||
|
/// Associated constant: `trait MyTrait { const ASSOC: usize; }`
|
||||||
AssocConst,
|
AssocConst,
|
||||||
|
|
||||||
// Macro namespace
|
// Macro namespace
|
||||||
|
@ -82,11 +102,16 @@ pub enum DefKind {
|
||||||
// Not namespaced (or they are, but we don't treat them so)
|
// Not namespaced (or they are, but we don't treat them so)
|
||||||
ExternCrate,
|
ExternCrate,
|
||||||
Use,
|
Use,
|
||||||
|
/// An `extern` block.
|
||||||
ForeignMod,
|
ForeignMod,
|
||||||
|
/// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`, or `const { 1 + 2}`
|
||||||
AnonConst,
|
AnonConst,
|
||||||
|
/// Opaque type, aka `impl Trait`.
|
||||||
OpaqueTy,
|
OpaqueTy,
|
||||||
Field,
|
Field,
|
||||||
|
/// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
|
||||||
LifetimeParam,
|
LifetimeParam,
|
||||||
|
/// A use of [`global_asm!`].
|
||||||
GlobalAsm,
|
GlobalAsm,
|
||||||
Impl,
|
Impl,
|
||||||
Closure,
|
Closure,
|
||||||
|
@ -196,35 +221,130 @@ impl DefKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The resolution of a path or export.
|
/// 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(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
||||||
#[derive(HashStable_Generic)]
|
#[derive(HashStable_Generic)]
|
||||||
pub enum Res<Id = hir::HirId> {
|
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),
|
Def(DefKind, DefId),
|
||||||
|
|
||||||
// Type namespace
|
// Type namespace
|
||||||
PrimTy(hir::PrimTy),
|
/// A primitive type such as `i32` or `str`.
|
||||||
/// `Self`, with both an optional trait and impl `DefId`.
|
|
||||||
///
|
///
|
||||||
/// HACK(min_const_generics): impl self types also have an optional requirement to not mention
|
/// **Belongs to the type namespace.**
|
||||||
|
PrimTy(hir::PrimTy),
|
||||||
|
/// 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
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// 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`:
|
/// 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
|
/// 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.
|
/// 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.
|
/// FIXME(lazy_normalization_consts): Remove this bodge once that feature is stable.
|
||||||
SelfTy(Option<DefId> /* trait */, Option<(DefId, bool)> /* impl */),
|
SelfTy(
|
||||||
ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
|
/// 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
|
// 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),
|
Local(Id),
|
||||||
|
|
||||||
// Macro namespace
|
// 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]`
|
NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
|
||||||
|
|
||||||
// All namespaces
|
// 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,
|
Err,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,17 +395,26 @@ impl PartialRes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Different kinds of symbols don't influence each other.
|
/// 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").
|
||||||
/// Therefore, they have a separate universe (namespace).
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
pub enum Namespace {
|
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,
|
TypeNS,
|
||||||
|
/// The value namespace includes `fn`s, `const`s, `static`s, and local variables (including function arguments).
|
||||||
ValueNS,
|
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,
|
MacroNS,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Namespace {
|
impl Namespace {
|
||||||
|
/// The English description of the namespace.
|
||||||
pub fn descr(self) -> &'static str {
|
pub fn descr(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::TypeNS => "type",
|
Self::TypeNS => "type",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue