From 1ae1c49c501f8c6baf662e0a8081280bb7a9e79c Mon Sep 17 00:00:00 2001 From: Kyle Matsuda Date: Mon, 16 Jan 2023 11:55:27 -0700 Subject: [PATCH] document EarlyBinder::subst_identity and skip_binder --- compiler/rustc_middle/src/ty/subst.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 5dc9e311bf6b1..3008c64199a11 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -538,6 +538,9 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List { /// Similar to [`super::Binder`] except that it tracks early bound generics, i.e. `struct Foo(T)` /// needs `T` substituted immediately. This type primarily exists to avoid forgetting to call /// `subst`. +/// +/// If you don't have anything to `subst`, you may be looking for +/// [`subst_identity`](EarlyBinder::subst_identity) or [`skip_binder`](EarlyBinder::skip_binder). #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Encodable, Decodable, HashStable)] pub struct EarlyBinder(pub T); @@ -578,6 +581,14 @@ impl EarlyBinder { EarlyBinder(value) } + /// Skips the binder and returns the "bound" value. + /// This can be used to extract data that does not depend on generic parameters + /// (e.g., getting the `DefId` of the inner value or getting the number of + /// arguments of an `FnSig`). Otherwise, consider using + /// [`subst_identity`](EarlyBinder::subst_identity). + /// + /// See also [`Binder::skip_binder`](super::Binder::skip_binder), which is + /// the analogous operation on [`super::Binder`]. pub fn skip_binder(self) -> T { self.0 } @@ -729,6 +740,14 @@ impl<'tcx, T: TypeFoldable<'tcx>> ty::EarlyBinder { self.0.fold_with(&mut folder) } + /// Makes the identity substitution `T0 => T0, ..., TN => TN`. + /// Conceptually, this converts universally bound variables into placeholders + /// when inside of a given item. + /// + /// For example, consider `for fn foo(){ .. }`: + /// - Outside of `foo`, `T` is bound (represented by the presence of `EarlyBinder`). + /// - Inside of the body of `foo`, we treat `T` as a placeholder by calling + /// `subst_identity` to discharge the `EarlyBinder`. pub fn subst_identity(self) -> T { self.0 }