Implement AST -> HIR generics propagation in delegation#151864
Implement AST -> HIR generics propagation in delegation#151864aerooneqq wants to merge 21 commits intorust-lang:mainfrom
Conversation
|
HIR ty lowering was modified cc @fmease |
This comment has been minimized.
This comment has been minimized.
|
would it be possible to split this pr to commits? |
@aerooneqq is sitting in the same office with me, we'll figure out how to review this better. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
94fa69b to
a6d9e63
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
a6d9e63 to
9033bc5
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
9033bc5 to
b398a09
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
9744189 to
558b07d
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
| #![allow(incomplete_features)] | ||
| #![allow(warnings)] | ||
|
|
||
| mod test_1 { |
There was a problem hiding this comment.
One line/sentence comments for all test cases
| //@ run-pass | ||
| #![feature(fn_delegation)] | ||
| #![allow(incomplete_features)] | ||
| #![allow(warnings)] |
| @@ -0,0 +1,2 @@ | |||
| mod delegation; | |||
| mod generics; | |||
There was a problem hiding this comment.
mod generics could be added to the old compiler/rustc_ast_lowering/src/delegation.rs
|
@aerooneqq Also, the test changes are better submitted as a separate PR to make this PR smaller, and to make snapshot of the current treatment of all those examples. |
|
We are not sure that doing all this at AST -> HIR lowering stage is the right place, doing it at ty level may be better, then we'll need to leave stubs in In any case we plan to merge this, and then possibly rework later, because the delegation logic is mostly contained in delegation.rs files and doesn't affect other parts of the compiler much, so it won't bother other people significantly. |
|
Reminder, once the PR becomes ready for a review, use |
|
☔ The latest upstream changes (presumably #152904) made this pull request unmergeable. Please resolve the merge conflicts. |
…tests, r=petrochenkov Add tests for delegation generics This PR adds tests from rust-lang#151864 as discussed in this [comment](rust-lang#151864 (comment)). Part of rust-lang#118212. The majority of new tests are added in `mapping` folder, (`ast-hir-engine` folder in rust-lang#151864), those tests test mapping between generic params of delegee and our generated function for delegation (that is why the name of the folder was changed, I think it better reflects what those tests testing). In each mapping test comments were added to each test case and one comment describing the goal of mapping tests was added at the top of each file. Next, tests for defaults in generic params (`generic-params-defaults.rs`), params with the same name (`generic-params-same-names`), errors in providing user-specified generic args (`generics-gen-args-errors.rs`) and wrong signature of a generated function in impl trait case (`impl-trait-wrong-args-count.rs`, renamed from `wrong-args-count-ice.rs` in rust-lang#151864). `generic-aux-pass.rs` test was not added, as all reuses in this test produce known ICE `DefId::expect_local DefId(..) isn't local` rust-lang#143498 (which will be fixed in rust-lang#151864, however it will not close mentioned issue, as synthetic generic params are not yet supported in new generics implementation). r? @petrochenkov
Rollup merge of #152907 - aerooneqq:delegation-generics-new-tests, r=petrochenkov Add tests for delegation generics This PR adds tests from #151864 as discussed in this [comment](#151864 (comment)). Part of #118212. The majority of new tests are added in `mapping` folder, (`ast-hir-engine` folder in #151864), those tests test mapping between generic params of delegee and our generated function for delegation (that is why the name of the folder was changed, I think it better reflects what those tests testing). In each mapping test comments were added to each test case and one comment describing the goal of mapping tests was added at the top of each file. Next, tests for defaults in generic params (`generic-params-defaults.rs`), params with the same name (`generic-params-same-names`), errors in providing user-specified generic args (`generics-gen-args-errors.rs`) and wrong signature of a generated function in impl trait case (`impl-trait-wrong-args-count.rs`, renamed from `wrong-args-count-ice.rs` in #151864). `generic-aux-pass.rs` test was not added, as all reuses in this test produce known ICE `DefId::expect_local DefId(..) isn't local` #143498 (which will be fixed in #151864, however it will not close mentioned issue, as synthetic generic params are not yet supported in new generics implementation). r? @petrochenkov
…petrochenkov Add tests for delegation generics This PR adds tests from rust-lang/rust#151864 as discussed in this [comment](rust-lang/rust#151864 (comment)). Part of rust-lang/rust#118212. The majority of new tests are added in `mapping` folder, (`ast-hir-engine` folder in rust-lang/rust#151864), those tests test mapping between generic params of delegee and our generated function for delegation (that is why the name of the folder was changed, I think it better reflects what those tests testing). In each mapping test comments were added to each test case and one comment describing the goal of mapping tests was added at the top of each file. Next, tests for defaults in generic params (`generic-params-defaults.rs`), params with the same name (`generic-params-same-names`), errors in providing user-specified generic args (`generics-gen-args-errors.rs`) and wrong signature of a generated function in impl trait case (`impl-trait-wrong-args-count.rs`, renamed from `wrong-args-count-ice.rs` in rust-lang/rust#151864). `generic-aux-pass.rs` test was not added, as all reuses in this test produce known ICE `DefId::expect_local DefId(..) isn't local` rust-lang/rust#143498 (which will be fixed in rust-lang/rust#151864, however it will not close mentioned issue, as synthetic generic params are not yet supported in new generics implementation). r? @petrochenkov
This PR adds support for generics propagation during AST -> HIR lowering and is a part of #118212.
High-level design overview
Motivation
The task is to generate generics for delegations (i.e. in this context we assume a function that is created for
reusestatements) during AST -> HIR lowering. Then we want to propagate those generated params to generated method call (or default call) in delegation. This will help to solve issues like the following:Moreover, user can specify generic args in
reuse, we need to propagate them (works now) and inherit signature with substituted generic args:In this case we want the delegation to have signature that have one
i32parameter (notTparameter).Considering all other cases, for now we want to preserve existing behavior, which was almost fully done (at this stage there are changes in behavior of delegations with placeholders and late-bound lifetimes).
Main approach overview
The main approach is as follows:
reusestatement (i.e.reuse Trait::<'static, i32, 123>::foo::<String>) we either generate delegee generic params or not. If not, then we should include user-specified generic args into the signature of delegation,[DELEGEE PARENT LIFETIMES, DELEGEE LIFETIMES, DELEGEE PARENT TYPES AND CONSTS, DELEGEE TYPES AND CONSTS],Selfgeneric param):'a: 'ain order to preserve all lifetimes in HIR, so for now we can generate more lifetimes params then needed. This will be partially fixed in one of next pull requests.Implementation details
generics_ofoftcx. Next, as we want to generate new generic params we generate new node ids for them, remove default types and then invoke already existent routine for lowering AST generic params into HIR,hir_analysispart, where user-specified args are obtained, then lowered through existing API and then used during signature and predicates inheritance,reuse Trait::<String>::foo), next we use those generic args and mapping for delegee parent and child generic params into those args in order to fold delegee signature and delegee predicates.Tests
New tests were developed and can be found in
ast-hir-enginefolder, those tests cover all cases of delegation with different number of lifetimes, types, consts in generic params and different user-specified args cases (parent and child, parent/child only, none).Edge cases
There are some edge cases worth mentioning.
Free to trait delegation.
Consider this example:
As we are reusing from trait and delegee has
&selfparam it means that delegation must haveSelfgeneric param:We inherit predicates from Self implicit generic param in
Trait, thus we can pass to delegation anything that implements this trait. Now, consider the case when user explicitly specifies parent generic args.In this case we do not need to generate parent generic params, but we still need to generate
Selfin delegation (DelegationGenerics::SelfAndUserSpecifiedvariant):User-specified generic arguments should be used to replace parent generic params in delegation, so if we had param of type
Tinfoo, during signature inheritance we should replace it with user-specifiedStringtype.impl trait delegation
When we delegate from impl trait to something, we want the delegation to have signature that matches signature in trait. For this reason we already resolve delegation not to the actual delegee but to the trait method in order to inherit its signature. That is why when processing user-specified args when the caller kind is
impl trait(FnKind::AssocTraitImpl), we discard parent user-specified args and replace them with those that are specified in trait header. In future we will also discardchild_argsbut we need proper error handling for this case, so it will be addressed in one of future pull requests that are approximately specified in "Nearest future work" section.Nearest future work (approximate future pull requests):
impl Traitparams in functionsFix diagnostics duplication during lowering of user-specified typesreuse <u8 as Trait<_>>::foo as generic_arguments2reuse Trait::<_, _>::foo::<_>r? @petrochenkov