Skip to content
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

Allow ~const bounds on non-const functions #102273

Merged
merged 1 commit into from
Sep 26, 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
7 changes: 3 additions & 4 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if !self.is_tilde_const_allowed {
self.err_handler()
.struct_span_err(bound.span(), "`~const` is not allowed here")
.note("only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions")
.note("only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions")
.emit();
}
}
Expand Down Expand Up @@ -1523,9 +1523,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
}

let tilde_const_allowed =
matches!(fk.header(), Some(FnHeader { constness: Const::Yes(_), .. }))
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
let tilde_const_allowed = matches!(fk.header(), Some(FnHeader { .. }))
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));

self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// check-pass
#![feature(const_trait_impl)]
#![feature(generic_arg_infer)]
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

struct Foo<const N: usize>;

impl<const N: usize> Foo<N> {
fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't be sound. ~const explicitly mean const but ehh. So it could be not const. We need something like A: const Trait which is "always const" to make this work. I will open a revert PR shortly.

Copy link
Contributor Author

@lilasta lilasta Sep 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I recall, the following code was accepted before this PR (I changed only 'non-associated' non-const functions).

impl Type {
    fn function<T: ~const Trait>() {}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, so all cases like the following are currently unsound...?

somefunc<T: ~const Trait>() -> Foo<{ T::bar(value) }>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just came here because I broke this test in #101900 😆

so yea, this is unsound or depending on the impl, very confusing, as making a function const fn will make it stop compiling

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

funky broken errors, but they point at the problem:

error[E0277]: the trait bound `A: Add42<_>` is not satisfied
  --> /home/ubuntu/rust2/src/test/ui/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs:27:61
   |
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
   |                                                             ^^^^^^ the trait `Add42<_>` is not implemented for `A`
   |
help: consider further restricting this bound
   |
LL | fn bar<A: ~const Add42 + Add42<_>, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
   |                        ++++++++++

error[E0277]: the trait bound `A: Add42<_>` is not satisfied
  --> /home/ubuntu/rust2/src/test/ui/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs:11:43
   |
LL |    fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
   |                                           ^^^^^^ the trait `Add42<_>` is not implemented for `A`
   |
help: consider further restricting this bound
   |
LL |    fn add<A: ~const Add42 + Add42<_>>(self) -> Foo<{ A::add(N) }> {
   |                           ++++++++++

error: aborting due to 2 previous errors

Foo
}
}

#[const_trait]
trait Add42 {
fn add(a: usize) -> usize;
}

impl const Add42 for () {
fn add(a: usize) -> usize {
a + 42
}
}

fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
Foo
}

fn main() {
let foo = Foo::<0>;
let foo = bar::<(), _>(foo);
let _foo = bar::<(), _>(foo);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
//~^ ERROR `~const` is not allowed

fn generic<P: ~const T>() {}
//~^ ERROR `~const` is not allowed

fn where_clause<P>() where P: ~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
Expand Up @@ -4,53 +4,37 @@ error: `~const` is not allowed here
LL | fn rpit() -> impl ~const T { S }
| ^^^^^^^^
|
= note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions

error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:11:17
|
LL | fn apit(_: impl ~const T) {}
| ^^^^^^^^
|
= note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions

error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:14:50
|
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
| ^^^^^^^^
|
= note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions

error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:17:48
|
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
| ^^^^^^^^
|
= note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions

error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:20:15
|
LL | fn generic<P: ~const T>() {}
| ^^^^^^^^
|
= note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions

error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:23:31
|
LL | fn where_clause<P>() where P: ~const T {}
| ^^^^^^^^
|
= note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions

error: `~const` and `?` are mutually exclusive
--> $DIR/tilde-const-invalid-places.rs:26:25
--> $DIR/tilde-const-invalid-places.rs:20:25
|
LL | struct TildeQuestion<T: ~const ?Sized>(std::marker::PhantomData<T>);
| ^^^^^^^^^^^^^

error: aborting due to 7 previous errors
error: aborting due to 5 previous errors