Skip to content

Commit

Permalink
Rollup merge of rust-lang#90114 - BoxyUwU:cg_defaults_tests, r=lcnr
Browse files Browse the repository at this point in the history
Add some tests for const_generics_defaults

I think this covers some of the stuff required for stabilisation report, some of these tests are probably covering stuff we already have but it can't hurt to have more :)

r? `@lcnr`
  • Loading branch information
JohnTitor authored Oct 21, 2021
2 parents 2d0f3c6 + e7a9e82 commit 114b995
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/test/ui/const-generics/defaults/default-annotation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![feature(staged_api)]
#![feature(const_generics_defaults)]
#![allow(incomplete_features)]
// FIXME(const_generics): It seems like we aren't testing the right thing here,
// FIXME(const_generics_defaults): It seems like we aren't testing the right thing here,
// I would assume that we want the attributes to apply to the const parameter defaults
// themselves.
#![stable(feature = "const_default_test", since="none")]
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/const-generics/defaults/doesnt_infer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(const_generics_defaults)]

// test that defaulted const params are not used to help type inference

struct Foo<const N: u32 = 2>;

impl<const N: u32> Foo<N> {
fn foo() -> Self { loop {} }
}

fn main() {
let foo = Foo::<1>::foo();
let foo = Foo::foo();
//~^ error: type annotations needed for `Foo<{_: u32}>`
}
11 changes: 11 additions & 0 deletions src/test/ui/const-generics/defaults/doesnt_infer.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0282]: type annotations needed for `Foo<{_: u32}>`
--> $DIR/doesnt_infer.rs:13:15
|
LL | let foo = Foo::foo();
| --- ^^^^^^^^ cannot infer the value of const parameter `N`
| |
| consider giving `foo` the explicit type `Foo<{_: u32}>`, where the type parameter `N` is specified

error: aborting due to previous error

For more information about this error, try `rustc --explain E0282`.
31 changes: 31 additions & 0 deletions src/test/ui/const-generics/defaults/rp_impl_trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// run-pass
#![feature(const_generics_defaults)]

struct Uwu<const N: u32 = 1, const M: u32 = N>;

trait Trait {}
impl<const N: u32> Trait for Uwu<N> {}

fn rawr<const N: u32>() -> impl Trait {
Uwu::<N>
}

trait Traitor<const N: u8 = 1, const M: u8 = N> { }

impl<const N: u8> Traitor<N> for u32 {}
impl Traitor<1, 1> for u64 {}

fn uwu<const N: u8>() -> impl Traitor<N> {
1_u32
}

fn owo() -> impl Traitor {
1_u64
}

fn main() {
rawr::<3>();
rawr::<7>();
uwu::<{ u8::MAX }>();
owo();
}
33 changes: 33 additions & 0 deletions src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#![feature(const_generics_defaults)]

struct Uwu<const N: u32 = 1, const M: u32 = N>;

trait Trait {}
impl<const N: u32> Trait for Uwu<N> {}

fn rawr() -> impl Trait {
//~^ error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied
Uwu::<10, 12>
}

trait Traitor<const N: u8 = 1, const M: u8 = N> { }

impl<const N: u8> Traitor<N, 2> for u32 {}
impl Traitor<1, 2> for u64 {}


fn uwu<const N: u8>() -> impl Traitor<N> {
//~^ error: the trait bound `u32: Traitor<N, N>` is not satisfied
1_u32
}

fn owo() -> impl Traitor {
//~^ error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
1_u64
}

fn main() {
rawr();
uwu();
owo();
}
30 changes: 30 additions & 0 deletions src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied
--> $DIR/rp_impl_trait_fail.rs:8:14
|
LL | fn rawr() -> impl Trait {
| ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>`
|
= help: the following implementations were found:
<Uwu<N> as Trait>

error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied
--> $DIR/rp_impl_trait_fail.rs:19:26
|
LL | fn uwu<const N: u8>() -> impl Traitor<N> {
| ^^^^^^^^^^^^^^^ the trait `Traitor<N, N>` is not implemented for `u32`
|
= help: the following implementations were found:
<u32 as Traitor<N, 2_u8>>

error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
--> $DIR/rp_impl_trait_fail.rs:24:13
|
LL | fn owo() -> impl Traitor {
| ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64`
|
= help: the following implementations were found:
<u64 as Traitor<1_u8, 2_u8>>

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
45 changes: 45 additions & 0 deletions src/test/ui/const-generics/defaults/trait_objects.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// run-pass
#![feature(const_generics_defaults)]

trait Trait<const N: u8 = 12> {
fn uwu(&self) -> u8 {
N
}
}

impl Trait for u32 {}

impl Trait<12> for u64 {
fn uwu(&self) -> u8 {
*self as u8
}
}

fn foo(arg: &dyn Trait) -> u8 {
arg.uwu()
}

trait Traitor<const N: u8 = 1, const M: u8 = N> {
fn owo(&self) -> u8 {
M
}
}

impl Traitor<2> for bool { }
impl Traitor for u8 {
fn owo(&self) -> u8 {
*self
}
}

fn bar<const N: u8>(arg: &dyn Traitor<N>) -> u8 {
arg.owo()
}

fn main() {
assert_eq!(foo(&10_u32), 12);
assert_eq!(foo(&3_u64), 3);

assert_eq!(bar(&true), 2);
assert_eq!(bar(&1_u8), 1);
}
32 changes: 32 additions & 0 deletions src/test/ui/const-generics/defaults/trait_objects_fail.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#![feature(const_generics_defaults)]

trait Trait<const N: u8 = 12> {
fn uwu(&self) -> u8 {
N
}
}

impl Trait<2> for u32 {}

fn foo(arg: &dyn Trait) -> u8 {
arg.uwu()
}

trait Traitor<const N: u8 = 1, const M: u8 = N> {
fn owo(&self) -> u8 {
M
}
}

impl Traitor<2, 3> for bool { }

fn bar<const N: u8>(arg: &dyn Traitor<N>) -> u8 {
arg.owo()
}

fn main() {
foo(&10_u32);
//~^ error: the trait bound `u32: Trait` is not satisfied
bar(&true);
//~^ error: the trait bound `bool: Traitor<{_: u8}, {_: u8}>` is not satisfied
}
27 changes: 27 additions & 0 deletions src/test/ui/const-generics/defaults/trait_objects_fail.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0277]: the trait bound `u32: Trait` is not satisfied
--> $DIR/trait_objects_fail.rs:28:9
|
LL | foo(&10_u32);
| --- ^^^^^^^ the trait `Trait` is not implemented for `u32`
| |
| required by a bound introduced by this call
|
= help: the following implementations were found:
<u32 as Trait<2_u8>>
= note: required for the cast to the object type `dyn Trait`

