-
Notifications
You must be signed in to change notification settings - Fork 581
Explain how nested generic args are represented #2809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -126,3 +126,35 @@ For the `MyStruct<U>` written in the `Foo` type alias, we would represent it in | |
| - There would be an `AdtDef` (and corresponding `DefId`) for `MyStruct`. | ||
| - There would be a `GenericArgs` containing the list `[GenericArgKind::Type(Ty(u32))]` | ||
| - And finally a `TyKind::Adt` with the `AdtDef` and `GenericArgs` listed above. | ||
|
|
||
| ## Nested generic args | ||
|
|
||
| ```rust | ||
| struct MyStruct<T>(T); | ||
|
|
||
| impl<T> MyStruct<T> { | ||
| fn func<T2, T3>() {} | ||
| } | ||
|
|
||
| fn main() { | ||
| MyStruct::<u32>::func::<bool, char>(); | ||
| } | ||
| ``` | ||
|
|
||
| The construct `MyStruct::<u32>::func::<bool, char>` is represented by a tuple: a DefId pointing at `func`, and then a | ||
| `GenericArgs` list that "walks" all containing generic parameters - in this case, the list would be `[u32, bool, char]`. | ||
|
|
||
| The [`ty::Generics`] type (returned by the [`generics_of`] query) contains the information of how a nested hierarchy | ||
| gets flattened down to a list, and lets you figure out which index in the `GenericArgs` list corresponds to which | ||
| generic. The general theme of how it works is outermost to innermost (`T` before `T2` in the example), left to right | ||
| (`T2` before `T3`), but there are several complications: | ||
|
|
||
| - 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). | ||
| - Only early-bound generic parameters are included, [late-bound generics] are not. | ||
BoxyUwU marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - ... and more... | ||
|
|
||
| Check out [`ty::Generics`] for exact specifics on how the flattening works. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think ideally there would be something better we could link but I'm not sure off the top of my head if such a place exists. |
||
|
|
||
| [`ty::Generics`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Generics.html | ||
|
Comment on lines
+156
to
+158
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see any info about flattening here. Where did you get all this info from?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, for example, is some details about how the flattening happens |
||
| [`generics_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.generics_of | ||
| [late-bound generics]: ../early-late-parameters.md | ||
Uh oh!
There was an error while loading. Please reload this page.