Skip to content

Commit 0bbf473

Browse files
committed
Auto merge of #82958 - camelid:res-docs, r=petrochenkov
Document `Res` and its friends I noticed [this Zulip conversation][z] and thought it would be a good idea to document `Res` and the other types near it. [z]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/.2382516.20-.20Add.20inherent.20associated.20types/near/227914819
2 parents 2118526 + 8563a19 commit 0bbf473

File tree

1 file changed

+142
-13
lines changed

1 file changed

+142
-13
lines changed

compiler/rustc_hir/src/def.rs

+142-13
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub enum CtorOf {
2020
Variant,
2121
}
2222

23+
/// What kind of constructor something is.
2324
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
2425
#[derive(HashStable_Generic)]
2526
pub enum CtorKind {
@@ -31,6 +32,7 @@ pub enum CtorKind {
3132
Fictive,
3233
}
3334

35+
/// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.
3436
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
3537
#[derive(HashStable_Generic)]
3638
pub enum NonMacroAttrKind {
@@ -47,33 +49,51 @@ pub enum NonMacroAttrKind {
4749
Registered,
4850
}
4951

52+
/// What kind of definition something is; e.g., `mod` vs `struct`.
5053
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
5154
#[derive(HashStable_Generic)]
5255
pub enum DefKind {
5356
// Type namespace
5457
Mod,
55-
/// Refers to the struct itself, `DefKind::Ctor` refers to its constructor if it exists.
58+
/// Refers to the struct itself, [`DefKind::Ctor`] refers to its constructor if it exists.
5659
Struct,
5760
Union,
5861
Enum,
59-
/// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists.
62+
/// Refers to the variant itself, [`DefKind::Ctor`] refers to its constructor if it exists.
6063
Variant,
6164
Trait,
62-
/// `type Foo = Bar;`
65+
/// Type alias: `type Foo = Bar;`
6366
TyAlias,
67+
/// Type from an `extern` block.
6468
ForeignTy,
69+
/// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
6570
TraitAlias,
71+
/// Associated type: `trait MyTrait { type Assoc; }`
6672
AssocTy,
73+
/// Type parameter: the `T` in `struct Vec<T> { ... }`
6774
TyParam,
6875

6976
// Value namespace
7077
Fn,
7178
Const,
79+
/// Constant generic parameter: `struct Foo<const N: usize> { ... }`
7280
ConstParam,
7381
Static,
7482
/// Refers to the struct or enum variant's constructor.
83+
///
84+
/// The reason `Ctor` exists in addition to [`DefKind::Struct`] and
85+
/// [`DefKind::Variant`] is because structs and enum variants exist
86+
/// in the *type* namespace, whereas struct and enum variant *constructors*
87+
/// exist in the *value* namespace.
88+
///
89+
/// You may wonder why enum variants exist in the type namespace as opposed
90+
/// to the value namespace. Check out [RFC 2593] for intuition on why that is.
91+
///
92+
/// [RFC 2593]: https://github.com/rust-lang/rfcs/pull/2593
7593
Ctor(CtorOf, CtorKind),
94+
/// Associated function: `impl MyStruct { fn associated() {} }`
7695
AssocFn,
96+
/// Associated constant: `trait MyTrait { const ASSOC: usize; }`
7797
AssocConst,
7898

7999
// Macro namespace
@@ -82,11 +102,16 @@ pub enum DefKind {
82102
// Not namespaced (or they are, but we don't treat them so)
83103
ExternCrate,
84104
Use,
105+
/// An `extern` block.
85106
ForeignMod,
107+
/// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`, or `const { 1 + 2}`
86108
AnonConst,
109+
/// Opaque type, aka `impl Trait`.
87110
OpaqueTy,
88111
Field,
112+
/// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
89113
LifetimeParam,
114+
/// A use of [`global_asm!`].
90115
GlobalAsm,
91116
Impl,
92117
Closure,
@@ -196,35 +221,130 @@ impl DefKind {
196221
}
197222

198223
/// The resolution of a path or export.
224+
///
225+
/// For every path or identifier in Rust, the compiler must determine
226+
/// what the path refers to. This process is called name resolution,
227+
/// and `Res` is the primary result of name resolution.
228+
///
229+
/// For example, everything prefixed with `/* Res */` in this example has
230+
/// an associated `Res`:
231+
///
232+
/// ```
233+
/// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
234+
/// /* Res */ String::from(/* Res */ s)
235+
/// }
236+
///
237+
/// /* Res */ str_to_string("hello");
238+
/// ```
239+
///
240+
/// The associated `Res`s will be:
241+
///
242+
/// - `str` will resolve to [`Res::PrimTy`];
243+
/// - `String` will resolve to [`Res::Def`], and the `Res` will include the [`DefId`]
244+
/// for `String` as defined in the standard library;
245+
/// - `String::from` will also resolve to [`Res::Def`], with the [`DefId`]
246+
/// pointing to `String::from`;
247+
/// - `s` will resolve to [`Res::Local`];
248+
/// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`]
249+
/// pointing to the definition of `str_to_string` in the current crate.
250+
//
199251
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
200252
#[derive(HashStable_Generic)]
201253
pub enum Res<Id = hir::HirId> {
254+
/// Definition having a unique ID (`DefId`), corresponds to something defined in user code.
255+
///
256+
/// **Not bound to a specific namespace.**
202257
Def(DefKind, DefId),
203258

204259
// Type namespace
260+
/// A primitive type such as `i32` or `str`.
261+
///
262+
/// **Belongs to the type namespace.**
205263
PrimTy(hir::PrimTy),
206-
/// `Self`, with both an optional trait and impl `DefId`.
264+
/// The `Self` type, optionally with the trait it is associated with
265+
/// and optionally with the [`DefId`] of the impl it is associated with.
266+
///
267+
/// **Belongs to the type namespace.**
268+
///
269+
/// For example, the `Self` in
207270
///
208-
/// HACK(min_const_generics): impl self types also have an optional requirement to not mention
271+
/// ```
272+
/// trait Foo {
273+
/// fn foo() -> Box<Self>;
274+
/// }
275+
/// ```
276+
///
277+
/// would have the [`DefId`] of `Foo` associated with it. The `Self` in
278+
///
279+
/// ```
280+
/// struct Bar;
281+
///
282+
/// impl Bar {
283+
/// fn new() -> Self { Bar }
284+
/// }
285+
/// ```
286+
///
287+
/// would have the [`DefId`] of the impl associated with it. Finally, the `Self` in
288+
///
289+
/// ```
290+
/// impl Foo for Bar {
291+
/// fn foo() -> Box<Self> { Box::new(Bar) }
292+
/// }
293+
/// ```
294+
///
295+
/// would have both the [`DefId`] of `Foo` and the [`DefId`] of the impl
296+
/// associated with it.
297+
///
298+
/// *See also [`Res::SelfCtor`].*
299+
///
300+
/// -----
301+
///
302+
/// HACK(min_const_generics): impl self types also have an optional requirement to **not** mention
209303
/// any generic parameters to allow the following with `min_const_generics`:
210-
/// ```rust
211-
/// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] {} }
304+
/// ```
305+
/// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
212306
/// ```
213307
/// We do however allow `Self` in repeat expression even if it is generic to not break code
214308
/// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint.
215309
///
216310
/// FIXME(lazy_normalization_consts): Remove this bodge once that feature is stable.
217-
SelfTy(Option<DefId> /* trait */, Option<(DefId, bool)> /* impl */),
218-
ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
311+
SelfTy(
312+
/// Optionally, the trait associated with this `Self` type.
313+
Option<DefId>,
314+
/// Optionally, the impl associated with this `Self` type.
315+
Option<(DefId, bool)>,
316+
),
317+
/// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
318+
///
319+
/// **Belongs to the type namespace.**
320+
ToolMod,
219321

220322
// Value namespace
221-
SelfCtor(DefId /* impl */), // `DefId` refers to the impl
323+
/// The `Self` constructor, along with the [`DefId`]
324+
/// of the impl it is associated with.
325+
///
326+
/// **Belongs to the value namespace.**
327+
///
328+
/// *See also [`Res::SelfTy`].*
329+
SelfCtor(DefId),
330+
/// A local variable or function parameter.
331+
///
332+
/// **Belongs to the value namespace.**
222333
Local(Id),
223334

224335
// Macro namespace
336+
/// An attribute that is *not* implemented via macro.
337+
/// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
338+
/// as opposed to `#[test]`, which is a builtin macro.
339+
///
340+
/// **Belongs to the macro namespace.**
225341
NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
226342

227343
// All namespaces
344+
/// Name resolution failed. We use a dummy `Res` variant so later phases
345+
/// of the compiler won't crash and can instead report more errors.
346+
///
347+
/// **Not bound to a specific namespace.**
228348
Err,
229349
}
230350

@@ -275,17 +395,26 @@ impl PartialRes {
275395
}
276396
}
277397

278-
/// Different kinds of symbols don't influence each other.
279-
///
280-
/// Therefore, they have a separate universe (namespace).
398+
/// Different kinds of symbols can coexist even if they share the same textual name.
399+
/// Therefore, they each have a separate universe (known as a "namespace").
281400
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
282401
pub enum Namespace {
402+
/// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s
403+
/// (and, by extension, crates).
404+
///
405+
/// Note that the type namespace includes other items; this is not an
406+
/// exhaustive list.
283407
TypeNS,
408+
/// The value namespace includes `fn`s, `const`s, `static`s, and local variables (including function arguments).
284409
ValueNS,
410+
/// The macro namespace includes `macro_rules!` macros, declarative `macro`s,
411+
/// procedural macros, attribute macros, `derive` macros, and non-macro attributes
412+
/// like `#[inline]` and `#[rustfmt::skip]`.
285413
MacroNS,
286414
}
287415

288416
impl Namespace {
417+
/// The English description of the namespace.
289418
pub fn descr(self) -> &'static str {
290419
match self {
291420
Self::TypeNS => "type",

0 commit comments

Comments
 (0)