Skip to content

Commit 058cec6

Browse files
authored
Merge pull request #2809 from khyperia/fix-2776
Explain how nested generic args are represented
2 parents 9d28335 + 383636a commit 058cec6

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

src/ty-module/generic-arguments.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,35 @@ For the `MyStruct<U>` written in the `Foo` type alias, we would represent it in
126126
- There would be an `AdtDef` (and corresponding `DefId`) for `MyStruct`.
127127
- There would be a `GenericArgs` containing the list `[GenericArgKind::Type(Ty(u32))]`
128128
- And finally a `TyKind::Adt` with the `AdtDef` and `GenericArgs` listed above.
129+
130+
## Nested generic args
131+
132+
```rust
133+
struct MyStruct<T>(T);
134+
135+
impl<T> MyStruct<T> {
136+
fn func<T2, T3>() {}
137+
}
138+
139+
fn main() {
140+
MyStruct::<u32>::func::<bool, char>();
141+
}
142+
```
143+
144+
The construct `MyStruct::<u32>::func::<bool, char>` is represented by a tuple: a DefId pointing at `func`, and then a
145+
`GenericArgs` list that "walks" all containing generic parameters - in this case, the list would be `[u32, bool, char]`.
146+
147+
The [`ty::Generics`] type (returned by the [`generics_of`] query) contains the information of how a nested hierarchy
148+
gets flattened down to a list, and lets you figure out which index in the `GenericArgs` list corresponds to which
149+
generic. The general theme of how it works is outermost to innermost (`T` before `T2` in the example), left to right
150+
(`T2` before `T3`), but there are several complications:
151+
152+
- Traits have an implicit `Self` generic parameter which is the first (i.e. 0th) generic parameter. Note that `Self` doesn't mean a generic parameter in all situations, see [Res::SelfTyAlias](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/enum.Res.html#variant.SelfTyAlias) and [Res::SelfCtor](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/enum.Res.html#variant.SelfCtor).
153+
- Only early-bound generic parameters are included, [late-bound generics] are not.
154+
- ... and more...
155+
156+
Check out [`ty::Generics`] for exact specifics on how the flattening works.
157+
158+
[`ty::Generics`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Generics.html
159+
[`generics_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.generics_of
160+
[late-bound generics]: ../early-late-parameters.md

0 commit comments

Comments
 (0)