-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
chalk lowering rule: ProjectionEq-Normalize #52153
Conversation
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.
src/librustc_traits/lowering.rs
Outdated
let trait_ref = tcx.impl_trait_ref(trait_id).unwrap(); | ||
|
||
// `U` | ||
let ty = tcx.type_of(item_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think this will work, what we want to do is to introduce a new type parameter U
. Not sure how to do that (probably through tcx.mk_ty_param
), I’ll try and get back to you for more guidance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so as you can see in the description of the rule, we want the output to be something like:
ProjectionEq(<Self as Trait>::Item = U) :- Normalize(<Self as Trait>::Item = U)
where U
is a new type variable. This could be done naively by having:
// add a type param at depth `0`
let ty = tcx.mk_ty_param(0, Symbol::intern(“U”).as_interned_str());
however as you can see, rustc refers to a type param with a depth index and an explicit name (here “U”), instead of referring to all parameters by using indices only. Hence if the name U
is already taken, as in:
trait Foo<U> {
#[rustc_dump_program_clauses]
type Item;
}
then the output clause will be wrong as it will use the same parameter U
for two unrelated things.
A possible fix would be to choose U
whenever this name is not already in use, and in case it is used just choose a random name which is not already in use. Another possible fix would be two Binder
layers instead of only one, as I think type parameters can have the same name if they are not at the same depth. I’ll confer with niko.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm so the problem here is that rustc doesn't really support this yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can leave this as a kind of FIXME for now
src/librustc_traits/lowering.rs
Outdated
let trait_ref = tcx.impl_trait_ref(trait_id).unwrap(); | ||
|
||
// `U` | ||
let ty = tcx.type_of(item_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so as you can see in the description of the rule, we want the output to be something like:
ProjectionEq(<Self as Trait>::Item = U) :- Normalize(<Self as Trait>::Item = U)
where U
is a new type variable. This could be done naively by having:
// add a type param at depth `0`
let ty = tcx.mk_ty_param(0, Symbol::intern(“U”).as_interned_str());
however as you can see, rustc refers to a type param with a depth index and an explicit name (here “U”), instead of referring to all parameters by using indices only. Hence if the name U
is already taken, as in:
trait Foo<U> {
#[rustc_dump_program_clauses]
type Item;
}
then the output clause will be wrong as it will use the same parameter U
for two unrelated things.
A possible fix would be to choose U
whenever this name is not already in use, and in case it is used just choose a random name which is not already in use. Another possible fix would be two Binder
layers instead of only one, as I think type parameters can have the same name if they are not at the same depth. I’ll confer with niko.
@scalexm thank you, Your instructions will be addressed soon. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@csmoe I think that’s good now! cc @nikomatsakis, what do you think of the FIXME? |
Ping from triage @nikomatsakis! This PR needs your review. |
Ping from triage @nikomatsakis / @rust-lang/compiler: This PR requires your review. |
Ping from triage @rust-lang/compiler / @nikomatsakis: This PR requires your review. |
I propose that we wait for rustc to handle quantification over types, once this is done it should be almost trivial to finish this PR. |
☔ The latest upstream changes (presumably #54969) made this pull request unmergeable. Please resolve the merge conflicts. |
3723239
to
e853d6c
Compare
📌 Commit e853d6c has been approved by |
☀️ Test successful - status-appveyor, status-travis |
Tested on commit rust-lang/rust@126a0e2. Direct link to PR: <rust-lang/rust#52153> 🎉 rls on windows: test-fail → test-pass (cc @nrc @Xanewok, @rust-lang/infra).
cc #49177
r? @scalexm