Add UI tests for generic const items

This commit is contained in:
León Orell Valerian Liehr 2023-07-10 03:10:03 +02:00
parent a011dd9dac
commit 6636916b66
No known key found for this signature in database
GPG key ID: D17A07215F68E713
34 changed files with 826 additions and 1 deletions

View file

@ -11,7 +11,7 @@
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

View 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(());
}

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

View 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() {}

View 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`.

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

View 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() {}

View 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

View 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() {}

View 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`.

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

View file

@ -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

View file

@ -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() {}

View file

@ -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`.

View 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() {}

View 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`.

View 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() {}

View 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() {}

View 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

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

View 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

View 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::<()>;
}

View file

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

View file

@ -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`.

View file

@ -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() {}

View file

@ -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`.

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

View 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`.

View file

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

View file

@ -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`.

View 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() {}

View file

@ -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

View file

@ -0,0 +1,4 @@
static S<T>: i32 = 0;
//~^ ERROR static items may not have generic parameters
fn main() {}

View 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