error[E0277]: the trait bound `bool: Traitor<{_: u8}, {_: u8}>` is not satisfied
--> $DIR/trait_objects_fail.rs:30:9
|
LL | bar(&true);
| --- ^^^^^ the trait `Traitor<{_: u8}, {_: u8}>` is not implemented for `bool`
| |
| required by a bound introduced by this call
|
= help: the following implementations were found:
<bool as Traitor<2_u8, 3_u8>>
= note: required for the cast to the object type `dyn Traitor<{_: u8}, {_: u8}>`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
21 changes: 21 additions & 0 deletions src/test/ui/const-generics/defaults/wfness.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#![feature(const_generics_defaults)]

struct Ooopsies<const N: u8 = { u8::MAX + 1 }>;
//~^ error: evaluation of constant value failed

trait Trait<const N: u8> {}
impl Trait<3> for () {}
struct WhereClause<const N: u8 = 2> where (): Trait<N>;
//~^ error: the trait bound `(): Trait<2_u8>` is not satisfied

trait Traitor<T, const N: u8> {}
struct WhereClauseTooGeneric<T = u32, const N: u8 = 2>(T) where (): Traitor<T, N>;

// no error on struct def
struct DependentDefaultWfness<const N: u8 = 1, T = WhereClause<N>>(T);
fn foo() -> DependentDefaultWfness {
//~^ error: the trait bound `(): Trait<1_u8>` is not satisfied
loop {}
}

fn main() {}
38 changes: 38 additions & 0 deletions src/test/ui/const-generics/defaults/wfness.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
error[E0080]: evaluation of constant value failed
--> $DIR/wfness.rs:3:33
|
LL | struct Ooopsies<const N: u8 = { u8::MAX + 1 }>;
| ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow

error[E0277]: the trait bound `(): Trait<2_u8>` is not satisfied
--> $DIR/wfness.rs:8:47
|
LL | struct WhereClause<const N: u8 = 2> where (): Trait<N>;
| ^^^^^^^^ the trait `Trait<2_u8>` is not implemented for `()`
|
= help: the following implementations were found:
<() as Trait<3_u8>>
note: required by `WhereClause`
--> $DIR/wfness.rs:8:1
|
LL | struct WhereClause<const N: u8 = 2> where (): Trait<N>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `(): Trait<1_u8>` is not satisfied
--> $DIR/wfness.rs:16:13
|
LL | fn foo() -> DependentDefaultWfness {
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<1_u8>` is not implemented for `()`
|
= help: the following implementations were found:
<() as Trait<3_u8>>
note: required by a bound in `WhereClause`
--> $DIR/wfness.rs:8:47
|
LL | struct WhereClause<const N: u8 = 2> where (): Trait<N>;
| ^^^^^^^^ required by this bound in `WhereClause`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0080, E0277.
For more information about an error, try `rustc --explain E0080`.
3 changes: 3 additions & 0 deletions src/test/ui/const-generics/defaults/wrong-order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ struct A<T = u32, const N: usize> {
arg: T,
}

struct Foo<const N: u8 = 3, T>(T);
//~^ error: generic parameters with a default must be trailing

fn main() {}
8 changes: 7 additions & 1 deletion src/test/ui/const-generics/defaults/wrong-order.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@ error: generic parameters with a default must be trailing
LL | struct A<T = u32, const N: usize> {
| ^

error: aborting due to previous error
error: generic parameters with a default must be trailing
--> $DIR/wrong-order.rs:8:18
|
LL | struct Foo<const N: u8 = 3, T>(T);
| ^

error: aborting due to 2 previous errors

0 comments on commit 114b995

Please sign in to comment.