Skip to content

Allow impl ~const Trait opaque types #105725

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ enum SelfSemantic {
/// What is the context that prevents using `~const`?
enum DisallowTildeConstContext<'a> {
TraitObject,
ImplTrait,
Fn(FnKind<'a>),
}

Expand Down Expand Up @@ -187,11 +186,7 @@ impl<'a> AstValidator<'a> {

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;
}

Expand Down Expand Up @@ -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"),
};
Expand Down
55 changes: 55 additions & 0 deletions src/test/ui/rfc-2632-const-trait-impl/const-impl-trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// check-pass
#![allow(incomplete_features)]
#![feature(
associated_type_bounds,
const_trait_impl,
const_cmp,
return_position_impl_trait_in_trait,
)]

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_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]
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() {}
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -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