From 9931782a38ad717961c9dd9d92934b3504526d84 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 3 Nov 2021 11:12:39 -0700 Subject: [PATCH] Document how recursion is handled for `ty::Ty` Based on this forum discussion: https://internals.rust-lang.org/t/recursive-type-representation-in-rustc/15235/4 --- compiler/rustc_middle/src/ty/adt.rs | 24 ++++++++++++++++++++++++ compiler/rustc_middle/src/ty/mod.rs | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 44f741c5df1..61764f9f0a9 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -64,6 +64,30 @@ bitflags! { /// Moreover, Rust only allows recursive data types through indirection. /// /// [adt]: https://en.wikipedia.org/wiki/Algebraic_data_type +/// +/// # Recursive types +/// +/// It may seem impossible to represent recursive types using [`Ty`], +/// since [`TyKind::Adt`] includes [`AdtDef`], which includes its fields, +/// creating a cycle. However, `AdtDef` does not actually include the *types* +/// of its fields; it includes just their [`DefId`]s. +/// +/// [`TyKind::Adt`]: ty::TyKind::Adt +/// +/// For example, the following type: +/// +/// ``` +/// struct S { x: Box } +/// ``` +/// +/// is essentially represented with [`Ty`] as the following pseudocode: +/// +/// ``` +/// struct S { x } +/// ``` +/// +/// where `x` here represents the `DefId` of `S.x`. Then, the `DefId` +/// can be used with [`TyCtxt::type_of()`] to get the type of the field. pub struct AdtDef { /// The `DefId` of the struct, enum or union item. pub did: DefId, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cf47da157d1..d162578dd00 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1700,7 +1700,7 @@ impl ReprOptions { impl<'tcx> FieldDef { /// Returns the type of this field. The resulting type is not normalized. The `subst` is - /// typically obtained via the second field of `TyKind::AdtDef`. + /// typically obtained via the second field of [`TyKind::Adt`]. pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> { tcx.type_of(self.did).subst(tcx, subst) }