From b6d4a4940bab85cc91eec70cc2e3096dd48da62d Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 17 May 2024 18:04:58 +0100 Subject: [PATCH] add a high level explanation, and remove a disclaimer (#1982) --- src/SUMMARY.md | 6 ++-- ...arly-late-bound-implementation-nuances.md} | 8 +---- .../early-late-bound-summary.md | 35 +++++++++++++++++++ .../turbofishing-and-early-late-bound.md | 0 src/early-late-bound-summary.md | 10 ------ 5 files changed, 39 insertions(+), 20 deletions(-) rename src/{what-does-early-late-bound-mean.md => early-late-bound-params/early-late-bound-implementation-nuances.md} (95%) create mode 100644 src/early-late-bound-params/early-late-bound-summary.md rename src/{ => early-late-bound-params}/turbofishing-and-early-late-bound.md (100%) delete mode 100644 src/early-late-bound-summary.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ad3146488b140..3eb80dec57c78 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -125,9 +125,9 @@ - [Which `ParamEnv` do I use?](./param_env/param_env_acquisition.md) - [Type inference](./type-inference.md) - [Trait solving](./traits/resolution.md) - - [Early and Late Bound Parameter Definitions](./early-late-bound-summary.md) - - [What are early and late bound parameters](./what-does-early-late-bound-mean.md) - - [Interactions with turbofishing](./turbofishing-and-early-late-bound.md) + - [Early and Late Bound Parameter Definitions](./early-late-bound-params/early-late-bound-summary.md) + - [Implementation nuances of early/late bound parameters](./early-late-bound-params/early-late-bound-implementation-nuances.md) + - [Interactions with turbofishing](./early-late-bound-params/turbofishing-and-early-late-bound.md) - [Higher-ranked trait bounds](./traits/hrtb.md) - [Caching subtleties](./traits/caching.md) - [Implied bounds](./traits/implied-bounds.md) diff --git a/src/what-does-early-late-bound-mean.md b/src/early-late-bound-params/early-late-bound-implementation-nuances.md similarity index 95% rename from src/what-does-early-late-bound-mean.md rename to src/early-late-bound-params/early-late-bound-implementation-nuances.md index ced07200a26fb..e1507f4295bf4 100644 --- a/src/what-does-early-late-bound-mean.md +++ b/src/early-late-bound-params/early-late-bound-implementation-nuances.md @@ -1,4 +1,4 @@ -# Early and Late Bound Parameter Definitions +# Early and Late Bound Parameter Implementation Nuances Understanding this page likely requires a rudimentary understanding of higher ranked trait bounds/`for<'a>`and also what types such as `dyn for<'a> Trait<'a>` and @@ -6,12 +6,6 @@ trait bounds/`for<'a>`and also what types such as `dyn for<'a> Trait<'a>` and on HRTB may be useful for understanding this syntax. The meaning of `for<'a> fn(&'a u32)` is incredibly similar to the meaning of `T: for<'a> Trait<'a>`. -If you are looking for information on the `RegionKind` variants `ReLateBound` and `ReEarlyBound` -you should look at the section on [bound vars and params](./bound-vars-and-params.md). This section -discusses what makes generic parameters on functions and closures late/early bound. Not the general -concept of bound vars and generic parameters which `RegionKind` has named somewhat confusingly -with this topic. - ## What does it mean for parameters to be early or late bound All function definitions conceptually have a ZST (this is represented by `TyKind::FnDef` in rustc). diff --git a/src/early-late-bound-params/early-late-bound-summary.md b/src/early-late-bound-params/early-late-bound-summary.md new file mode 100644 index 0000000000000..a4d823e66474d --- /dev/null +++ b/src/early-late-bound-params/early-late-bound-summary.md @@ -0,0 +1,35 @@ +# Early/Late bound parameters + +This section discusses what it means for generic parameters to be early or late bound. + +```rust +fn foo<'a, T>(b: &'a T) -> &'a T { b } +// ^^ ^early bound +// ^^ +// ^^late bound +``` + +Generally when referring to an item with generic parameters you must specify a list of generic arguments corresponding to the item's generic parameters. In +some cases it is permitted to elide these arguments but still, implicitly, a set of arguments are provided (i.e. `Vec::default()` desugars to `Vec::<_>::default()`). + +For functions this is not necessarily the case, for example if we take the function `foo` from the example above and write the following code: +```rust +fn main() { + let f = foo::<_>; + + let b = String::new(); + let c = String::new(); + + f(&b); + drop(b); + f(&c); +} +``` + +This code compiles perfectly fine even though there is no single lifetime that could possibly be specified in `foo::<_>` that would allow for both +the `&b` and `&c` borrows to be used as arguments (note: the `drop(b)` line forces the `&b` borrow to be shorter than the `&c` borrow). This works because +the `'a` lifetime is _late bound_. + +A generic parameter being late bound means that when we write `foo::<_>` we do not actually provide an argument for that parameter, instead we wait until _calling_ the function to provide the generic argument. In the above example this means that we are doing something like `f::<'_>(&b);` and `f::<'_>(&c);` (although in practice we do not actually support turbofishing late bound parameters in this manner) + +It may be helpful to think of "early bound parameter" or "late bound parameter" as meaning "early provided parameter" and "late provided parameter", i.e. we provide the argument to the parameter either early (when naming the function) or late (when calling it). \ No newline at end of file diff --git a/src/turbofishing-and-early-late-bound.md b/src/early-late-bound-params/turbofishing-and-early-late-bound.md similarity index 100% rename from src/turbofishing-and-early-late-bound.md rename to src/early-late-bound-params/turbofishing-and-early-late-bound.md diff --git a/src/early-late-bound-summary.md b/src/early-late-bound-summary.md deleted file mode 100644 index 223e2251d71ca..0000000000000 --- a/src/early-late-bound-summary.md +++ /dev/null @@ -1,10 +0,0 @@ -# Early/Late bound parameters - -This section discusses what it means for generic parameters to be early or late bound. - -```rust -fn foo<'a, T>(b: &'a u32) -> &'a u32 { a } -// ^^ ^early bound -// ^^ -// ^^late bound -``` \ No newline at end of file