Rollup merge of #68140 - ecstatic-morse:const-trait-bound-opt-out, r=oli-obk
Implement `?const` opt-out for trait bounds For now, such bounds are treated exactly the same as unprefixed ones in all contexts. [RFC 2632](https://github.com/rust-lang/rfcs/pull/2632) does not specify whether such bounds are forbidden outside of `const` contexts, so they are allowed at the moment. Prior to this PR, the constness of a trait bound/impl was stored in `TraitRef`. Now, the constness of an `impl` is stored in `ast::ItemKind::Impl` and the constness of a bound in `ast::TraitBoundModifer`. Additionally, constness of trait bounds is now stored in an additional field of `ty::Predicate::Trait`, and the combination of the constness of the item along with any `TraitBoundModifier` determines the constness of the bound in accordance with the RFC. Encoding the constness of impls at the `ty` level is left for a later PR. After a discussion in \#wg-grammar on Discord, it was decided that the grammar should not encode the mutual exclusivity of trait bound modifiers. The grammar for trait bound modifiers remains `[?const] [?]`. To encode this, I add a dummy variant to `ast::TraitBoundModifier` that is used when the syntax `?const ?` appears. This variant causes an error in AST validation and disappears during HIR lowering. cc #67794 r? @oli-obk
This commit is contained in:
commit
3484e2fab4
71 changed files with 495 additions and 311 deletions
|
|
@ -1,8 +1,8 @@
|
|||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/feature-gate.rs:11:29
|
||||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/feature-gate.rs:16:1
|
||||
|
|
||||
LL | const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
|
||||
| ^^^^^^^^
|
||||
LL | fn main() {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#![cfg_attr(gated, feature(const_trait_bound_opt_out))]
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
trait T {
|
||||
const CONST: i32;
|
||||
|
|
@ -10,6 +11,6 @@ trait T {
|
|||
|
||||
const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
|
||||
//[stock]~^ ERROR `?const` on trait bounds is experimental
|
||||
//[stock,gated]~^^ ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn main() {}
|
||||
#[rustc_error]
|
||||
fn main() {} //[gated]~ ERROR fatal error triggered by #[rustc_error]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0658]: `?const` on trait bounds is experimental
|
||||
--> $DIR/feature-gate.rs:11:29
|
||||
--> $DIR/feature-gate.rs:12:29
|
||||
|
|
||||
LL | const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
|
||||
| ^^^^^^
|
||||
|
|
@ -7,12 +7,6 @@ LL | const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
|
|||
= note: for more information, see https://github.com/rust-lang/rust/issues/67794
|
||||
= help: add `#![feature(const_trait_bound_opt_out)]` to the crate attributes to enable
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/feature-gate.rs:11:29
|
||||
|
|
||||
LL | const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
|||
|
|
@ -8,18 +8,14 @@ impl T for S {}
|
|||
|
||||
fn rpit() -> impl ?const T { S }
|
||||
//~^ ERROR `?const` is not permitted in `impl Trait`
|
||||
//~| ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn apit(_: impl ?const T) {}
|
||||
//~^ ERROR `?const` is not permitted in `impl Trait`
|
||||
//~| ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn rpit_assoc_bound() -> impl IntoIterator<Item: ?const T> { Some(S) }
|
||||
//~^ ERROR `?const` is not permitted in `impl Trait`
|
||||
//~| ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn apit_assoc_bound(_: impl IntoIterator<Item: ?const T>) {}
|
||||
//~^ ERROR `?const` is not permitted in `impl Trait`
|
||||
//~| ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -5,46 +5,22 @@ LL | fn rpit() -> impl ?const T { S }
|
|||
| ^^^^^^^^
|
||||
|
||||
error: `?const` is not permitted in `impl Trait`
|
||||
--> $DIR/in-impl-trait.rs:13:17
|
||||
--> $DIR/in-impl-trait.rs:12:17
|
||||
|
|
||||
LL | fn apit(_: impl ?const T) {}
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` is not permitted in `impl Trait`
|
||||
--> $DIR/in-impl-trait.rs:17:50
|
||||
--> $DIR/in-impl-trait.rs:15:50
|
||||
|
|
||||
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ?const T> { Some(S) }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` is not permitted in `impl Trait`
|
||||
--> $DIR/in-impl-trait.rs:21:48
|
||||
--> $DIR/in-impl-trait.rs:18:48
|
||||
|
|
||||
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ?const T>) {}
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/in-impl-trait.rs:9:19
|
||||
|
|
||||
LL | fn rpit() -> impl ?const T { S }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/in-impl-trait.rs:13:17
|
||||
|
|
||||
LL | fn apit(_: impl ?const T) {}
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/in-impl-trait.rs:17:50
|
||||
|
|
||||
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ?const T> { Some(S) }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/in-impl-trait.rs:21:48
|
||||
|
|
||||
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ?const T>) {}
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,5 @@
|
|||
trait Super {}
|
||||
trait T: ?const Super {}
|
||||
//~^ ERROR `?const` is not permitted in supertraits
|
||||
//~| ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,5 @@ error: `?const` is not permitted in supertraits
|
|||
LL | trait T: ?const Super {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/in-trait-bounds.rs:5:10
|
||||
|
|
||||
LL | trait T: ?const Super {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -9,14 +9,11 @@ impl T for S {}
|
|||
// An inherent impl for the trait object `?const T`.
|
||||
impl ?const T {}
|
||||
//~^ ERROR `?const` is not permitted in trait objects
|
||||
//~| ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn trait_object() -> &'static dyn ?const T { &S }
|
||||
//~^ ERROR `?const` is not permitted in trait objects
|
||||
//~| ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn trait_object_in_apit(_: impl IntoIterator<Item = Box<dyn ?const T>>) {}
|
||||
//~^ ERROR `?const` is not permitted in trait objects
|
||||
//~| ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -5,34 +5,16 @@ LL | impl ?const T {}
|
|||
| ^^^^^^^^
|
||||
|
||||
error: `?const` is not permitted in trait objects
|
||||
--> $DIR/in-trait-object.rs:14:35
|
||||
--> $DIR/in-trait-object.rs:13:35
|
||||
|
|
||||
LL | fn trait_object() -> &'static dyn ?const T { &S }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` is not permitted in trait objects
|
||||
--> $DIR/in-trait-object.rs:18:61
|
||||
--> $DIR/in-trait-object.rs:16:61
|
||||
|
|
||||
LL | fn trait_object_in_apit(_: impl IntoIterator<Item = Box<dyn ?const T>>) {}
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/in-trait-object.rs:10:6
|
||||
|
|
||||
LL | impl ?const T {}
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/in-trait-object.rs:14:35
|
||||
|
|
||||
LL | fn trait_object() -> &'static dyn ?const T { &S }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/in-trait-object.rs:18:61
|
||||
|
|
||||
LL | fn trait_object_in_apit(_: impl IntoIterator<Item = Box<dyn ?const T>>) {}
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,5 @@
|
|||
|
||||
struct S<T: ?const ?Sized>(std::marker::PhantomData<T>);
|
||||
//~^ ERROR `?const` and `?` are mutually exclusive
|
||||
//~| ERROR `?const` on trait bounds is not yet implemented
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,5 @@ error: `?const` and `?` are mutually exclusive
|
|||
LL | struct S<T: ?const ?Sized>(std::marker::PhantomData<T>);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: `?const` on trait bounds is not yet implemented
|
||||
--> $DIR/with-maybe-sized.rs:4:13
|
||||
|
|
||||
LL | struct S<T: ?const ?Sized>(std::marker::PhantomData<T>);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
// compile-flags: -Z parse-only
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_bound_opt_out)]
|
||||
#![allow(incomplete_features)]
|
||||
|
|
@ -8,7 +6,12 @@
|
|||
struct S;
|
||||
trait T {}
|
||||
|
||||
impl const S {}
|
||||
//~^ ERROR inherent impls cannot be `const`
|
||||
//~| ERROR const trait impls are not yet implemented
|
||||
|
||||
impl const T {}
|
||||
//~^ ERROR `const` cannot modify an inherent impl
|
||||
//~^ ERROR inherent impls cannot be `const`
|
||||
//~| ERROR const trait impls are not yet implemented
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,30 @@
|
|||
error: `const` cannot modify an inherent impl
|
||||
--> $DIR/inherent-impl.rs:11:6
|
||||
error: inherent impls cannot be `const`
|
||||
--> $DIR/inherent-impl.rs:9:1
|
||||
|
|
||||
LL | impl const S {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: only trait implementations may be annotated with `const`
|
||||
|
||||
error: inherent impls cannot be `const`
|
||||
--> $DIR/inherent-impl.rs:13:1
|
||||
|
|
||||
LL | impl const T {}
|
||||
| ^^^^^
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: only a trait impl can be `const`
|
||||
= note: only trait implementations may be annotated with `const`
|
||||
|
||||
error: aborting due to previous error
|
||||
error: const trait impls are not yet implemented
|
||||
--> $DIR/inherent-impl.rs:9:1
|
||||
|
|
||||
LL | impl const S {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: const trait impls are not yet implemented
|
||||
--> $DIR/inherent-impl.rs:13:1
|
||||
|
|
||||
LL | impl const T {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue