mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 04:26:48 +00:00
Add UI tests for generic const items
This commit is contained in:
parent
a011dd9dac
commit
6636916b66
@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
|
||||
const ENTRY_LIMIT: usize = 900;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1893;
|
||||
const ROOT_ENTRY_LIMIT: usize = 871;
|
||||
const ROOT_ENTRY_LIMIT: usize = 872;
|
||||
|
||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||
"rs", // test source files
|
||||
|
22
tests/ui/generic-const-items/associated-const-equality.rs
Normal file
22
tests/ui/generic-const-items/associated-const-equality.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(generic_const_items, associated_const_equality)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Owner {
|
||||
const C<const N: u32>: u32;
|
||||
const K<const N: u32>: u32;
|
||||
}
|
||||
|
||||
impl Owner for () {
|
||||
const C<const N: u32>: u32 = N;
|
||||
const K<const N: u32>: u32 = N + 1;
|
||||
}
|
||||
|
||||
fn take0<const N: u32>(_: impl Owner<C<N> = { N }>) {}
|
||||
fn take1(_: impl Owner<K<99> = 100>) {}
|
||||
|
||||
fn main() {
|
||||
take0::<128>(());
|
||||
take1(());
|
||||
}
|
61
tests/ui/generic-const-items/basic.rs
Normal file
61
tests/ui/generic-const-items/basic.rs
Normal file
@ -0,0 +1,61 @@
|
||||
// check-pass
|
||||
|
||||
// Basic usage patterns of free & associated generic const items.
|
||||
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
const NULL<T>: Option<T> = None::<T>;
|
||||
const NOTHING<T>: Option<T> = None; // arg inferred
|
||||
|
||||
let _ = NOTHING::<String>;
|
||||
let _: Option<u8> = NULL; // arg inferred
|
||||
|
||||
const IDENTITY<const X: u64>: u64 = X;
|
||||
|
||||
const COUNT: u64 = IDENTITY::<48>;
|
||||
const AMOUNT: u64 = IDENTITY::<COUNT>;
|
||||
const NUMBER: u64 = IDENTITY::<{ AMOUNT * 2 }>;
|
||||
let _ = NUMBER;
|
||||
let _ = IDENTITY::<0>;
|
||||
|
||||
let _ = match 0 {
|
||||
IDENTITY::<1> => 2,
|
||||
IDENTITY::<{ 1 + 1 }> => 4,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
const CREATE<I: Inhabited>: I = I::PROOF;
|
||||
let _ = CREATE::<u64>;
|
||||
let _: u64 = CREATE; // arg inferred
|
||||
|
||||
let _ = <() as Main<u64>>::MAKE::<u64>;
|
||||
let _: (u64, u64) = <()>::MAKE; // args inferred
|
||||
}
|
||||
|
||||
pub fn usage<'any>() {
|
||||
const REGION_POLY<'a>: &'a () = &();
|
||||
|
||||
let _: &'any () = REGION_POLY::<'any>;
|
||||
let _: &'any () = REGION_POLY::<'_>;
|
||||
let _: &'static () = REGION_POLY;
|
||||
}
|
||||
|
||||
trait Main<O> {
|
||||
type Output<I>;
|
||||
const MAKE<I: Inhabited>: Self::Output<I>;
|
||||
}
|
||||
|
||||
impl<O: Inhabited> Main<O> for () {
|
||||
type Output<I> = (O, I);
|
||||
const MAKE<I: Inhabited>: Self::Output<I> = (O::PROOF, I::PROOF);
|
||||
}
|
||||
|
||||
trait Inhabited {
|
||||
const PROOF: Self;
|
||||
}
|
||||
|
||||
impl Inhabited for u64 {
|
||||
const PROOF: Self = 512;
|
||||
}
|
30
tests/ui/generic-const-items/compare-impl-item.rs
Normal file
30
tests/ui/generic-const-items/compare-impl-item.rs
Normal file
@ -0,0 +1,30 @@
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Trait<P> {
|
||||
const A: ();
|
||||
const B<const K: u64, const Q: u64>: u64;
|
||||
const C<T>: T;
|
||||
const D<const N: usize>: usize;
|
||||
|
||||
const E: usize;
|
||||
const F<T: PartialEq>: ();
|
||||
}
|
||||
|
||||
impl<P> Trait<P> for () {
|
||||
const A<T>: () = ();
|
||||
//~^ ERROR const `A` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
const B<const K: u64>: u64 = 0;
|
||||
//~^ ERROR const `B` has 1 const parameter but its trait declaration has 2 const parameters
|
||||
const C<'a>: &'a str = "";
|
||||
//~^ ERROR const `C` has 0 type parameters but its trait declaration has 1 type parameter
|
||||
const D<const N: u16>: u16 = N;
|
||||
//~^ ERROR const `D` has an incompatible generic parameter for trait `Trait`
|
||||
|
||||
const E: usize = 1024
|
||||
where
|
||||
P: Copy; //~ ERROR impl has stricter requirements than trait
|
||||
const F<T: Eq>: () = (); //~ ERROR impl has stricter requirements than trait
|
||||
}
|
||||
|
||||
fn main() {}
|
66
tests/ui/generic-const-items/compare-impl-item.stderr
Normal file
66
tests/ui/generic-const-items/compare-impl-item.stderr
Normal file
@ -0,0 +1,66 @@
|
||||
error[E0049]: const `A` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
--> $DIR/compare-impl-item.rs:15:13
|
||||
|
|
||||
LL | const A: ();
|
||||
| - expected 0 type parameters
|
||||
...
|
||||
LL | const A<T>: () = ();
|
||||
| ^ found 1 type parameter
|
||||
|
||||
error[E0049]: const `B` has 1 const parameter but its trait declaration has 2 const parameters
|
||||
--> $DIR/compare-impl-item.rs:17:13
|
||||
|
|
||||
LL | const B<const K: u64, const Q: u64>: u64;
|
||||
| ------------ ------------
|
||||
| |
|
||||
| expected 2 const parameters
|
||||
...
|
||||
LL | const B<const K: u64>: u64 = 0;
|
||||
| ^^^^^^^^^^^^ found 1 const parameter
|
||||
|
||||
error[E0049]: const `C` has 0 type parameters but its trait declaration has 1 type parameter
|
||||
--> $DIR/compare-impl-item.rs:19:13
|
||||
|
|
||||
LL | const C<T>: T;
|
||||
| - expected 1 type parameter
|
||||
...
|
||||
LL | const C<'a>: &'a str = "";
|
||||
| ^^ found 0 type parameters
|
||||
|
||||
error[E0053]: const `D` has an incompatible generic parameter for trait `Trait`
|
||||
--> $DIR/compare-impl-item.rs:21:13
|
||||
|
|
||||
LL | trait Trait<P> {
|
||||
| -----
|
||||
...
|
||||
LL | const D<const N: usize>: usize;
|
||||
| -------------- expected const parameter of type `usize`
|
||||
...
|
||||
LL | impl<P> Trait<P> for () {
|
||||
| -----------------------
|
||||
...
|
||||
LL | const D<const N: u16>: u16 = N;
|
||||
| ^^^^^^^^^^^^ found const parameter of type `u16`
|
||||
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/compare-impl-item.rs:26:12
|
||||
|
|
||||
LL | const E: usize;
|
||||
| -------------- definition of `E` from trait
|
||||
...
|
||||
LL | P: Copy;
|
||||
| ^^^^ impl has extra requirement `P: Copy`
|
||||
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/compare-impl-item.rs:27:16
|
||||
|
|
||||
LL | const F<T: PartialEq>: ();
|
||||
| ------------------------- definition of `F` from trait
|
||||
...
|
||||
LL | const F<T: Eq>: () = ();
|
||||
| ^^ impl has extra requirement `T: Eq`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0049, E0053, E0276.
|
||||
For more information about an error, try `rustc --explain E0049`.
|
24
tests/ui/generic-const-items/const-trait-impl.rs
Normal file
24
tests/ui/generic-const-items/const-trait-impl.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// check-pass
|
||||
|
||||
// Test that we can call methods from const trait impls inside of generic const items.
|
||||
|
||||
#![feature(generic_const_items, const_trait_impl)]
|
||||
#![allow(incomplete_features)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// FIXME(generic_const_items): Interpret `~const` as always-const.
|
||||
const CREATE<T: ~const Create>: T = T::create();
|
||||
|
||||
pub const K0: i32 = CREATE::<i32>;
|
||||
pub const K1: i32 = CREATE; // arg inferred
|
||||
|
||||
#[const_trait]
|
||||
trait Create {
|
||||
fn create() -> Self;
|
||||
}
|
||||
|
||||
impl const Create for i32 {
|
||||
fn create() -> i32 {
|
||||
4096
|
||||
}
|
||||
}
|
27
tests/ui/generic-const-items/duplicate-where-clause.rs
Normal file
27
tests/ui/generic-const-items/duplicate-where-clause.rs
Normal file
@ -0,0 +1,27 @@
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Tr<P> {
|
||||
const K: ()
|
||||
where
|
||||
P: Copy
|
||||
where
|
||||
P: Eq;
|
||||
//~^ ERROR cannot define duplicate `where` clauses on an item
|
||||
}
|
||||
|
||||
// Test that we error on the first where-clause but also that we don't suggest to swap it with the
|
||||
// body as it would conflict with the second where-clause.
|
||||
// FIXME(generic_const_items): We should provide a structured sugg to merge the 1st into the 2nd WC.
|
||||
|
||||
impl<P> Tr<P> for () {
|
||||
const K: ()
|
||||
where
|
||||
P: Eq
|
||||
= ()
|
||||
where
|
||||
P: Copy;
|
||||
//~^^^^^ ERROR where clauses are not allowed before const item bodies
|
||||
}
|
||||
|
||||
fn main() {}
|
27
tests/ui/generic-const-items/duplicate-where-clause.stderr
Normal file
27
tests/ui/generic-const-items/duplicate-where-clause.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error: cannot define duplicate `where` clauses on an item
|
||||
--> $DIR/duplicate-where-clause.rs:9:9
|
||||
|
|
||||
LL | P: Copy
|
||||
| - previous `where` clause starts here
|
||||
LL | where
|
||||
LL | P: Eq;
|
||||
| ^
|
||||
|
|
||||
help: consider joining the two `where` clauses into one
|
||||
|
|
||||
LL | P: Copy,
|
||||
| ~
|
||||
|
||||
error: where clauses are not allowed before const item bodies
|
||||
--> $DIR/duplicate-where-clause.rs:19:5
|
||||
|
|
||||
LL | const K: ()
|
||||
| - while parsing this const item
|
||||
LL | / where
|
||||
LL | | P: Eq
|
||||
| |_____________^ unexpected where clause
|
||||
LL | = ()
|
||||
| -- the item body
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
18
tests/ui/generic-const-items/elided-lifetimes.rs
Normal file
18
tests/ui/generic-const-items/elided-lifetimes.rs
Normal file
@ -0,0 +1,18 @@
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Check that we forbid elided lifetimes inside the generics of const items.
|
||||
|
||||
const K<T>: () = ()
|
||||
where
|
||||
&T: Copy; //~ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
|
||||
const I<const S: &str>: &str = "";
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
//~| ERROR `&str` is forbidden as the type of a const generic parameter
|
||||
|
||||
const B<T: Trait<'_>>: () = (); //~ ERROR `'_` cannot be used here
|
||||
|
||||
trait Trait<'a> {}
|
||||
|
||||
fn main() {}
|
35
tests/ui/generic-const-items/elided-lifetimes.stderr
Normal file
35
tests/ui/generic-const-items/elided-lifetimes.stderr
Normal file
@ -0,0 +1,35 @@
|
||||
error[E0637]: `&` without an explicit lifetime name cannot be used here
|
||||
--> $DIR/elided-lifetimes.rs:8:5
|
||||
|
|
||||
LL | &T: Copy;
|
||||
| ^ explicit lifetime name needed here
|
||||
|
|
||||
help: consider introducing a higher-ranked lifetime here
|
||||
|
|
||||
LL | for<'a> &'a T: Copy;
|
||||
| +++++++ ++
|
||||
|
||||
error[E0637]: `&` without an explicit lifetime name cannot be used here
|
||||
--> $DIR/elided-lifetimes.rs:10:18
|
||||
|
|
||||
LL | const I<const S: &str>: &str = "";
|
||||
| ^ explicit lifetime name needed here
|
||||
|
||||
error[E0637]: `'_` cannot be used here
|
||||
--> $DIR/elided-lifetimes.rs:14:18
|
||||
|
|
||||
LL | const B<T: Trait<'_>>: () = ();
|
||||
| ^^ `'_` is a reserved lifetime name
|
||||
|
||||
error: `&str` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/elided-lifetimes.rs:10:18
|
||||
|
|
||||
LL | const I<const S: &str>: &str = "";
|
||||
| ^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= help: more complex types are supported with `#![feature(adt_const_params)]`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0637`.
|
31
tests/ui/generic-const-items/evaluatable-bounds.rs
Normal file
31
tests/ui/generic-const-items/evaluatable-bounds.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// This is a regression test for issue #104400.
|
||||
|
||||
// revisions: unconstrained constrained
|
||||
//[constrained] check-pass
|
||||
|
||||
// Test that we can constrain generic const items that appear inside associated consts by
|
||||
// adding a (makeshift) "evaluatable"-bound to the item.
|
||||
|
||||
#![feature(generic_const_items, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Trait {
|
||||
const LEN: usize;
|
||||
|
||||
#[cfg(unconstrained)]
|
||||
const ARRAY: [i32; Self::LEN]; //[unconstrained]~ ERROR unconstrained generic constant
|
||||
|
||||
#[cfg(constrained)]
|
||||
const ARRAY: [i32; Self::LEN]
|
||||
where
|
||||
[(); Self::LEN]:;
|
||||
}
|
||||
|
||||
impl Trait for () {
|
||||
const LEN: usize = 2;
|
||||
const ARRAY: [i32; Self::LEN] = [360, 720];
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let [_, _] = <() as Trait>::ARRAY;
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/evaluatable-bounds.rs:16:5
|
||||
|
|
||||
LL | const ARRAY: [i32; Self::LEN];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); Self::LEN]:`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -0,0 +1,37 @@
|
||||
pub trait Trait<A> {
|
||||
const ONE<T>: i32;
|
||||
//~^ ERROR generic const items are experimental
|
||||
|
||||
const TWO: ()
|
||||
where
|
||||
A: Copy;
|
||||
//~^^ ERROR generic const items are experimental
|
||||
}
|
||||
|
||||
const CONST<T>: i32 = 0;
|
||||
//~^ ERROR generic const items are experimental
|
||||
|
||||
const EMPTY<>: i32 = 0;
|
||||
//~^ ERROR generic const items are experimental
|
||||
|
||||
const TRUE: () = ()
|
||||
where
|
||||
String: Clone;
|
||||
//~^^ ERROR generic const items are experimental
|
||||
|
||||
// Ensure that we flag generic const items inside macro calls as well:
|
||||
|
||||
macro_rules! discard {
|
||||
($item:item) => {}
|
||||
}
|
||||
|
||||
discard! { const FREE<T>: () = (); }
|
||||
//~^ ERROR generic const items are experimental
|
||||
|
||||
discard! { impl () { const ASSOC<const N: ()>: () = (); } }
|
||||
//~^ ERROR generic const items are experimental
|
||||
|
||||
discard! { impl () { const ASSOC: i32 = 0 where String: Copy; } }
|
||||
//~^ ERROR generic const items are experimental
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,77 @@
|
||||
error[E0658]: generic const items are experimental
|
||||
--> $DIR/feature-gate-generic_const_items.rs:2:14
|
||||
|
|
||||
LL | const ONE<T>: i32;
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
|
||||
= help: add `#![feature(generic_const_items)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: generic const items are experimental
|
||||
--> $DIR/feature-gate-generic_const_items.rs:6:5
|
||||
|
|
||||
LL | / where
|
||||
LL | | A: Copy;
|
||||
| |_______________^
|
||||
|
|
||||
= note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
|
||||
= help: add `#![feature(generic_const_items)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: generic const items are experimental
|
||||
--> $DIR/feature-gate-generic_const_items.rs:11:12
|
||||
|
|
||||
LL | const CONST<T>: i32 = 0;
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
|
||||
= help: add `#![feature(generic_const_items)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: generic const items are experimental
|
||||
--> $DIR/feature-gate-generic_const_items.rs:14:12
|
||||
|
|
||||
LL | const EMPTY<>: i32 = 0;
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
|
||||
= help: add `#![feature(generic_const_items)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: generic const items are experimental
|
||||
--> $DIR/feature-gate-generic_const_items.rs:18:1
|
||||
|
|
||||
LL | / where
|
||||
LL | | String: Clone;
|
||||
| |_________________^
|
||||
|
|
||||
= note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
|
||||
= help: add `#![feature(generic_const_items)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: generic const items are experimental
|
||||
--> $DIR/feature-gate-generic_const_items.rs:28:22
|
||||
|
|
||||
LL | discard! { const FREE<T>: () = (); }
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
|
||||
= help: add `#![feature(generic_const_items)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: generic const items are experimental
|
||||
--> $DIR/feature-gate-generic_const_items.rs:31:33
|
||||
|
|
||||
LL | discard! { impl () { const ASSOC<const N: ()>: () = (); } }
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
|
||||
= help: add `#![feature(generic_const_items)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: generic const items are experimental
|
||||
--> $DIR/feature-gate-generic_const_items.rs:34:43
|
||||
|
|
||||
LL | discard! { impl () { const ASSOC: i32 = 0 where String: Copy; } }
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
|
||||
= help: add `#![feature(generic_const_items)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
15
tests/ui/generic-const-items/inference-failure.rs
Normal file
15
tests/ui/generic-const-items/inference-failure.rs
Normal file
@ -0,0 +1,15 @@
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
const NONE<T>: Option<T> = None::<T>;
|
||||
const IGNORE<T>: () = ();
|
||||
|
||||
fn none() {
|
||||
let _ = NONE; //~ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn ignore() {
|
||||
let _ = IGNORE; //~ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
20
tests/ui/generic-const-items/inference-failure.stderr
Normal file
20
tests/ui/generic-const-items/inference-failure.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error[E0282]: type annotations needed for `Option<T>`
|
||||
--> $DIR/inference-failure.rs:8:9
|
||||
|
|
||||
LL | let _ = NONE;
|
||||
| ^
|
||||
|
|
||||
help: consider giving this pattern a type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let _: Option<T> = NONE;
|
||||
| +++++++++++
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/inference-failure.rs:12:13
|
||||
|
|
||||
LL | let _ = IGNORE;
|
||||
| ^^^^^^ cannot infer type for type parameter `T` declared on the constant `IGNORE`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
18
tests/ui/generic-const-items/misplaced-where-clause.fixed
Normal file
18
tests/ui/generic-const-items/misplaced-where-clause.fixed
Normal file
@ -0,0 +1,18 @@
|
||||
// run-rustfix
|
||||
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features, dead_code)]
|
||||
|
||||
const K<T>: u64
|
||||
= T::K where
|
||||
T: Tr<()>;
|
||||
//~^^^ ERROR where clauses are not allowed before const item bodies
|
||||
|
||||
trait Tr<P> {
|
||||
const K: u64
|
||||
= 0 where
|
||||
P: Copy;
|
||||
//~^^^ ERROR where clauses are not allowed before const item bodies
|
||||
}
|
||||
|
||||
fn main() {}
|
20
tests/ui/generic-const-items/misplaced-where-clause.rs
Normal file
20
tests/ui/generic-const-items/misplaced-where-clause.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// run-rustfix
|
||||
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features, dead_code)]
|
||||
|
||||
const K<T>: u64
|
||||
where
|
||||
T: Tr<()>
|
||||
= T::K;
|
||||
//~^^^ ERROR where clauses are not allowed before const item bodies
|
||||
|
||||
trait Tr<P> {
|
||||
const K: u64
|
||||
where
|
||||
P: Copy
|
||||
= 0;
|
||||
//~^^^ ERROR where clauses are not allowed before const item bodies
|
||||
}
|
||||
|
||||
fn main() {}
|
36
tests/ui/generic-const-items/misplaced-where-clause.stderr
Normal file
36
tests/ui/generic-const-items/misplaced-where-clause.stderr
Normal file
@ -0,0 +1,36 @@
|
||||
error: where clauses are not allowed before const item bodies
|
||||
--> $DIR/misplaced-where-clause.rs:7:1
|
||||
|
|
||||
LL | const K<T>: u64
|
||||
| - while parsing this const item
|
||||
LL | / where
|
||||
LL | | T: Tr<()>
|
||||
| |_____________^ unexpected where clause
|
||||
LL | = T::K;
|
||||
| ---- the item body
|
||||
|
|
||||
help: move the body before the where clause
|
||||
|
|
||||
LL ~ = T::K where
|
||||
LL ~ T: Tr<()>;
|
||||
|
|
||||
|
||||
error: where clauses are not allowed before const item bodies
|
||||
--> $DIR/misplaced-where-clause.rs:14:5
|
||||
|
|
||||
LL | const K: u64
|
||||
| - while parsing this const item
|
||||
LL | / where
|
||||
LL | | P: Copy
|
||||
| |_______________^ unexpected where clause
|
||||
LL | = 0;
|
||||
| - the item body
|
||||
|
|
||||
help: move the body before the where clause
|
||||
|
|
||||
LL ~ = 0 where
|
||||
LL ~ P: Copy;
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
14
tests/ui/generic-const-items/parameter-defaults.rs
Normal file
14
tests/ui/generic-const-items/parameter-defaults.rs
Normal file
@ -0,0 +1,14 @@
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Check that we emit a *hard* error (not just a lint warning or error for example) for generic
|
||||
// parameter defaults on free const items since we are not limited by backward compatibility.
|
||||
#![allow(invalid_type_param_default)] // Should have no effect here.
|
||||
|
||||
// FIXME(default_type_parameter_fallback): Consider reallowing them once they work properly.
|
||||
|
||||
const NONE<T = ()>: Option<T> = None::<T>; //~ ERROR defaults for type parameters are only allowed
|
||||
|
||||
fn main() {
|
||||
let _ = NONE;
|
||||
}
|
8
tests/ui/generic-const-items/parameter-defaults.stderr
Normal file
8
tests/ui/generic-const-items/parameter-defaults.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/parameter-defaults.rs:10:12
|
||||
|
|
||||
LL | const NONE<T = ()>: Option<T> = None::<T>;
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
12
tests/ui/generic-const-items/recursive.rs
Normal file
12
tests/ui/generic-const-items/recursive.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// FIXME(generic_const_items): This leads to a stack overflow in the compiler!
|
||||
// known-bug: unknown
|
||||
// ignore-test
|
||||
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
const RECUR<T>: () = RECUR::<(T,)>;
|
||||
|
||||
fn main() {
|
||||
let _ = RECUR::<()>;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#![feature(generic_const_items, trivial_bounds)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Ensure that we check if trivial bounds on const items hold or not.
|
||||
|
||||
const UNUSABLE: () = ()
|
||||
where
|
||||
String: Copy;
|
||||
|
||||
fn main() {
|
||||
let _ = UNUSABLE; //~ ERROR the trait bound `String: Copy` is not satisfied
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
error[E0277]: the trait bound `String: Copy` is not satisfied
|
||||
--> $DIR/trivially-unsatisfied-bounds-0.rs:11:13
|
||||
|
|
||||
LL | let _ = UNUSABLE;
|
||||
| ^^^^^^^^ the trait `Copy` is not implemented for `String`
|
||||
|
|
||||
note: required by a bound in `UNUSABLE`
|
||||
--> $DIR/trivially-unsatisfied-bounds-0.rs:8:13
|
||||
|
|
||||
LL | const UNUSABLE: () = ()
|
||||
| -------- required by a bound in this constant
|
||||
LL | where
|
||||
LL | String: Copy;
|
||||
| ^^^^ required by this bound in `UNUSABLE`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -0,0 +1,12 @@
|
||||
#![feature(generic_const_items, trivial_bounds)]
|
||||
#![allow(incomplete_features, dead_code, trivial_bounds)]
|
||||
|
||||
// FIXME(generic_const_items): This looks like a bug to me. I expected that we wouldn't emit any
|
||||
// errors. I thought we'd skip the evaluation of consts whose bounds don't hold.
|
||||
|
||||
const UNUSED: () = ()
|
||||
where
|
||||
String: Copy;
|
||||
//~^^^ ERROR evaluation of constant value failed
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,11 @@
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/trivially-unsatisfied-bounds-1.rs:7:1
|
||||
|
|
||||
LL | / const UNUSED: () = ()
|
||||
LL | | where
|
||||
LL | | String: Copy;
|
||||
| |_________________^ entering unreachable code
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
34
tests/ui/generic-const-items/unsatisfied-bounds.rs
Normal file
34
tests/ui/generic-const-items/unsatisfied-bounds.rs
Normal file
@ -0,0 +1,34 @@
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Ensure that we check if bounds on const items hold or not.
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
const C<T: Copy>: () = ();
|
||||
|
||||
const K<T>: () = ()
|
||||
where
|
||||
Infallible: From<T>;
|
||||
|
||||
trait Trait<P> {
|
||||
const A: u32
|
||||
where
|
||||
P: Copy;
|
||||
|
||||
const B<T>: u32
|
||||
where
|
||||
Infallible: From<T>;
|
||||
}
|
||||
|
||||
impl<P> Trait<P> for () {
|
||||
const A: u32 = 0;
|
||||
const B<T>: u32 = 1;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let () = C::<String>; //~ ERROR the trait bound `String: Copy` is not satisfied
|
||||
let () = K::<()>; //~ ERROR the trait bound `Infallible: From<()>` is not satisfied
|
||||
let _ = <() as Trait<Vec<u8>>>::A; //~ ERROR the trait bound `Vec<u8>: Copy` is not satisfied
|
||||
let _ = <() as Trait<&'static str>>::B::<()>; //~ ERROR the trait bound `Infallible: From<()>` is not satisfied
|
||||
}
|
62
tests/ui/generic-const-items/unsatisfied-bounds.stderr
Normal file
62
tests/ui/generic-const-items/unsatisfied-bounds.stderr
Normal file
@ -0,0 +1,62 @@
|
||||
error[E0277]: the trait bound `String: Copy` is not satisfied
|
||||
--> $DIR/unsatisfied-bounds.rs:30:18
|
||||
|
|
||||
LL | let () = C::<String>;
|
||||
| ^^^^^^ the trait `Copy` is not implemented for `String`
|
||||
|
|
||||
note: required by a bound in `C`
|
||||
--> $DIR/unsatisfied-bounds.rs:8:12
|
||||
|
|
||||
LL | const C<T: Copy>: () = ();
|
||||
| ^^^^ required by this bound in `C`
|
||||
|
||||
error[E0277]: the trait bound `Infallible: From<()>` is not satisfied
|
||||
--> $DIR/unsatisfied-bounds.rs:31:18
|
||||
|
|
||||
LL | let () = K::<()>;
|
||||
| ^^ the trait `From<()>` is not implemented for `Infallible`
|
||||
|
|
||||
= help: the trait `From<!>` is implemented for `Infallible`
|
||||
note: required by a bound in `K`
|
||||
--> $DIR/unsatisfied-bounds.rs:12:17
|
||||
|
|
||||
LL | const K<T>: () = ()
|
||||
| - required by a bound in this constant
|
||||
LL | where
|
||||
LL | Infallible: From<T>;
|
||||
| ^^^^^^^ required by this bound in `K`
|
||||
|
||||
error[E0277]: the trait bound `Vec<u8>: Copy` is not satisfied
|
||||
--> $DIR/unsatisfied-bounds.rs:32:13
|
||||
|
|
||||
LL | let _ = <() as Trait<Vec<u8>>>::A;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Vec<u8>`
|
||||
|
|
||||
note: required by a bound in `Trait::A`
|
||||
--> $DIR/unsatisfied-bounds.rs:17:12
|
||||
|
|
||||
LL | const A: u32
|
||||
| - required by a bound in this associated constant
|
||||
LL | where
|
||||
LL | P: Copy;
|
||||
| ^^^^ required by this bound in `Trait::A`
|
||||
|
||||
error[E0277]: the trait bound `Infallible: From<()>` is not satisfied
|
||||
--> $DIR/unsatisfied-bounds.rs:33:46
|
||||
|
|
||||
LL | let _ = <() as Trait<&'static str>>::B::<()>;
|
||||
| ^^ the trait `From<()>` is not implemented for `Infallible`
|
||||
|
|
||||
= help: the trait `From<!>` is implemented for `Infallible`
|
||||
note: required by a bound in `Trait::B`
|
||||
--> $DIR/unsatisfied-bounds.rs:21:21
|
||||
|
|
||||
LL | const B<T>: u32
|
||||
| - required by a bound in this associated constant
|
||||
LL | where
|
||||
LL | Infallible: From<T>;
|
||||
| ^^^^^^^ required by this bound in `Trait::B`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -0,0 +1,12 @@
|
||||
#![feature(generic_const_items, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Ensure that we check if (makeshift) "evaluatable"-bounds on const items hold or not.
|
||||
|
||||
const POSITIVE<const N: usize>: usize = N
|
||||
where
|
||||
[(); N - 1]:; //~ ERROR evaluation of `POSITIVE::<0>::{constant#0}` failed
|
||||
|
||||
fn main() {
|
||||
let _ = POSITIVE::<0>;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
error[E0080]: evaluation of `POSITIVE::<0>::{constant#0}` failed
|
||||
--> $DIR/unsatisfied-evaluatable-bounds.rs:8:10
|
||||
|
|
||||
LL | [(); N - 1]:;
|
||||
| ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
17
tests/ui/generic-const-items/unsatisfied-outlives-bounds.rs
Normal file
17
tests/ui/generic-const-items/unsatisfied-outlives-bounds.rs
Normal file
@ -0,0 +1,17 @@
|
||||
#![feature(generic_const_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Ensure that we check if outlives-bounds on const items hold or not.
|
||||
|
||||
const C<'a, T: 'a>: () = ();
|
||||
const K<'a, 'b: 'a>: () = ();
|
||||
|
||||
fn parametrized0<'any>() {
|
||||
let () = C::<'static, &'any ()>; //~ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn parametrized1<'any>() {
|
||||
let () = K::<'static, 'any>; //~ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,18 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/unsatisfied-outlives-bounds.rs:10:14
|
||||
|
|
||||
LL | fn parametrized0<'any>() {
|
||||
| ---- lifetime `'any` defined here
|
||||
LL | let () = C::<'static, &'any ()>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ requires that `'any` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/unsatisfied-outlives-bounds.rs:14:14
|
||||
|
|
||||
LL | fn parametrized1<'any>() {
|
||||
| ---- lifetime `'any` defined here
|
||||
LL | let () = K::<'static, 'any>;
|
||||
| ^^^^^^^^^^^^^^^^^^ requires that `'any` must outlive `'static`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
4
tests/ui/parser/generic-statics.rs
Normal file
4
tests/ui/parser/generic-statics.rs
Normal file
@ -0,0 +1,4 @@
|
||||
static S<T>: i32 = 0;
|
||||
//~^ ERROR static items may not have generic parameters
|
||||
|
||||
fn main() {}
|
8
tests/ui/parser/generic-statics.stderr
Normal file
8
tests/ui/parser/generic-statics.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: static items may not have generic parameters
|
||||
--> $DIR/generic-statics.rs:1:9
|
||||
|
|
||||
LL | static S<T>: i32 = 0;
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user