Skip to content

Commit 2c7d051

Browse files
committed
sembr src/ty-module/param-ty-const-regions.md
1 parent acb9dfa commit 2c7d051

1 file changed

Lines changed: 18 additions & 9 deletions

File tree

src/ty-module/param-ty-const-regions.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Parameter `Ty`/`Const`/`Region`s
22

3-
When inside of generic items, types can be written that use in scope generic parameters, for example `fn foo<'a, T>(_: &'a Vec<T>)`. In this specific case
4-
the `&'a Vec<T>` type would be represented internally as:
3+
When inside of generic items, types can be written that use in scope generic parameters, for example `fn foo<'a, T>(_: &'a Vec<T>)`.
4+
In this specific case the `&'a Vec<T>` type would be represented internally as:
55
```
66
TyKind::Ref(
77
RegionKind::LateParam(DefId(foo), DefId(foo::'a), "'a"),
@@ -29,8 +29,10 @@ struct Foo<T>(Vec<T>);
2929
```
3030
The `Vec<T>` type is represented as `TyKind::Adt(Vec, &[GenericArgKind::Type(Param("T", 0))])`.
3131

32-
The name is somewhat self explanatory, it's the name of the type parameter. The index of the type parameter is an integer indicating
33-
its order in the list of generic parameters in scope (note: this includes parameters defined on items on outer scopes than the item the parameter is defined on). Consider the following examples:
32+
The name is somewhat self explanatory, it's the name of the type parameter.
33+
The index of the type parameter is an integer indicating
34+
its order in the list of generic parameters in scope (note: this includes parameters defined on items on outer scopes than the item the parameter is defined on).
35+
Consider the following examples:
3436

3537
```rust,ignore
3638
struct Foo<A, B> {
@@ -49,25 +51,32 @@ impl<X, Y> Foo<X, Y> {
4951
}
5052
```
5153

52-
Concretely given the `ty::Generics` for the item the parameter is defined on, if the index is `2` then starting from the root `parent`, it will be the third parameter to be introduced. For example in the above example, `Z` has index `2` and is the third generic parameter to be introduced, starting from the `impl` block.
54+
Concretely given the `ty::Generics` for the item the parameter is defined on, if the index is `2` then starting from the root `parent`, it will be the third parameter to be introduced.
55+
For example in the above example, `Z` has index `2` and is the third generic parameter to be introduced, starting from the `impl` block.
5356

5457
The index fully defines the `Ty` and is the only part of `TyKind::Param` that matters for reasoning about the code we are compiling.
5558

56-
Generally we do not care what the name is and only use the index. The name is included for diagnostics and debug logs as otherwise it would be
59+
Generally we do not care what the name is and only use the index.
60+
The name is included for diagnostics and debug logs as otherwise it would be
5761
incredibly difficult to understand the output, i.e. `Vec<Param(0)>: Sized` vs `Vec<T>: Sized`. In debug output, parameter types are
5862
often printed out as `{name}/#{index}`, for example in the function `foo` if we were to debug print `Vec<T>` it would be written as `Vec<T/#0>`.
5963

60-
An alternative representation would be to only have the name, however using an index is more efficient as it means we can index into `GenericArgs` when instantiating generic parameters with some arguments. We would otherwise have to store `GenericArgs` as a `HashMap<Symbol, GenericArg>` and do a hashmap lookup everytime we used a generic item.
64+
An alternative representation would be to only have the name, however using an index is more efficient as it means we can index into `GenericArgs` when instantiating generic parameters with some arguments.
65+
We would otherwise have to store `GenericArgs` as a `HashMap<Symbol, GenericArg>` and do a hashmap lookup everytime we used a generic item.
6166

6267
In theory an index would also allow for having multiple distinct parameters that use the same name, e.g.
6368
`impl<A> Foo<A> { fn bar<A>() { .. } }`.
6469
The rules against shadowing make this difficult but those language rules could change in the future.
6570

6671
### Lifetime parameters
6772

68-
In contrast to `Ty`/`Const`'s `Param` singular `Param` variant, lifetimes have two variants for representing region parameters: [`RegionKind::EarlyParam`] and [`RegionKind::LateParam`]. The reason for this is due to function's distinguishing between [early and late bound parameters][ch_early_late_bound] which is discussed in an earlier chapter (see link).
73+
In contrast to `Ty`/`Const`'s `Param` singular `Param` variant, lifetimes have two variants for representing region parameters: [`RegionKind::EarlyParam`] and [`RegionKind::LateParam`].
74+
The reason for this is due to function's distinguishing between [early and late bound parameters][ch_early_late_bound] which is discussed in an earlier chapter (see link).
6975

70-
`RegionKind::EarlyParam` is structured identically to `Ty/Const`'s `Param` variant, it is simply a `u32` index and a `Symbol`. For lifetime parameters defined on non-function items we always use `ReEarlyParam`. For functions we use `ReEarlyParam` for any early bound parameters and `ReLateParam` for any late bound parameters. Note that just like `Ty` and `Const` params we often debug format them as `'SYMBOL/#INDEX`, see for example:
76+
`RegionKind::EarlyParam` is structured identically to `Ty/Const`'s `Param` variant, it is simply a `u32` index and a `Symbol`.
77+
For lifetime parameters defined on non-function items we always use `ReEarlyParam`.
78+
For functions we use `ReEarlyParam` for any early bound parameters and `ReLateParam` for any late bound parameters.
79+
Note that just like `Ty` and `Const` params we often debug format them as `'SYMBOL/#INDEX`, see for example:
7180

7281
```rust,ignore
7382
// This function would have its signature represented as:

0 commit comments

Comments
 (0)