Skip to content

Commit b6679c0

Browse files
committed
Auto merge of rust-lang#122055 - compiler-errors:stabilize-atb, r=oli-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
2 parents 68f4157 + e0fca7a commit b6679c0

File tree

3 files changed

+3
-3
lines changed

3 files changed

+3
-3
lines changed

alloc/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,12 @@
173173
//
174174
// Language features:
175175
// tidy-alphabetical-start
176+
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
176177
#![cfg_attr(not(test), feature(coroutine_trait))]
177178
#![cfg_attr(test, feature(panic_update_hook))]
178179
#![cfg_attr(test, feature(test))]
179180
#![feature(allocator_internals)]
180181
#![feature(allow_internal_unstable)]
181-
#![feature(associated_type_bounds)]
182182
#![feature(c_unwind)]
183183
#![feature(cfg_sanitize)]
184184
#![feature(const_mut_refs)]

alloc/tests/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
12
#![feature(allocator_api)]
23
#![feature(alloc_layout_extra)]
34
#![feature(iter_array_chunks)]
@@ -22,7 +23,6 @@
2223
#![feature(try_reserve_kind)]
2324
#![feature(try_with_capacity)]
2425
#![feature(unboxed_closures)]
25-
#![feature(associated_type_bounds)]
2626
#![feature(binary_heap_into_iter_sorted)]
2727
#![feature(binary_heap_drain_sorted)]
2828
#![feature(slice_ptr_get)]

core/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@
203203
//
204204
// Language features:
205205
// tidy-alphabetical-start
206+
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
206207
#![cfg_attr(bootstrap, feature(diagnostic_namespace))]
207208
#![cfg_attr(bootstrap, feature(exhaustive_patterns))]
208209
#![cfg_attr(bootstrap, feature(platform_intrinsics))]
@@ -213,7 +214,6 @@
213214
#![feature(allow_internal_unsafe)]
214215
#![feature(allow_internal_unstable)]
215216
#![feature(asm_const)]
216-
#![feature(associated_type_bounds)]
217217
#![feature(auto_traits)]
218218
#![feature(c_unwind)]
219219
#![feature(cfg_sanitize)]

0 commit comments

Comments
 (0)