Skip to content

Commit 21d94a3

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 3c85e56 + c63f3fe commit 21d94a3

File tree

95 files changed

+147
-533
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+147
-533
lines changed

compiler/rustc_ast/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#![doc(rust_logo)]
1212
#![allow(internal_features)]
1313
#![feature(rustdoc_internals)]
14-
#![feature(associated_type_bounds)]
14+
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
1515
#![feature(associated_type_defaults)]
1616
#![feature(box_patterns)]
1717
#![feature(if_let_guard)]

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -463,13 +463,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
463463
constraint.span,
464464
"return type notation is experimental"
465465
);
466-
} else {
467-
gate!(
468-
&self,
469-
associated_type_bounds,
470-
constraint.span,
471-
"associated type bounds are unstable"
472-
);
473466
}
474467
}
475468
visit::walk_assoc_constraint(self, constraint)
@@ -615,7 +608,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
615608
}
616609

617610
gate_all_legacy_dont_use!(trait_alias, "trait aliases are experimental");
618-
gate_all_legacy_dont_use!(associated_type_bounds, "associated type bounds are unstable");
619611
// Despite being a new feature, `where T: Trait<Assoc(): Sized>`, which is RTN syntax now,
620612
// used to be gated under associated_type_bounds, which are right above, so RTN needs to
621613
// be too.

compiler/rustc_borrowck/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#![feature(rustdoc_internals)]
55
#![doc(rust_logo)]
66
#![feature(assert_matches)]
7-
#![feature(associated_type_bounds)]
7+
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
88
#![feature(box_patterns)]
99
#![feature(control_flow_enum)]
1010
#![feature(let_chains)]

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
#![feature(
2020
rustc_private,
2121
decl_macro,
22-
associated_type_bounds,
2322
never_type,
2423
trusted_len,
2524
hash_raw_entry
2625
)]
26+
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
2727
#![allow(broken_intra_doc_links)]
2828
#![recursion_limit = "256"]
2929
#![warn(rust_2018_idioms)]

compiler/rustc_codegen_ssa/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#![allow(internal_features)]
55
#![allow(rustc::diagnostic_outside_of_impl)]
66
#![allow(rustc::untranslatable_diagnostic)]
7-
#![feature(associated_type_bounds)]
7+
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
88
#![feature(box_patterns)]
99
#![feature(if_let_guard)]
1010
#![feature(let_chains)]

compiler/rustc_error_codes/src/error_codes/E0719.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ An associated type value was specified more than once.
33
Erroneous code example:
44

55
```compile_fail,E0719
6-
#![feature(associated_type_bounds)]
7-
86
trait FooTrait {}
97
trait BarTrait {}
108
@@ -19,8 +17,6 @@ specify the associated type with the new trait.
1917
Corrected example:
2018

2119
```
22-
#![feature(associated_type_bounds)]
23-
2420
trait FooTrait {}
2521
trait BarTrait {}
2622
trait FooBarTrait: FooTrait + BarTrait {}

compiler/rustc_expand/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![doc(rust_logo)]
22
#![feature(rustdoc_internals)]
33
#![feature(array_windows)]
4-
#![feature(associated_type_bounds)]
4+
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
55
#![feature(associated_type_defaults)]
66
#![feature(if_let_guard)]
77
#![feature(let_chains)]

compiler/rustc_feature/src/accepted.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ declare_features! (
5959
(accepted, asm_sym, "1.66.0", Some(93333)),
6060
/// Allows the definition of associated constants in `trait` or `impl` blocks.
6161
(accepted, associated_consts, "1.20.0", Some(29646)),
62+
/// Allows the user of associated type bounds.
63+
(accepted, associated_type_bounds, "CURRENT_RUSTC_VERSION", Some(52662)),
6264
/// Allows using associated `type`s in `trait`s.
6365
(accepted, associated_types, "1.0.0", None),
6466
/// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.

compiler/rustc_feature/src/unstable.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,6 @@ declare_features! (
351351
(unstable, asm_unwind, "1.58.0", Some(93334)),
352352
/// Allows users to enforce equality of associated constants `TraitImpl<AssocConst=3>`.
353353
(unstable, associated_const_equality, "1.58.0", Some(92827)),
354-
/// Allows the user of associated type bounds.
355-
(unstable, associated_type_bounds, "1.34.0", Some(52662)),
356354
/// Allows associated type defaults.
357355
(unstable, associated_type_defaults, "1.2.0", Some(29661)),
358356
/// Allows `async || body` closures.

compiler/rustc_infer/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#![allow(internal_features)]
1919
#![allow(rustc::diagnostic_outside_of_impl)]
2020
#![allow(rustc::untranslatable_diagnostic)]
21-
#![feature(associated_type_bounds)]
21+
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
2222
#![feature(box_patterns)]
2323
#![feature(control_flow_enum)]
2424
#![feature(extend_one)]

0 commit comments

Comments
 (0)