-
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
(Re-)Implement impl_trait_in_bindings
#134185
(Re-)Implement impl_trait_in_bindings
#134185
Conversation
@bors try @rust-timer queue |
Some changes occurred in match lowering cc @Nadrieril Some changes occurred in src/tools/clippy cc @rust-lang/clippy HIR ty lowering was modified cc @fmease |
This comment has been minimized.
This comment has been minimized.
⌛ Trying commit f84b2f6 with merge 917c884c739f8b62081dbc8e34bb112bab0f248f... |
…gs, r=<try> (Re-)Implement `impl_trait_in_bindings` This reimplements the `impl_trait_in_bindings` feature for local bindings. "`impl Trait` in bindings" serve as a form of *trait* ascription, where the type basically functions as an infer var but additionally registering the `impl Trait`'s trait bounds for the infer type. These trait bounds can be used to enforce that predicates hold, and can guide inference (e.g. for closure signature inference): ```rust let _: impl Fn(&u8) -> &u8 = |x| x; ``` They are implemented as an additional set of bounds that are registered when the type is lowered during typeck, and then these bounds are tied to a given `CanonicalUserTypeAscription` for borrowck. We enforce these `CanonicalUserTypeAscription` bounds during borrowck to make sure that the `impl Trait` types are sensitive to lifetimes: ```rust trait Static: 'static {} impl<T> Static for T where T: 'static {} let local = 1; let x: impl Static = &local; //~^ ERROR `local` does not live long enough ``` r? oli-obk cc rust-lang#63065 --- Why can't we just use TAIT inference or something? Well, TAITs in bodies have the problem that they cannot reference lifetimes local to a body. For example: ```rust type TAIT = impl Display; let local = 0; let x: TAIT = &local; //~^ ERROR `local` does not live long enough ``` That's because TAITs requires us to do *opaque type inference* which is pretty strict, since we need to remap all of the lifetimes of the hidden type to universal regions. This is simply not possible here. --- I consider this part of the "impl trait everywhere" experiment. I'm not certain if this needs yet another lang team experiment.
f84b2f6
to
7ea56c5
Compare
@rust-timer build 917c884 |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (917c884): comparison URL. Overall result: no relevant changes - no action neededBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results (primary 0.4%, secondary -4.6%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 771.021s -> 769.24s (-0.23%) |
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.
A difference to APIT is that impl Trait<impl Debug>
is allowed. r=me with a test for that added
We should definitely not allow that, ill check and add test and maybe fix it |
7ea56c5
to
3bbdc9e
Compare
Added a test which confirms that we deny |
@bors r=oli-obk |
☔ The latest upstream changes (presumably #134269) made this pull request unmergeable. Please resolve the merge conflicts. |
3bbdc9e
to
d714a22
Compare
@bors r=oli-obk |
☀️ Test successful - checks-actions |
Finished benchmarking commit (f5079d0): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results (primary -1.8%, secondary -2.1%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 768.74s -> 769.535s (0.10%) |
This reimplements the
impl_trait_in_bindings
feature for local bindings."
impl Trait
in bindings" serve as a form of trait ascription, where the type basically functions as an infer var but additionally registering theimpl Trait
's trait bounds for the infer type. These trait bounds can be used to enforce that predicates hold, and can guide inference (e.g. for closure signature inference):They are implemented as an additional set of bounds that are registered when the type is lowered during typeck, and then these bounds are tied to a given
CanonicalUserTypeAscription
for borrowck. We enforce theseCanonicalUserTypeAscription
bounds during borrowck to make sure that theimpl Trait
types are sensitive to lifetimes:r? oli-obk
cc #63065
Why can't we just use TAIT inference or something? Well, TAITs in bodies have the problem that they cannot reference lifetimes local to a body. For example:
That's because TAITs requires us to do opaque type inference which is pretty strict, since we need to remap all of the lifetimes of the hidden type to universal regions. This is simply not possible here.
I consider this part of the "impl trait everywhere" experiment. I'm not certain if this needs yet another lang team experiment.