-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Stabilize associated type bounds (RFC 2289) #122055
Conversation
ae9d4ca
to
a450e96
Compare
This comment has been minimized.
This comment has been minimized.
a450e96
to
a5fb53e
Compare
Some changes occurred in compiler/rustc_codegen_gcc |
r? types |
Thank you to @compiler-errors and everyone else who has worked on this! It's wonderful seeing this brought to the point of stabilization. I know many people's fingers keep expecting that this already works. :) @rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:
No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
@rfcbot reviewed |
For implementation history, its probably worth pointing out the PRs I made around the bound var refactoring. Its important in understanding how those are captured. All in all though, I'm happy to see this stabilized. I also think its important to point out that other than in where clauses, you can't currently write these bounds, because they are more like the "ensures" clauses than the existing "where" clauses and thus have different effects on implied bounds. |
Feel free to edit and add more commits to the impl history section, since I don't know which ones you're talking about specifically. If they don't have to do with ATB specifically, maybe also leave a little note beside them that talks about how it impacts the impls?
Yep. I pointed this out a bit in the document. See "The latter three are not expressible in surface Rust", "however, the bound on the associated item is implied whenever the trait is used". Perhaps ping me if you'd like to request additions to this stabilization doc to make this more clear. |
@rfcbot reviewed |
I sort of had naively assumed that this would already work: trait Foo {
type Bar: Iterator
where
<Self::Bar as Iterator>::Item: Display;
} but rather it just causes an overflow when evaluating an impl. Should it work and be equivalent to |
Keep in mind that item bounds on associated types are not equivalent to where clauses in general, i.e. trait Foo {
type Assoc: Iterator;
}
// is not:
trait Foo {
type Assoc
where
Self::Assoc: Iterator;
} They differ in what is implied and what is required to be proven: trait Foo {
type Assoc
where
Self::Assoc: Iterator;
}
fn foo<T: Foo>(xs: T::Assoc) {
//~^ ERROR `<T as Foo>::Assoc` is not an iterator
for x in xs {}
} If we wanted to collect such bounds and make them implied, we certainly could, though. But currently, we don't collect item bounds from the After the PR #120752 lands, a possible way to express this bound would be putting the trait Foo
where
<Self::Bar as Iterator>::Item: Display,
{
type Bar: Iterator;
} However, given this stabilization is forwards-compatible with #120752, I'd really rather not block this on that, or any other extensions of implied bounds. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
☀️ Test successful - checks-actions |
Finished benchmarking commit (21d94a3): 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)ResultsThis 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: 669.42s -> 670.018s (0.09%) |
associated_type_bounds stabilized in Rust 1.79. rust-lang/rust#122055
…ound, r=compiler-errors Suggest associated type bounds on problematic associated equality bounds Fixes rust-lang#105056. TL;DR: Suggest `Trait<Ty: Bound>` on `Trait<Ty = Bound>` in Rust >=2021. ~~Blocked on rust-lang#122055 (stabilization of `associated_type_bounds`), I'd say.~~ (merged)
Rollup merge of rust-lang#122120 - fmease:sugg-assoc-ty-bound-on-eq-bound, r=compiler-errors Suggest associated type bounds on problematic associated equality bounds Fixes rust-lang#105056. TL;DR: Suggest `Trait<Ty: Bound>` on `Trait<Ty = Bound>` in Rust >=2021. ~~Blocked on rust-lang#122055 (stabilization of `associated_type_bounds`), I'd say.~~ (merged)
Now that associated type bounds are stabilized in rustc (see rust-lang/rust#122055), we can remove the workaround used in the IP crate to put filtering constraints on the device ID type. Change-Id: I80a9d6ce9553ff64f5f7a209dccb26d667a1753b Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1055952 Fuchsia-Auto-Submit: Peter Johnston <peterjohnston@google.com> Reviewed-by: Bruno Dal Bo <brunodalbo@google.com> Commit-Queue: Auto-Submit <auto-submit@fuchsia-infra.iam.gserviceaccount.com>
Now that associated type bounds are stabilized in rustc (see rust-lang/rust#122055), we can remove the workaround used in the IP crate to put filtering constraints on the device ID type. Change-Id: I80a9d6ce9553ff64f5f7a209dccb26d667a1753b Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1055952 Fuchsia-Auto-Submit: Peter Johnston <peterjohnston@google.com> Reviewed-by: Bruno Dal Bo <brunodalbo@google.com> Commit-Queue: Auto-Submit <auto-submit@fuchsia-infra.iam.gserviceaccount.com>
…4107) # Objective The bounds for query iterators are quite intimidating. ## Solution With Rust 1.79, [associated type bounds](rust-lang/rust#122055) stabilized, which can simplify the bounds slightly.
…vyengine#14107) # Objective The bounds for query iterators are quite intimidating. ## Solution With Rust 1.79, [associated type bounds](rust-lang/rust#122055) stabilized, which can simplify the bounds slightly.
…vyengine#14107) # Objective The bounds for query iterators are quite intimidating. ## Solution With Rust 1.79, [associated type bounds](rust-lang/rust#122055) stabilized, which can simplify the bounds slightly.
…-obk Stabilize associated type bounds (RFC 2289) This PR stabilizes associated type bounds, which were laid out in [RFC 2289]. This gives us a shorthand to express nested type bounds that would otherwise need to be expressed with nested `impl Trait` or broken into several `where` clauses. ### What are we stabilizing? We're stabilizing the associated item bounds syntax, which allows us to put bounds in associated type position within other bounds, i.e. `T: Trait<Assoc: Bounds...>`. See [RFC 2289] for motivation. In all position, the associated type bound syntax expands into a set of two (or more) bounds, and never anything else (see "How does this differ[...]" section for more info). Associated type bounds are stabilized in four positions: * **`where` clauses (and APIT)** - This is equivalent to breaking up the bound into two (or more) `where` clauses. For example, `where T: Trait<Assoc: Bound>` is equivalent to `where T: Trait, <T as Trait>::Assoc: Bound`. * **Supertraits** - Similar to above, `trait CopyIterator: Iterator<Item: Copy> {}`. This is almost equivalent to breaking up the bound into two (or more) `where` clauses; however, the bound on the associated item is implied whenever the trait is used. See rust-lang#112573/rust-lang#112629. * **Associated type item bounds** - This allows constraining the *nested* rigid projections that are associated with a trait's associated types. e.g. `trait Trait { type Assoc: Trait2<Assoc2: Copy>; }`. * **opaque item bounds (RPIT, TAIT)** - This allows constraining associated types that are associated with the opaque without having to *name* the opaque. For example, `impl Iterator<Item: Copy>` defines an iterator whose item is `Copy` without having to actually name that item bound. The latter three are not expressible in surface Rust (though for associated type item bounds, this will change in rust-lang#120752, which I don't believe should block this PR), so this does represent a slight expansion of what can be expressed in trait bounds. ### How does this differ from the RFC? Compared to the RFC, the current implementation *always* desugars associated type bounds to sets of `ty::Clause`s internally. Specifically, it does *not* introduce a position-dependent desugaring as laid out in [RFC 2289], and in particular: * It does *not* desugar to anonymous associated items in associated type item bounds. * It does *not* desugar to nested RPITs in RPIT bounds, nor nested TAITs in TAIT bounds. This position-dependent desugaring laid out in the RFC existed simply to side-step limitations of the trait solver, which have mostly been fixed in rust-lang#120584. The desugaring laid out in the RFC also added unnecessary complication to the design of the feature, and introduces its own limitations to, for example: * Conditionally lowering to nested `impl Trait` in certain positions such as RPIT and TAIT means that we inherit the limitations of RPIT/TAIT, namely lack of support for higher-ranked opaque inference. See this code example: rust-lang#120752 (comment). * Introducing anonymous associated types makes traits no longer object safe, since anonymous associated types are not nameable, and all associated types must be named in `dyn` types. This last point motivates why this PR is *not* stabilizing support for associated type bounds in `dyn` types, e.g, `dyn Assoc<Item: Bound>`. Why? Because `dyn` types need to have *concrete* types for all associated items, this would necessitate a distinct lowering for associated type bounds, which seems both complicated and unnecessary compared to just requiring the user to write `impl Trait` themselves. See rust-lang#120719. ### Implementation history: Limited to the significant behavioral changes and fixes and relevant PRs, ping me if I left something out-- * rust-lang#57428 * rust-lang#108063 * rust-lang#110512 * rust-lang#112629 * rust-lang#120719 * rust-lang#120584 Closes rust-lang#52662 [RFC 2289]: https://rust-lang.github.io/rfcs/2289-associated-type-bounds.html
This PR stabilizes associated type bounds, which were laid out in RFC 2289. This gives us a shorthand to express nested type bounds that would otherwise need to be expressed with nested
impl Trait
or broken into severalwhere
clauses.What are we stabilizing?
We're stabilizing the associated item bounds syntax, which allows us to put bounds in associated type position within other bounds, i.e.
T: Trait<Assoc: Bounds...>
. See RFC 2289 for motivation.In all position, the associated type bound syntax expands into a set of two (or more) bounds, and never anything else (see "How does this differ[...]" section for more info).
Associated type bounds are stabilized in four positions:
where
clauses (and APIT) - This is equivalent to breaking up the bound into two (or more)where
clauses. For example,where T: Trait<Assoc: Bound>
is equivalent towhere T: Trait, <T as Trait>::Assoc: Bound
.trait CopyIterator: Iterator<Item: Copy> {}
. This is almost equivalent to breaking up the bound into two (or more)where
clauses; however, the bound on the associated item is implied whenever the trait is used. See Should associated type bounds on supertraits be implied? #112573/Make associated type bounds in supertrait position implied #112629.trait Trait { type Assoc: Trait2<Assoc2: Copy>; }
.impl Iterator<Item: Copy>
defines an iterator whose item isCopy
without having to actually name that item bound.The latter three are not expressible in surface Rust (though for associated type item bounds, this will change in #120752, which I don't believe should block this PR), so this does represent a slight expansion of what can be expressed in trait bounds.
How does this differ from the RFC?
Compared to the RFC, the current implementation always desugars associated type bounds to sets of
ty::Clause
s internally. Specifically, it does not introduce a position-dependent desugaring as laid out in RFC 2289, and in particular:This position-dependent desugaring laid out in the RFC existed simply to side-step limitations of the trait solver, which have mostly been fixed in #120584. The desugaring laid out in the RFC also added unnecessary complication to the design of the feature, and introduces its own limitations to, for example:
impl Trait
in certain positions such as RPIT and TAIT means that we inherit the limitations of RPIT/TAIT, namely lack of support for higher-ranked opaque inference. See this code example: Collect relevant item bounds from trait clauses for nested rigid projections #120752 (comment).dyn
types.This last point motivates why this PR is not stabilizing support for associated type bounds in
dyn
types, e.g,dyn Assoc<Item: Bound>
. Why? Becausedyn
types need to have concrete types for all associated items, this would necessitate a distinct lowering for associated type bounds, which seems both complicated and unnecessary compared to just requiring the user to writeimpl Trait
themselves. See #120719.Implementation history:
Limited to the significant behavioral changes and fixes and relevant PRs, ping me if I left something out--
associated_type_bound
nested indyn
types #120719associated_type_bounds
feature #120584Closes #52662