From 5da1a04278ffddfb9252ee4a0eb9b1f19738673d Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 15 Dec 2022 00:51:34 +0000 Subject: [PATCH 1/2] Allow `impl ~const Trait` opaque types --- .../rustc_ast_passes/src/ast_validation.rs | 8 +---- .../const-impl-trait.rs | 34 ++++++++++++++++++ .../tilde-const-invalid-places.rs | 17 --------- .../tilde-const-invalid-places.stderr | 36 ++----------------- 4 files changed, 37 insertions(+), 58 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-impl-trait.rs diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index eb9c841d80c16..55ea12d25ea2c 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -42,7 +42,6 @@ enum SelfSemantic { /// What is the context that prevents using `~const`? enum DisallowTildeConstContext<'a> { TraitObject, - ImplTrait, Fn(FnKind<'a>), } @@ -187,11 +186,7 @@ impl<'a> AstValidator<'a> { fn with_impl_trait(&mut self, outer: Option, f: impl FnOnce(&mut Self)) { let old = mem::replace(&mut self.outer_impl_trait, outer); - if outer.is_some() { - self.with_banned_tilde_const(DisallowTildeConstContext::ImplTrait, f); - } else { - f(self); - } + f(self); self.outer_impl_trait = old; } @@ -1384,7 +1379,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { let mut err = self.err_handler().struct_span_err(bound.span(), "`~const` is not allowed here"); match reason { DisallowTildeConstContext::TraitObject => err.note("trait objects cannot have `~const` trait bounds"), - DisallowTildeConstContext::ImplTrait => err.note("`impl Trait`s cannot have `~const` trait bounds"), DisallowTildeConstContext::Fn(FnKind::Closure(..)) => err.note("closures cannot have `~const` trait bounds"), DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => err.span_note(ident.span, "this function is not `const`, so it cannot have `~const` trait bounds"), }; diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-trait.rs new file mode 100644 index 0000000000000..2059f6d79a573 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-trait.rs @@ -0,0 +1,34 @@ +// check-pass +#![feature(associated_type_bounds, const_trait_impl, const_cmp)] + +use std::marker::Destruct; + +const fn cmp(a: &impl ~const PartialEq) -> bool { + a == a +} + +const fn wrap(x: impl ~const PartialEq + ~const Destruct) -> impl ~const PartialEq + ~const Destruct { + x +} + +const _: () = { + assert!(cmp(&0xDEADBEEFu32)); + assert!(cmp(&())); + assert!(wrap(123) == wrap(123)); + assert!(wrap(123) != wrap(456)); +}; + +#[const_trait] +trait T {} +struct S; +impl const T for S {} + +const fn rpit() -> impl ~const T { S } + +const fn apit(_: impl ~const T + ~const Destruct) {} + +const fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } + +const fn apit_assoc_bound(_: impl IntoIterator + ~const Destruct) {} + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs index 5bd52151f42ac..95f7aaba0fc38 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs @@ -1,23 +1,6 @@ #![feature(const_trait_impl)] #![feature(associated_type_bounds)] -#[const_trait] -trait T {} -struct S; -impl T for S {} - -fn rpit() -> impl ~const T { S } -//~^ ERROR `~const` is not allowed - -fn apit(_: impl ~const T) {} -//~^ ERROR `~const` is not allowed - -fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } -//~^ ERROR `~const` is not allowed - -fn apit_assoc_bound(_: impl IntoIterator) {} -//~^ ERROR `~const` is not allowed - struct TildeQuestion(std::marker::PhantomData); //~^ ERROR `~const` and `?` are mutually exclusive diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index 84867cb4a5342..d20f146df3f1a 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -1,40 +1,8 @@ -error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:9:19 - | -LL | fn rpit() -> impl ~const T { S } - | ^^^^^^^^ - | - = note: `impl Trait`s cannot have `~const` trait bounds - -error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:12:17 - | -LL | fn apit(_: impl ~const T) {} - | ^^^^^^^^ - | - = note: `impl Trait`s cannot have `~const` trait bounds - -error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:15:50 - | -LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } - | ^^^^^^^^ - | - = note: `impl Trait`s cannot have `~const` trait bounds - -error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:18:48 - | -LL | fn apit_assoc_bound(_: impl IntoIterator) {} - | ^^^^^^^^ - | - = note: `impl Trait`s cannot have `~const` trait bounds - error: `~const` and `?` are mutually exclusive - --> $DIR/tilde-const-invalid-places.rs:21:25 + --> $DIR/tilde-const-invalid-places.rs:4:25 | LL | struct TildeQuestion(std::marker::PhantomData); | ^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to previous error From a8b9e00518aef62e20ff2ab79801d200c869ea8f Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 15 Dec 2022 14:17:38 +0000 Subject: [PATCH 2/2] fix tidy and add rpitit test --- .../const-impl-trait.rs | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-trait.rs index 2059f6d79a573..0622f96e70d81 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-trait.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-trait.rs @@ -1,5 +1,11 @@ // check-pass -#![feature(associated_type_bounds, const_trait_impl, const_cmp)] +#![allow(incomplete_features)] +#![feature( + associated_type_bounds, + const_trait_impl, + const_cmp, + return_position_impl_trait_in_trait, +)] use std::marker::Destruct; @@ -7,15 +13,30 @@ const fn cmp(a: &impl ~const PartialEq) -> bool { a == a } -const fn wrap(x: impl ~const PartialEq + ~const Destruct) -> impl ~const PartialEq + ~const Destruct { +const fn wrap(x: impl ~const PartialEq + ~const Destruct) + -> impl ~const PartialEq + ~const Destruct +{ x } +#[const_trait] +trait Foo { + fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; +} + +impl const Foo for () { + fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { + 123 + } +} + const _: () = { assert!(cmp(&0xDEADBEEFu32)); assert!(cmp(&())); assert!(wrap(123) == wrap(123)); assert!(wrap(123) != wrap(456)); + let x = <() as Foo>::huh(); + assert!(x == x); }; #[const_trait]