Allow impl ~const Trait opaque types

This commit is contained in:
Deadbeef 2022-12-15 00:51:34 +00:00
parent b70baa4f92
commit 5da1a04278
4 changed files with 37 additions and 58 deletions

View file

@ -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 @@ fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) {
fn with_impl_trait(&mut self, outer: Option<Span>, 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 @@ fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
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"),
};

View file

@ -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<Item: ~const T> { Some(S) }
const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
fn main() {}

View file

@ -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<Item: ~const T> { Some(S) }
//~^ ERROR `~const` is not allowed
fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
//~^ ERROR `~const` is not allowed
struct TildeQuestion<T: ~const ?Sized>(std::marker::PhantomData<T>);
//~^ ERROR `~const` and `?` are mutually exclusive

View file

@ -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<Item: ~const T> { 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<Item: ~const T>) {}
| ^^^^^^^^
|
= 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<T: ~const ?Sized>(std::marker::PhantomData<T>);
| ^^^^^^^^^^^^^
error: aborting due to 5 previous errors
error: aborting due to previous error