-
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
Tracking issue for RFC 2289, "Associated type bounds" #52662
Comments
😕 How does it work? For instance while trait Tr {
type Assoc;
fn input(&self, assoc: &Self::Assoc);
fn output(&self) -> Self::Assoc;
}
let a: &Tr<Assoc: Debug> = ...;
let o = a.output(); // ???
a.input(&o); // ???
let b: &Tr<Assoc: Debug> = ...;
b.input(&o); // ?????????? |
@kennytm I think that while |
So I suppose we could parse |
@kennytm sounds reasonable. 👍 |
I haven't found any discussion about this: what about super trait bounds? In particular: whether other code can "rely" on it. Example (current Rust, Playground): trait Color {
type Channel;
}
trait CloneColor: Color
where
Self::Channel: Clone,
{}
fn foo<T: CloneColor>() {
let f = T::Channel::clone;
} This errors. While My question is: how would the following code behave? trait CloneColor: Color<Channel: Clone> {} Would it behave as the first code example or would other code now be able to deduce (I hope I'm not missing something obvious here) |
#44491 will likely change this :) (cc @scalexm)
Same as: trait CloneColor where Self: Color, <Self as Color>::Channel: Clone {}
Depends on whether you have implied bounds or not :) |
@Centril Thanks for the quick explanation! I didn't know implied bounds would change this too -- that's great! |
How does this interact with HRLB? I just discovered that trait aliases allow you to write the constraints required for working with async functions/closures, but could this be another way to do so? You can currently write: trait Foo<'a> = FnOnce<(&'a u8,)> where <Self as FnOnce<(&'a u8,)>>::Output: Future<Output = u8> + 'a;
fn foo<F: for<'a> Foo<'a>>(f: F) and presumably once this is implemented it could be: trait Foo<'a> = FnOnce<(&'a u8,), Output: Future<Output = u8> + 'a>;
fn foo<F: for<'a> Foo<'a>>(f: F) but can you go all the way to: fn foo<F: for<'a> FnOnce<(&'a u8,), Output: Future<Output = u8> + 'a>>(f: F) |
@Nemo157 When you write: where
Foo: for<'a> Bar<'a, Assoc: Bound> it should desugar into: where
Foo: for<'a> Bar<'a>,
for<'a> <Foo as Bar<'a>>::Assoc: Bound, However, rustc is generally unhappy with |
#63350 by @iluuu1994 & reviewed by @Centril fixed #61738. The standard library now uses ATBs in some places. This is further enhanced in #63584. |
… r=alexreg libcore: more cleanups using `#![feature(associated_type_bounds)]` Turns out this was indeed a bootstrapping issue from a test with `./x.py check` locally after rust-lang#63534 merged. Closes rust-lang#63393 r? @alexreg cc @iluuu1994 cc rust-lang#52662
… r=alexreg libcore: more cleanups using `#![feature(associated_type_bounds)]` Turns out this was indeed a bootstrapping issue from a test with `./x.py check` locally after rust-lang#63534 merged. Closes rust-lang#63393 r? @alexreg cc @iluuu1994 cc rust-lang#52662
… r=alexreg libcore: more cleanups using `#![feature(associated_type_bounds)]` Turns out this was indeed a bootstrapping issue from a test with `./x.py check` locally after rust-lang#63534 merged. Closes rust-lang#63393 r? @alexreg cc @iluuu1994 cc rust-lang#52662
… r=alexreg libcore: more cleanups using `#![feature(associated_type_bounds)]` Turns out this was indeed a bootstrapping issue from a test with `./x.py check` locally after rust-lang#63534 merged. Closes rust-lang#63393 r? @alexreg cc @iluuu1994 cc rust-lang#52662
This comment was marked as resolved.
This comment was marked as resolved.
This feature is tracked by [rust-lang/rust#52662][1]. Fixes `[ref:trait_constraints_on_associated_types_do_not_propagate]`. That is, when you have `C: ~const CfgTimer`, you don't need `C::System: KernelTimer` anymore. [1]: rust-lang/rust#52662
This comment was marked as off-topic.
This comment was marked as off-topic.
I assume that fully implementing this feature isn't very high priority, but what do people think in terms of marking this flag as incomplete, given the comment I posted earlier this year? I would offer to help with this but I'm not sure I'm aware of what's involved to do this. I'm also not sure where this is on the road map, but my assumption is it's lower than other planned features and no one's going to be working ensure this doesn't ambiguify (?) the existing trait behaviour for a while. |
Using a special keyword "effect", its possible to indicate that a type, function or trait is generic over a effect with the "rust way" of expressing generics. The effect keyword also has a role in the where clause, capable of specifing the keywords beeing generic (e.g. async, !async, ?async, const + ?async, etc) and the keyword bounds of traits in generic arguments. This design also takes into account possible syntax changes in other proposals and ideas. - [associated type bounds](rust-lang/rust#52662) - [return type notation](https://smallcultfollowing.com/babysteps/blog/2023/02/13/return-type-notation-send-bounds-part-2/)
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Tracking issues are impractical for discussions. I'm locking this issue. Please open new issues for problems and discuss the feature on zulip instead |
…li-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
…-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 is a tracking issue for the RFC "Associated type bounds of form
MyTrait<AssociatedType: Bounds>
" (rust-lang/rfcs#2289). The feature gate is#![feature(associated_type_bounds)]
.Steps:
Unresolved questions:
Does allowing this for
dyn
trait objects introduce any unforeseen issues? This can be resolved during stabilization.associated_type_bound
nested indyn
types #120719Resolve exact desugaring in the context of putting bounds on an associated type of a trait. See discussion in the RFC.
Consider nested lifetimes, https://gist.github.com/Centril/b0e62d31d4ae1849535c3e506e1fad64.
TODO:
Extend with tests in Implementation of RFC 2289 (associated_type_bounds) #57428 (comment).
associated_type_bounds
: errors with ambiguous associated type #61752The text was updated successfully, but these errors were encountered: