Rollup merge of #88418 - fee1-dead:trait-assoc-tilde-const, r=oli-obk
Allow `~const` bounds on trait assoc functions r? `@oli-obk`
This commit is contained in:
commit
ab37e49611
6 changed files with 180 additions and 8 deletions
|
@ -1442,7 +1442,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
if !self.is_tilde_const_allowed {
|
if !self.is_tilde_const_allowed {
|
||||||
self.err_handler()
|
self.err_handler()
|
||||||
.struct_span_err(bound.span(), "`~const` is not allowed here")
|
.struct_span_err(bound.span(), "`~const` is not allowed here")
|
||||||
.note("only allowed on bounds on traits' associated types, const fns, const impls and its associated functions")
|
.note("only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions")
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1616,7 +1616,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
walk_list!(self, visit_ty, ty);
|
walk_list!(self, visit_ty, ty);
|
||||||
}
|
}
|
||||||
AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, ref body))
|
AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, ref body))
|
||||||
if self.in_const_trait_impl =>
|
if self.in_const_trait_impl || ctxt == AssocCtxt::Trait =>
|
||||||
{
|
{
|
||||||
self.visit_vis(&item.vis);
|
self.visit_vis(&item.vis);
|
||||||
self.visit_ident(item.ident);
|
self.visit_ident(item.ident);
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: `~const` is not allowed here
|
||||||
LL | fn rpit() -> impl ~const T { S }
|
LL | fn rpit() -> impl ~const T { S }
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: only allowed on bounds on traits' associated types, const fns, const impls and its associated functions
|
= 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
|
error: `~const` is not allowed here
|
||||||
--> $DIR/tilde-const-invalid-places.rs:11:17
|
--> $DIR/tilde-const-invalid-places.rs:11:17
|
||||||
|
@ -12,7 +12,7 @@ error: `~const` is not allowed here
|
||||||
LL | fn apit(_: impl ~const T) {}
|
LL | fn apit(_: impl ~const T) {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: only allowed on bounds on traits' associated types, const fns, const impls and its associated functions
|
= 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
|
error: `~const` is not allowed here
|
||||||
--> $DIR/tilde-const-invalid-places.rs:14:50
|
--> $DIR/tilde-const-invalid-places.rs:14:50
|
||||||
|
@ -20,7 +20,7 @@ error: `~const` is not allowed here
|
||||||
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
|
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: only allowed on bounds on traits' associated types, const fns, const impls and its associated functions
|
= 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
|
error: `~const` is not allowed here
|
||||||
--> $DIR/tilde-const-invalid-places.rs:17:48
|
--> $DIR/tilde-const-invalid-places.rs:17:48
|
||||||
|
@ -28,7 +28,7 @@ error: `~const` is not allowed here
|
||||||
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
|
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: only allowed on bounds on traits' associated types, const fns, const impls and its associated functions
|
= 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
|
error: `~const` is not allowed here
|
||||||
--> $DIR/tilde-const-invalid-places.rs:20:15
|
--> $DIR/tilde-const-invalid-places.rs:20:15
|
||||||
|
@ -36,7 +36,7 @@ error: `~const` is not allowed here
|
||||||
LL | fn generic<P: ~const T>() {}
|
LL | fn generic<P: ~const T>() {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: only allowed on bounds on traits' associated types, const fns, const impls and its associated functions
|
= 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
|
error: `~const` is not allowed here
|
||||||
--> $DIR/tilde-const-invalid-places.rs:23:31
|
--> $DIR/tilde-const-invalid-places.rs:23:31
|
||||||
|
@ -44,7 +44,7 @@ error: `~const` is not allowed here
|
||||||
LL | fn where_clause<P>() where P: ~const T {}
|
LL | fn where_clause<P>() where P: ~const T {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: only allowed on bounds on traits' associated types, const fns, const impls and its associated functions
|
= note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions
|
||||||
|
|
||||||
error: `~const` and `?` are mutually exclusive
|
error: `~const` and `?` are mutually exclusive
|
||||||
--> $DIR/tilde-const-invalid-places.rs:26:25
|
--> $DIR/tilde-const-invalid-places.rs:26:25
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
#![feature(const_fn_trait_bound)]
|
||||||
|
|
||||||
|
trait Bar {
|
||||||
|
fn bar() -> u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
#[default_method_body_is_const]
|
||||||
|
fn foo() -> u8 where Self: ~const Bar {
|
||||||
|
<Self as Bar>::bar() * 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NonConst;
|
||||||
|
struct Const;
|
||||||
|
|
||||||
|
impl Bar for NonConst {
|
||||||
|
fn bar() -> u8 {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for NonConst {}
|
||||||
|
|
||||||
|
impl const Bar for Const {
|
||||||
|
fn bar() -> u8 {
|
||||||
|
4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const Foo for Const {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
const ANS1: u8 = Const::foo();
|
||||||
|
let ans2 = NonConst::foo();
|
||||||
|
|
||||||
|
assert_eq!(ANS1 + ans2, 42);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
#![feature(const_fn_trait_bound)]
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn bar() where Self: ~const Foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
impl Foo for S {
|
||||||
|
fn bar() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn baz<T: Foo>() {
|
||||||
|
T::bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn qux<T: ~const Foo>() {
|
||||||
|
T::bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
40
src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
Normal file
40
src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#![feature(const_fn_trait_bound)]
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
trait Bar {}
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn a();
|
||||||
|
fn b() where Self: ~const Bar;
|
||||||
|
fn c<T: ~const Bar>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn test1<T: ~const Foo + Bar>() {
|
||||||
|
T::a();
|
||||||
|
T::b();
|
||||||
|
//~^ ERROR the trait bound
|
||||||
|
T::c::<T>();
|
||||||
|
//~^ ERROR the trait bound
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn test2<T: ~const Foo + ~const Bar>() {
|
||||||
|
T::a();
|
||||||
|
T::b();
|
||||||
|
T::c::<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test3<T: Foo>() {
|
||||||
|
T::a();
|
||||||
|
T::b();
|
||||||
|
//~^ ERROR the trait bound
|
||||||
|
T::c::<T>();
|
||||||
|
//~^ ERROR the trait bound
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test4<T: Foo + Bar>() {
|
||||||
|
T::a();
|
||||||
|
T::b();
|
||||||
|
T::c::<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,67 @@
|
||||||
|
error[E0277]: the trait bound `T: Bar` is not satisfied
|
||||||
|
--> $DIR/trait-where-clause.rs:14:5
|
||||||
|
|
|
||||||
|
LL | T::b();
|
||||||
|
| ^^^^ the trait `Bar` is not implemented for `T`
|
||||||
|
|
|
||||||
|
note: required by `Foo::b`
|
||||||
|
--> $DIR/trait-where-clause.rs:8:5
|
||||||
|
|
|
||||||
|
LL | fn b() where Self: ~const Bar;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | const fn test1<T: ~const Foo + Bar + Bar>() {
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: Bar` is not satisfied
|
||||||
|
--> $DIR/trait-where-clause.rs:16:5
|
||||||
|
|
|
||||||
|
LL | T::c::<T>();
|
||||||
|
| ^^^^^^^^^ the trait `Bar` is not implemented for `T`
|
||||||
|
|
|
||||||
|
note: required by `Foo::c`
|
||||||
|
--> $DIR/trait-where-clause.rs:9:5
|
||||||
|
|
|
||||||
|
LL | fn c<T: ~const Bar>();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | const fn test1<T: ~const Foo + Bar + Bar>() {
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: Bar` is not satisfied
|
||||||
|
--> $DIR/trait-where-clause.rs:28:5
|
||||||
|
|
|
||||||
|
LL | T::b();
|
||||||
|
| ^^^^ the trait `Bar` is not implemented for `T`
|
||||||
|
|
|
||||||
|
note: required by `Foo::b`
|
||||||
|
--> $DIR/trait-where-clause.rs:8:5
|
||||||
|
|
|
||||||
|
LL | fn b() where Self: ~const Bar;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | fn test3<T: Foo + Bar>() {
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: Bar` is not satisfied
|
||||||
|
--> $DIR/trait-where-clause.rs:30:5
|
||||||
|
|
|
||||||
|
LL | T::c::<T>();
|
||||||
|
| ^^^^^^^^^ the trait `Bar` is not implemented for `T`
|
||||||
|
|
|
||||||
|
note: required by `Foo::c`
|
||||||
|
--> $DIR/trait-where-clause.rs:9:5
|
||||||
|
|
|
||||||
|
LL | fn c<T: ~const Bar>();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | fn test3<T: Foo + Bar>() {
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue