Auto merge of #79135 - lcnr:the-paleogenesis-of-generic-germination, r=varkor

stabilize `#![feature(min_const_generics)]` in 1.51

*A new Kind*
*A Sort long Prophesized*
*Once Fragile, now Eternal*

blocked on #79073.

# Stabilization report

This is the stabilization report for `#![feature(min_const_generics)]` (tracking issue #74878), a subset of `#![feature(const_generics)]` (tracking issue #44580), based on rust-lang/rfcs#2000.

The [version target](https://forge.rust-lang.org/#current-release-versions) is ~~1.50 (2020-12-31 => beta, 2021-02-11 => stable)~~ 1.51 (2021-02-111 => beta, 2021-03-25 => stable).

This report is a collaborative effort of `@varkor,` `@shepmaster` and `@lcnr.`

## Summary

It is currently possible to parameterize functions, type aliases, types, traits and implementations by types and lifetimes.
With `#![feature(min_const_generics)]`, it becomes possible, in addition, to parameterize these by constants.

This is done using the syntax `const IDENT: Type` in the parameter listing. Unlike full const generics, `min_const_generics` is limited to parameterization by integers, and constants of type `char` or `bool`.

We already use `#![feature(min_const_generics)]` on stable to implement many common traits for arrays. See [the documentation](https://doc.rust-lang.org/nightly/std/primitive.array.html) for specific examples.

Generic const arguments, for now, are not permitted to involve computations depending on generic parameters. This means that const parameters may only be instantiated using either:

1. const expressions that do not depend on any generic parameters, e.g. `{ foo() + 1 }`, where `foo` is a `const fn`
1. standalone const parameters, e.g. `{N}`

### Example

```rust
#![feature(min_const_generics)]

trait Foo<const N: usize> {
    fn method<const M: usize>(&mut self, arr: [[u8; M]; N]);
}

struct Bar<T, const N: usize> {
    inner: [T; N],
}

impl<const N: usize> Foo<N> for Bar<u8, N> {
    fn method<const M: usize>(&mut self, arr: [[u8; M]; N]) {
        for (elem, s) in self.inner.iter_mut().zip(arr.iter()) {
            for &x in s {
                *elem &= x;
            }
        }
    }
}

fn function<const N: u16>() -> u16 {
    // Const parameters can be used freely inside of functions.
    (N + 1) / 2 * N
}

fn main() {
    let mut bar = Bar { inner: [0xff; 3] };
    // This infers the value of `M` from the type of the function argument.
    bar.method([[0b11_00, 0b01_00], [0b00_11, 0b00_01], [0b11_00, 0b00_11]]);
    assert_eq!(bar.inner, [0b01_00, 0b00_01, 0b00_00]);

    // You can also explicitly specify the value of `N`.
    assert_eq!(function::<17>(), 153);
}
```

## Motivation

Rust has the built-in array type, which is parametric over a constant. Without const generics, this type can be quite cumbersome to use as it is not possible to generically implement a trait for arrays of different lengths. For example, this meant that, for a long time, the standard library only contained trait implementations for arrays up to a length of 32. This restriction has since been lifted through the use of const generics.

Const parameters allow users to naturally specify variants of a generic type which are more naturally parameterized by values, rather than by types. For example, using const generics, many of the uses of the crate [typenum](https://crates.io/crates/typenum) may now be replaced with const parameters, improving compilation time as well as code readability and diagnostics.

The subset described by `min_const_generics` is self-contained, but extensive enough to help with the most frequent issues: implementing traits for arrays and using arbitrarily-sized arrays inside of other types. Furthermore, it extends naturally to full `const_generics` once the remaining design and implementation questions have been resolved.

## In-depth feature description

### Declaring const parameters

*Const parameters* are allowed in all places where types and lifetimes are supported. They use the syntax `const IDENT: Type`. Currently, const parameters must be declared after lifetime and type parameters. Their scope is equal to the scope of other generic parameters. They live in the value namespace.

`Type` must be one of `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`. This restriction is implemented in two places:

1. during name resolution, where we forbid generic parameters
1. during well-formedness checking, where we only allow the types listed above

The updated syntax of parameter listings is:

```
GenericParams:
    (OuterAttr* LifetimeParam),* (OuterAttr* TypeParam),* (OuterAttr* ConstParam),*

OuterAttr: '#[' ... ']'
LifetimeParam: ...
TypeParam: ...
ConstParam: 'const' IDENT ':' Type
```

Unlike type and lifetime parameters, const parameters of types can be used without being mentioned inside of a parameterized type because const parameters do not have issues concerning variance. This means that the following types are allowed:

```rust
struct Foo<const N: usize>;
enum Bar<const M: usize> { A, B }
```

### Const arguments

Const parameters are instantiated using *const arguments*. Any concrete const expression or const parameter as a standalone argument can be used. When applying an expression as const parameter, most expressions must be contained within a block, with two exceptions:

1. literals and single-segment path expressions
1. array lengths

This syntactic restriction is necessary to avoid ambiguity, or requiring infinite lookahead when parsing an expression as a generic argument.

In the cases where a generic argument could be resolved as either a type or const argument, we always interpret it as a type. This causes the following test to fail:

```rust
type N = u32;
struct Foo<const N: usize>;
fn foo<const N: usize>() -> Foo<N> { todo!() } // ERR
```

To circumvent this, the user may wrap the const parameter with braces, at which point it is unambiguously accepted.

```rust
type N = u32;
struct Foo<const N: usize>;
fn bar<const N: usize>() -> Foo<{ N }> { todo!() } // ok
```

Operations depending on generic parameters are **not** allowed, which is enforced during well-formedness checking. Allowing generic unevaluated constants would require a way to check if they would always evaluate successfully to prevent errors that are not caught at declaration time. This ability forms part of `#![feature(const_evaluatable_checked)]`, which is not yet being stabilised.

Since we are not yet stabilizing `#![feature(lazy_normalization_consts)]`, we must not supply the parent generics to anonymous constants except for repeat expressions. Doing so can cause cycle errors for arrays used in `where`-bounds. Not supplying the parent generics can however lead to ICEs occurring before well-formedness checking when trying to use a generic parameter. See #56445 for details.

Since we expect cases like this to occur more frequently once `min_const_generics` is stabilized, we have chosen to forbid generic parameters in anonymous constants during name resolution. While this changes the ICE in the situation above to an ordinary error, this is theoretically a breaking change, as early-bound lifetimes were previously permitted in repeat expressions but now are disallowed, causing the following snippet to break:

```rust
fn late_bound<'a>() {
    let _ = [0; {
        let _: &'a (); // ICE ==> ERR
        3
    }];
}

fn early_bound<'a>() where &'a (): Sized {
    let _ = [0; {
        let _: &'a (); // ok ==> ERR
        3
    }];
}
```

### Using const parameters

Const parameters can be used almost everywhere ordinary constants are allowed, except that they may not be used in the construction of consts, statics, functions, or types inside a function body and are subject to the generic argument restrictions mentioned above.

Expressions containing const parameters are eligible for promotion:

```rust
fn test<const N: usize>() -> &'static usize {
    &(3 + N)
}
```

### Symbol mangling

See the [Rust symbol name mangling RFC](https://rust-lang.github.io/rfcs/2603-rust-symbol-name-mangling-v0.html) for an overview. Generic const parameters take the form `K[type][value]` when the value is known, or `Kp` where the value is not known, where:
- `[type]` is any integral type, `bool`, or `char`.
- `[value]` is the unsigned hex value for integers, preceded by `n` when negative; is `0` or `1` for `bool`; is the hex value for `char`.

### Exhaustiveness checking

We do not check the exhaustiveness of impls, meaning that the following example does **not** compile:

```rust
struct Foo<const B: bool>;
trait Bar {}
impl Bar for Foo<true> {}
impl Bar for Foo<false> {}

fn needs_bar(_: impl Bar) {}
fn generic<const B: bool>() {
    let v = Foo::<B>;
    needs_bar(v);
}
```

### Type inference

The value of const parameters can be inferred during typeck. One interesting case is the length of generic arrays, which can also be inferred from patterns (implemented in #70562). Practical usage of this can be seen in #76825.

### Equality of constants

`#![feature(min_const_generics)]` only permits generic parameters to be used as standalone generic arguments. We compare two parameters to be equal if they are literally the same generic parameter.

### Associated constants

Associated constants can use const parameters without restriction, see https://github.com/rust-lang/rust/pull/79135#issuecomment-748299774 for more details.

## Future work

As this is a limited subset of rust-lang/rfcs#2000, there are quite a few extensions we will be looking into next.

### Lazy normalization of constants

Stabilizing `#![feature(lazy_normalization_consts)]` (tracking issue #72219) will remove some special cases that are currently necessary for `min_const_generics`, and unblocks operations on const parameters.

### Relaxing ordering requirements between const and type parameters

We currently restrict the order of generic parameters so that types must come before consts. We could relax this, as is currently done with `const_generics`. Without this it is not possible to use both type defaults and const parameters at the same time.

Unrestricting the order will require us to improve some diagnostics that expect there to be a strict order between type and const parameters.

### Allowing more parameter types

We would like to support const parameters of more types, especially`&str` and user-defined types. Both are blocked on [valtrees]. There are also open questions regarding the design of `structural_match` concerning the latter. Supporting generic const parameter types such as `struct Foo<T, const N: T>` will be a lot harder and is unlikely to be implemented in the near future.

### Default values of const parameters

We do not yet support default values for const parameters. There is work in progress to enable this on nightly (see https://github.com/rust-lang/rust/pull/75384).

### Generic const operations

With `#![feature(min_const_generics)]`, only concrete const expressions and parameters as standalone arguments are allowed in types and repeat expressions. However, supporting generic const operations, such as `N + 1` or `std::mem::size_of::<T>()` is highly desirable. This feature is in early development under `#![feature(const_evaluatable_checked)]`.

## Implementation history

Many people have contributed to the design and implementation of const generics over the last three years. See https://github.com/rust-lang/rust/issues/44580#issuecomment-728913127 for a summary. Once again thank you to everybody who helped out here!

[valtrees]: https://github.com/rust-lang/rust/issues/72396

---

r? `@varkor`
This commit is contained in:
bors 2020-12-27 07:05:56 +00:00
commit 1d517afcd0
478 changed files with 699 additions and 1118 deletions

View File

@ -16,7 +16,7 @@
#![feature(new_uninit)]
#![feature(maybe_uninit_slice)]
#![feature(array_value_iter)]
#![feature(min_const_generics)]
#![cfg_attr(bootstrap, feature(min_const_generics))]
#![feature(min_specialization)]
#![cfg_attr(test, feature(test))]

View File

@ -1128,7 +1128,7 @@ impl Expr {
/// Is this expr either `N`, or `{ N }`.
///
/// If this is not the case, name resolution does not resolve `N` when using
/// `feature(min_const_generics)` as more complex expressions are not supported.
/// `min_const_generics` as more complex expressions are not supported.
pub fn is_potential_trivial_const_param(&self) -> bool {
let this = if let ExprKind::Block(ref block, None) = self.kind {
if block.stmts.len() == 1 {

View File

@ -773,14 +773,12 @@ fn validate_generic_param_order<'a>(
err.span_suggestion(
span,
&format!(
"reorder the parameters: lifetimes{}",
"reorder the parameters: lifetimes, {}",
if sess.features_untracked().const_generics {
", then consts and types"
} else if sess.features_untracked().min_const_generics {
", then types, then consts"
"then consts and types"
} else {
", then types"
},
"then types, then consts"
}
),
ordered_params.clone(),
Applicability::MachineApplicable,

View File

@ -1,7 +1,7 @@
use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId};
use rustc_ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
use rustc_ast::{PatKind, RangeEnd, VariantData};
use rustc_errors::struct_span_err;
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
use rustc_feature::{Features, GateIssue};
@ -529,19 +529,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
visit::walk_fn(self, fn_kind, span)
}
fn visit_generic_param(&mut self, param: &'a GenericParam) {
if let GenericParamKind::Const { .. } = param.kind {
gate_feature_fn!(
&self,
|x: &Features| x.const_generics || x.min_const_generics,
param.ident.span,
sym::min_const_generics,
"const generics are unstable"
);
}
visit::walk_generic_param(self, param)
}
fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
if let AssocTyConstraintKind::Bound { .. } = constraint.kind {
gate_feature_post!(

View File

@ -27,7 +27,7 @@
#![feature(thread_id_value)]
#![feature(extend_one)]
#![feature(const_panic)]
#![feature(min_const_generics)]
#![cfg_attr(bootstrap, feature(min_const_generics))]
#![feature(new_uninit)]
#![feature(once_cell)]
#![feature(maybe_uninit_uninit_array)]

View File

@ -3,8 +3,6 @@ An array without a fixed length was pattern-matched.
Erroneous code example:
```compile_fail,E0730
#![feature(const_generics)]
fn is_123<const N: usize>(x: [u32; N]) -> bool {
match x {
[1, 2, ..] => true, // error: cannot pattern-match on an

View File

@ -10,6 +10,5 @@ fn foo<T, const N: T>() {} // error!
To fix this error, use a concrete type for the const parameter:
```
#![feature(const_generics)]
fn foo<T, const N: usize>() {}
```

View File

@ -273,6 +273,8 @@ declare_features! (
/// Allows patterns with concurrent by-move and by-ref bindings.
/// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
(accepted, move_ref_pattern, "1.48.0", Some(68354), None),
/// The smallest useful subset of `const_generics`.
(accepted, min_const_generics, "1.51.0", Some(74878), None),
// -------------------------------------------------------------------------
// feature-group-end: accepted features

View File

@ -578,9 +578,6 @@ declare_features! (
/// Allows calling `transmute` in const fn
(active, const_fn_transmute, "1.46.0", Some(53605), None),
/// The smallest useful subset of `const_generics`.
(active, min_const_generics, "1.47.0", Some(74878), None),
/// Allows `if let` guard in match arms.
(active, if_let_guard, "1.47.0", Some(51114), None),
@ -651,5 +648,7 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
/// Some features are not allowed to be used together at the same time, if
/// the two are present, produce an error.
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] =
&[(sym::const_generics, sym::min_const_generics)];
///
/// Currently empty, but we will probably need this again in the future,
/// so let's keep it in for now.
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[];

View File

@ -2299,7 +2299,7 @@ impl EarlyLintPass for IncompleteFeatures {
}
}
const HAS_MIN_FEATURES: &[Symbol] = &[sym::const_generics, sym::specialization];
const HAS_MIN_FEATURES: &[Symbol] = &[sym::specialization];
declare_lint! {
/// The `invalid_value` lint detects creating a value that is not valid,

View File

@ -1386,7 +1386,7 @@ impl<'tcx> TyCtxt<'tcx> {
#[inline]
pub fn lazy_normalization(self) -> bool {
let features = self.features();
// Note: We do not enable lazy normalization for `features.min_const_generics`.
// Note: We do not enable lazy normalization for `min_const_generics`.
features.const_generics || features.lazy_normalization_consts
}

View File

@ -1638,8 +1638,6 @@ pub type PlaceholderConst<'tcx> = Placeholder<BoundConst<'tcx>>;
/// which cause cycle errors.
///
/// ```rust
/// #![feature(const_generics)]
///
/// struct A;
/// impl A {
/// fn foo<const N: usize>(&self) -> [u8; N] { [0; N] }

View File

@ -5,7 +5,7 @@ use rustc_ast::{
self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause,
};
use rustc_errors::PResult;
use rustc_span::symbol::{kw, sym};
use rustc_span::symbol::kw;
impl<'a> Parser<'a> {
/// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@ -56,8 +56,6 @@ impl<'a> Parser<'a> {
self.expect(&token::Colon)?;
let ty = self.parse_ty()?;
self.sess.gated_spans.gate(sym::min_const_generics, const_span.to(self.prev_token.span));
Ok(GenericParam {
ident,
id: ast::DUMMY_NODE_ID,

View File

@ -1985,8 +1985,8 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
}
}
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics` so
/// this function will emit an error if `min_const_generics` is enabled, the body identified by
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
/// This function will emit an error if `const_generics` is not enabled, the body identified by
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
crate fn maybe_emit_forbidden_non_static_lifetime_error(
&self,
@ -2002,7 +2002,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore
);
if self.tcx.features().min_const_generics && is_anon_const && !is_allowed_lifetime {
if !self.tcx.lazy_normalization() && is_anon_const && !is_allowed_lifetime {
feature_err(
&self.tcx.sess.parse_sess,
sym::const_generics,

View File

@ -1769,8 +1769,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let result = loop {
match *scope {
Scope::Body { id, s } => {
// Non-static lifetimes are prohibited in anonymous constants under
// `min_const_generics`.
// Non-static lifetimes are prohibited in anonymous constants without
// `const_generics`.
self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref);
outermost_body = Some(id);

View File

@ -2624,8 +2624,12 @@ impl<'a> Resolver<'a> {
continue;
}
ConstantItemRibKind(trivial) => {
let features = self.session.features_untracked();
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
if !trivial && self.session.features_untracked().min_const_generics {
if !(trivial
|| features.const_generics
|| features.lazy_normalization_consts)
{
// HACK(min_const_generics): If we encounter `Self` in an anonymous constant
// we can't easily tell if it's generic at this stage, so we instead remember
// this and then enforce the self type to be concrete later on.
@ -2713,8 +2717,12 @@ impl<'a> Resolver<'a> {
continue;
}
ConstantItemRibKind(trivial) => {
let features = self.session.features_untracked();
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
if !trivial && self.session.features_untracked().min_const_generics {
if !(trivial
|| features.const_generics
|| features.lazy_normalization_consts)
{
if record_used {
self.report_error(
span,

View File

@ -13,7 +13,7 @@ Core encoding and decoding interfaces.
#![feature(never_type)]
#![feature(nll)]
#![feature(associated_type_bounds)]
#![feature(min_const_generics)]
#![cfg_attr(bootstrap, feature(min_const_generics))]
#![cfg_attr(test, feature(test))]
#![allow(rustc::internal)]

View File

@ -293,7 +293,13 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
let err_ty_str;
let mut is_ptr = true;
let err = if tcx.features().min_const_generics {
let err = if tcx.features().const_generics {
match ty.peel_refs().kind() {
ty::FnPtr(_) => Some("function pointers"),
ty::RawPtr(_) => Some("raw pointers"),
_ => None,
}
} else {
match ty.kind() {
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
ty::FnPtr(_) => Some("function pointers"),
@ -304,12 +310,6 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
Some(err_ty_str.as_str())
}
}
} else {
match ty.peel_refs().kind() {
ty::FnPtr(_) => Some("function pointers"),
ty::RawPtr(_) => Some("raw pointers"),
_ => None,
}
};
if let Some(unsupported_type) = err {
if is_ptr {

View File

@ -1260,7 +1260,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
//
// Note that we do not supply the parent generics when using
// `feature(min_const_generics)`.
// `min_const_generics`.
Some(parent_def_id.to_def_id())
} else {
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));

View File

@ -1,6 +1,5 @@
// check-pass
// edition:2018
#![feature(min_const_generics)]
trait ValidTrait {}
/// This has docs

View File

@ -1,7 +1,5 @@
// ignore-tidy-linelength
// edition:2018
#![feature(min_const_generics)]
// @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option<Foo>'
pub async fn foo() -> Option<Foo> {
None

View File

@ -1,6 +1,4 @@
// edition:2018
#![feature(min_const_generics)]
pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]> {
[[0; N]; N].iter().copied()
}

View File

@ -1,6 +1,5 @@
// edition:2018
// aux-build: extern_crate.rs
#![feature(min_const_generics)]
#![crate_name = "foo"]
extern crate extern_crate;

View File

@ -1,5 +1,4 @@
// ignore-tidy-linelength
#![feature(min_const_generics)]
#![crate_name = "foo"]
// @has foo/type.CellIndex.html '//pre[@class="rust typedef"]' 'type CellIndex<const D: usize> = [i64; D];'

View File

@ -6,7 +6,6 @@ LL | #![feature(const_generics)]
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
= help: consider using `min_const_generics` instead, which is more stable and complete
error[E0308]: mismatched types
--> $DIR/match_arr_unknown_len.rs:6:9

View File

@ -14,8 +14,7 @@ impl Foo for Def {
pub fn test<A: Foo, B: Foo>() {
let _array: [u32; <A as Foo>::Y];
//~^ ERROR the trait bound `A: Foo` is not satisfied [E0277]
//~^ ERROR generic parameters may not be used
}
fn main() {
}
fn main() {}

View File

@ -1,17 +1,11 @@
error[E0277]: the trait bound `A: Foo` is not satisfied
--> $DIR/associated-const-type-parameter-arrays.rs:16:23
error: generic parameters may not be used in const operations
--> $DIR/associated-const-type-parameter-arrays.rs:16:24
|
LL | const Y: usize;
| --------------- required by `Foo::Y`
...
LL | let _array: [u32; <A as Foo>::Y];
| ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
| ^ cannot perform const operation using `A`
|
help: consider further restricting this bound
|
LL | pub fn test<A: Foo + Foo, B: Foo>() {
| ^^^^^
= note: type parameters may not be used in const expressions
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -5,7 +5,7 @@ trait Adapter {
struct Foo<A: Adapter> {
adapter: A,
links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
//~^ ERROR: no associated item named `LINKS` found
//~^ ERROR generic parameters may not be used in const operations
}
fn main() {}

View File

@ -1,11 +1,11 @@
error[E0599]: no associated item named `LINKS` found for type parameter `A` in the current scope
--> $DIR/associated-item-duplicate-bounds.rs:7:21
error: generic parameters may not be used in const operations
--> $DIR/associated-item-duplicate-bounds.rs:7:18
|
LL | links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
| ^^^^^ associated item not found in `A`
| ^^^^^^^^ cannot perform const operation using `A`
|
= help: items from traits can only be used if the type parameter is bounded by the trait
= note: type parameters may not be used in const expressions
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: aborting due to previous error
For more information about this error, try `rustc --explain E0599`.

View File

@ -1,11 +1,11 @@
error[E0573]: expected type, found built-in attribute `feature`
--> $DIR/issue-78654.rs:10:15
--> $DIR/issue-78654.rs:9:15
|
LL | impl<const H: feature> Foo {
| ^^^^^^^ not a type
error[E0207]: the const parameter `H` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-78654.rs:10:12
--> $DIR/issue-78654.rs:9:12
|
LL | impl<const H: feature> Foo {
| ^ unconstrained const parameter

View File

@ -1,11 +1,11 @@
error[E0573]: expected type, found built-in attribute `feature`
--> $DIR/issue-78654.rs:10:15
--> $DIR/issue-78654.rs:9:15
|
LL | impl<const H: feature> Foo {
| ^^^^^^^ not a type
error[E0207]: the const parameter `H` is not constrained by the impl trait, self type, or predicates
--> $DIR/issue-78654.rs:10:12
--> $DIR/issue-78654.rs:9:12
|
LL | impl<const H: feature> Foo {
| ^ unconstrained const parameter

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
struct Foo;

View File

@ -0,0 +1,9 @@
error[E0158]: const parameters cannot be referenced in patterns
--> $DIR/const-param.rs:8:9
|
LL | N => {}
| ^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0158`.

View File

@ -0,0 +1,9 @@
error[E0158]: const parameters cannot be referenced in patterns
--> $DIR/const-param.rs:8:9
|
LL | N => {}
| ^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0158`.

View File

@ -1,6 +1,7 @@
// Identifier pattern referring to a const generic parameter is an error (issue #68853).
#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
fn check<const N: usize>() {
match 1 {

View File

@ -1,19 +0,0 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/const-param.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
= help: consider using `min_const_generics` instead, which is more stable and complete
error[E0158]: const parameters cannot be referenced in patterns
--> $DIR/const-param.rs:7:9
|
LL | N => {}
| ^
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0158`.

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
trait Trait {}

View File

@ -1,11 +1,11 @@
error: lifetime parameters must be declared prior to const parameters
--> $DIR/argument_order.rs:12:32
--> $DIR/argument_order.rs:11:32
|
LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
| -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>`
error[E0747]: lifetime provided when a type was expected
--> $DIR/argument_order.rs:20:23
--> $DIR/argument_order.rs:19:23
|
LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
| ^^^^^^^

View File

@ -1,23 +1,23 @@
error: type parameters must be declared prior to const parameters
--> $DIR/argument_order.rs:6:28
--> $DIR/argument_order.rs:5:28
|
LL | struct Bad<const N: usize, T> {
| -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
error: lifetime parameters must be declared prior to const parameters
--> $DIR/argument_order.rs:12:32
--> $DIR/argument_order.rs:11:32
|
LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
| -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`
error: type parameters must be declared prior to const parameters
--> $DIR/argument_order.rs:12:36
--> $DIR/argument_order.rs:11:36
|
LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
| ---------------------^----------------------^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`
error[E0747]: lifetime provided when a type was expected
--> $DIR/argument_order.rs:20:23
--> $DIR/argument_order.rs:19:23
|
LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
| ^^^^^^^

View File

@ -1,7 +1,6 @@
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
struct Bad<const N: usize, T> {
//[min]~^ ERROR type parameters must be declared prior to const parameters

View File

@ -1,5 +1,5 @@
error: constant expression depends on a generic parameter
--> $DIR/array-size-in-generic-struct-param.rs:9:38
--> $DIR/array-size-in-generic-struct-param.rs:8:38
|
LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
| ^^^^^^^^^^^^
@ -7,7 +7,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
--> $DIR/array-size-in-generic-struct-param.rs:20:10
--> $DIR/array-size-in-generic-struct-param.rs:19:10
|
LL | arr: [u8; CFG.arr_size],
| ^^^^^^^^^^^^^^^^^^

View File

@ -1,5 +1,5 @@
error: generic parameters may not be used in const operations
--> $DIR/array-size-in-generic-struct-param.rs:9:48
--> $DIR/array-size-in-generic-struct-param.rs:8:48
|
LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
| ^ cannot perform const operation using `N`
@ -8,7 +8,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: generic parameters may not be used in const operations
--> $DIR/array-size-in-generic-struct-param.rs:20:15
--> $DIR/array-size-in-generic-struct-param.rs:19:15
|
LL | arr: [u8; CFG.arr_size],
| ^^^ cannot perform const operation using `CFG`
@ -17,7 +17,7 @@ LL | arr: [u8; CFG.arr_size],
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: `Config` is forbidden as the type of a const generic parameter
--> $DIR/array-size-in-generic-struct-param.rs:18:21
--> $DIR/array-size-in-generic-struct-param.rs:17:21
|
LL | struct B<const CFG: Config> {
| ^^^^^^

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
#[allow(dead_code)]
struct ArithArrayLen<const N: usize>([u32; 0 + N]);

View File

@ -2,7 +2,6 @@
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
#![allow(dead_code)]

View File

@ -1,5 +1,5 @@
error[E0277]: the trait bound `u16: Bar<N>` is not satisfied
--> $DIR/associated-type-bound-fail.rs:14:5
--> $DIR/associated-type-bound-fail.rs:13:5
|
LL | type Assoc: Bar<N>;
| ------ required by this bound in `Foo::Assoc`

View File

@ -1,5 +1,5 @@
error[E0277]: the trait bound `u16: Bar<N>` is not satisfied
--> $DIR/associated-type-bound-fail.rs:14:5
--> $DIR/associated-type-bound-fail.rs:13:5
|
LL | type Assoc: Bar<N>;
| ------ required by this bound in `Foo::Assoc`

View File

@ -1,7 +1,6 @@
// revisions: full min
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(min, feature(min_const_generics))]
trait Bar<const N: usize> {}

View File

@ -2,7 +2,6 @@
// revisions: full min
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(min, feature(min_const_generics))]
trait Bar<const N: usize> {}

View File

@ -1,6 +1,5 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub struct Struct<const N: usize>(pub [u8; N]);

View File

@ -1,7 +1,6 @@
// edition:2018
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub trait Foo<const N: usize> {}
struct Local;

View File

@ -1,6 +1,5 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub struct Num<const N: usize>;

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub trait Foo {
fn foo(&self);

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
use std::fmt::Debug;

View File

@ -2,7 +2,6 @@
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
// This test confirms that the types can be inferred correctly for this example with const
// generics. Previously this would ICE, and more recently error.

View File

@ -1,5 +1,5 @@
error: expressions must be enclosed in braces to be used as const generic arguments
--> $DIR/closing-args-token.rs:11:9
--> $DIR/closing-args-token.rs:10:9
|
LL | S::<5 + 2 >> 7>;
| ^^^^^
@ -10,7 +10,7 @@ LL | S::<{ 5 + 2 } >> 7>;
| ^ ^
error: comparison operators cannot be chained
--> $DIR/closing-args-token.rs:11:16
--> $DIR/closing-args-token.rs:10:16
|
LL | S::<5 + 2 >> 7>;
| ^ ^
@ -21,7 +21,7 @@ LL | S::<5 + 2 >> 7 && 7>;
| ^^^^
error: comparison operators cannot be chained
--> $DIR/closing-args-token.rs:17:20
--> $DIR/closing-args-token.rs:16:20
|
LL | S::<{ 5 + 2 } >> 7>;
| ^ ^
@ -32,13 +32,13 @@ LL | S::<{ 5 + 2 } >> 7 && 7>;
| ^^^^
error: expected expression, found `;`
--> $DIR/closing-args-token.rs:22:16
--> $DIR/closing-args-token.rs:21:16
|
LL | T::<0 >= 3>;
| ^ expected expression
error: comparison operators cannot be chained
--> $DIR/closing-args-token.rs:28:12
--> $DIR/closing-args-token.rs:27:12
|
LL | T::<x >>= 2 > 0>;
| ^^ ^

View File

@ -1,5 +1,5 @@
error: expressions must be enclosed in braces to be used as const generic arguments
--> $DIR/closing-args-token.rs:11:9
--> $DIR/closing-args-token.rs:10:9
|
LL | S::<5 + 2 >> 7>;
| ^^^^^
@ -10,7 +10,7 @@ LL | S::<{ 5 + 2 } >> 7>;
| ^ ^
error: comparison operators cannot be chained
--> $DIR/closing-args-token.rs:11:16
--> $DIR/closing-args-token.rs:10:16
|
LL | S::<5 + 2 >> 7>;
| ^ ^
@ -21,7 +21,7 @@ LL | S::<5 + 2 >> 7 && 7>;
| ^^^^
error: comparison operators cannot be chained
--> $DIR/closing-args-token.rs:17:20
--> $DIR/closing-args-token.rs:16:20
|
LL | S::<{ 5 + 2 } >> 7>;
| ^ ^
@ -32,13 +32,13 @@ LL | S::<{ 5 + 2 } >> 7 && 7>;
| ^^^^
error: expected expression, found `;`
--> $DIR/closing-args-token.rs:22:16
--> $DIR/closing-args-token.rs:21:16
|
LL | T::<0 >= 3>;
| ^ expected expression
error: comparison operators cannot be chained
--> $DIR/closing-args-token.rs:28:12
--> $DIR/closing-args-token.rs:27:12
|
LL | T::<x >>= 2 > 0>;
| ^^ ^

View File

@ -2,7 +2,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
struct S<const X: u32>;
struct T<const X: bool>;

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
fn foo<const N: usize>(v: &[u8; N]) -> &[u8] {
v

View File

@ -4,7 +4,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
struct A<const N: usize>; // ok

View File

@ -5,7 +5,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
pub struct A<const N: u32>;

View File

@ -4,7 +4,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
trait IsZeroTrait<const IS_ZERO: bool>{}

View File

@ -1,5 +1,5 @@
error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:14:23
--> $DIR/const-arg-in-const-arg.rs:13:23
|
LL | let _: [u8; foo::<T>()];
| ^ cannot perform const operation using `T`
@ -8,7 +8,7 @@ LL | let _: [u8; foo::<T>()];
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:15:23
--> $DIR/const-arg-in-const-arg.rs:14:23
|
LL | let _: [u8; bar::<N>()];
| ^ cannot perform const operation using `N`
@ -17,7 +17,7 @@ LL | let _: [u8; bar::<N>()];
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:25:23
--> $DIR/const-arg-in-const-arg.rs:24:23
|
LL | let _ = [0; bar::<N>()];
| ^ cannot perform const operation using `N`
@ -26,7 +26,7 @@ LL | let _ = [0; bar::<N>()];
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:30:24
--> $DIR/const-arg-in-const-arg.rs:29:24
|
LL | let _: Foo<{ foo::<T>() }>;
| ^ cannot perform const operation using `T`
@ -35,7 +35,7 @@ LL | let _: Foo<{ foo::<T>() }>;
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:31:24
--> $DIR/const-arg-in-const-arg.rs:30:24
|
LL | let _: Foo<{ bar::<N>() }>;
| ^ cannot perform const operation using `N`
@ -44,7 +44,7 @@ LL | let _: Foo<{ bar::<N>() }>;
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:36:27
--> $DIR/const-arg-in-const-arg.rs:35:27
|
LL | let _ = Foo::<{ foo::<T>() }>;
| ^ cannot perform const operation using `T`
@ -53,7 +53,7 @@ LL | let _ = Foo::<{ foo::<T>() }>;
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:37:27
--> $DIR/const-arg-in-const-arg.rs:36:27
|
LL | let _ = Foo::<{ bar::<N>() }>;
| ^ cannot perform const operation using `N`
@ -62,7 +62,7 @@ LL | let _ = Foo::<{ bar::<N>() }>;
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:16:23
--> $DIR/const-arg-in-const-arg.rs:15:23
|
LL | let _: [u8; faz::<'a>(&())];
| ^^
@ -71,7 +71,7 @@ LL | let _: [u8; faz::<'a>(&())];
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:17:23
--> $DIR/const-arg-in-const-arg.rs:16:23
|
LL | let _: [u8; baz::<'a>(&())];
| ^^
@ -80,7 +80,7 @@ LL | let _: [u8; baz::<'a>(&())];
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:18:23
--> $DIR/const-arg-in-const-arg.rs:17:23
|
LL | let _: [u8; faz::<'b>(&())];
| ^^
@ -89,7 +89,7 @@ LL | let _: [u8; faz::<'b>(&())];
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:19:23
--> $DIR/const-arg-in-const-arg.rs:18:23
|
LL | let _: [u8; baz::<'b>(&())];
| ^^
@ -98,7 +98,7 @@ LL | let _: [u8; baz::<'b>(&())];
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:26:23
--> $DIR/const-arg-in-const-arg.rs:25:23
|
LL | let _ = [0; faz::<'a>(&())];
| ^^
@ -107,7 +107,7 @@ LL | let _ = [0; faz::<'a>(&())];
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:27:23
--> $DIR/const-arg-in-const-arg.rs:26:23
|
LL | let _ = [0; baz::<'a>(&())];
| ^^
@ -116,7 +116,7 @@ LL | let _ = [0; baz::<'a>(&())];
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:28:23
--> $DIR/const-arg-in-const-arg.rs:27:23
|
LL | let _ = [0; faz::<'b>(&())];
| ^^
@ -125,7 +125,7 @@ LL | let _ = [0; faz::<'b>(&())];
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:29:23
--> $DIR/const-arg-in-const-arg.rs:28:23
|
LL | let _ = [0; baz::<'b>(&())];
| ^^
@ -134,7 +134,7 @@ LL | let _ = [0; baz::<'b>(&())];
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:32:24
--> $DIR/const-arg-in-const-arg.rs:31:24
|
LL | let _: Foo<{ faz::<'a>(&()) }>;
| ^^
@ -143,7 +143,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>;
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:33:24
--> $DIR/const-arg-in-const-arg.rs:32:24
|
LL | let _: Foo<{ baz::<'a>(&()) }>;
| ^^
@ -152,7 +152,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>;
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:34:24
--> $DIR/const-arg-in-const-arg.rs:33:24
|
LL | let _: Foo<{ faz::<'b>(&()) }>;
| ^^
@ -161,7 +161,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>;
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:35:24
--> $DIR/const-arg-in-const-arg.rs:34:24
|
LL | let _: Foo<{ baz::<'b>(&()) }>;
| ^^
@ -170,7 +170,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>;
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:38:27
--> $DIR/const-arg-in-const-arg.rs:37:27
|
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
| ^^
@ -179,7 +179,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>;
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:39:27
--> $DIR/const-arg-in-const-arg.rs:38:27
|
LL | let _ = Foo::<{ baz::<'a>(&()) }>;
| ^^
@ -188,7 +188,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>;
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:40:27
--> $DIR/const-arg-in-const-arg.rs:39:27
|
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
| ^^
@ -197,7 +197,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>;
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/const-arg-in-const-arg.rs:41:27
--> $DIR/const-arg-in-const-arg.rs:40:27
|
LL | let _ = Foo::<{ baz::<'b>(&()) }>;
| ^^

View File

@ -2,7 +2,6 @@
// FIXME(const_generics): This test currently causes an ICE because
// we don't yet correctly deal with lifetimes, reenable this test once
// this is fixed.
#![cfg_attr(min, feature(min_const_generics))]
const fn foo<T>() -> usize { std::mem::size_of::<T>() }
const fn bar<const N: usize>() -> usize { N }

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
fn const_u32_identity<const X: u32>() -> u32 {
X

View File

@ -1,5 +1,5 @@
error[E0747]: constant provided when a type was expected
--> $DIR/const-arg-type-arg-misordered.rs:8:35
--> $DIR/const-arg-type-arg-misordered.rs:7:35
|
LL | fn foo<const N: usize>() -> Array<N, ()> {
| ^

View File

@ -1,5 +1,5 @@
error[E0747]: constant provided when a type was expected
--> $DIR/const-arg-type-arg-misordered.rs:8:35
--> $DIR/const-arg-type-arg-misordered.rs:7:35
|
LL | fn foo<const N: usize>() -> Array<N, ()> {
| ^

View File

@ -1,7 +1,6 @@
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
type Array<T, const N: usize> = [T; N];

View File

@ -1,5 +1,5 @@
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/const-argument-if-length.rs:8:28
--> $DIR/const-argument-if-length.rs:7:28
|
LL | pub const fn is_zst<T: ?Sized>() -> usize {
| - this type parameter needs to be `Sized`
@ -12,7 +12,7 @@ LL | pub const fn size_of<T>() -> usize {
| - required by this bound in `std::mem::size_of`
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/const-argument-if-length.rs:17:12
--> $DIR/const-argument-if-length.rs:16:12
|
LL | pub struct AtLeastByte<T: ?Sized> {
| - this type parameter needs to be `Sized`

View File

@ -1,5 +1,5 @@
error: generic parameters may not be used in const operations
--> $DIR/const-argument-if-length.rs:19:24
--> $DIR/const-argument-if-length.rs:18:24
|
LL | pad: [u8; is_zst::<T>()],
| ^ cannot perform const operation using `T`
@ -8,7 +8,7 @@ LL | pad: [u8; is_zst::<T>()],
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/const-argument-if-length.rs:17:12
--> $DIR/const-argument-if-length.rs:16:12
|
LL | pub struct AtLeastByte<T: ?Sized> {
| - this type parameter needs to be `Sized`

View File

@ -2,7 +2,6 @@
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(min, feature(min_const_generics))]
pub const fn is_zst<T: ?Sized>() -> usize {
if std::mem::size_of::<T>() == 0 {

View File

@ -1,5 +1,5 @@
error: expressions must be enclosed in braces to be used as const generic arguments
--> $DIR/const-expression-parameter.rs:16:20
--> $DIR/const-expression-parameter.rs:15:20
|
LL | i32_identity::<1 + 2>();
| ^^^^^

View File

@ -1,5 +1,5 @@
error: expressions must be enclosed in braces to be used as const generic arguments
--> $DIR/const-expression-parameter.rs:16:20
--> $DIR/const-expression-parameter.rs:15:20
|
LL | i32_identity::<1 + 2>();
| ^^^^^

View File

@ -2,7 +2,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
fn i32_identity<const X: i32>() -> i32 {
5

View File

@ -4,7 +4,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
const fn const_u32_identity<const X: u32>() -> u32 {
X

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
struct Foo<T, const N: usize>([T; N]);

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
#[derive(Debug)]
struct S<const N: usize>;

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
struct Foo<const A: usize, const B: usize>;

View File

@ -1,5 +1,5 @@
error: lifetime parameters must be declared prior to const parameters
--> $DIR/const-param-before-other-params.rs:6:21
--> $DIR/const-param-before-other-params.rs:5:21
|
LL | fn bar<const X: (), 'a>(_: &'a ()) {
| --------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const X: ()>`

View File

@ -1,17 +1,17 @@
error: lifetime parameters must be declared prior to const parameters
--> $DIR/const-param-before-other-params.rs:6:21
--> $DIR/const-param-before-other-params.rs:5:21
|
LL | fn bar<const X: (), 'a>(_: &'a ()) {
| --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>`
error: type parameters must be declared prior to const parameters
--> $DIR/const-param-before-other-params.rs:11:21
--> $DIR/const-param-before-other-params.rs:10:21
|
LL | fn foo<const X: (), T>(_: &T) {}
| --------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const X: ()>`
error: `()` is forbidden as the type of a const generic parameter
--> $DIR/const-param-before-other-params.rs:6:17
--> $DIR/const-param-before-other-params.rs:5:17
|
LL | fn bar<const X: (), 'a>(_: &'a ()) {
| ^^
@ -20,7 +20,7 @@ LL | fn bar<const X: (), 'a>(_: &'a ()) {
= help: more complex types are supported with `#[feature(const_generics)]`
error: `()` is forbidden as the type of a const generic parameter
--> $DIR/const-param-before-other-params.rs:11:17
--> $DIR/const-param-before-other-params.rs:10:17
|
LL | fn foo<const X: (), T>(_: &T) {}
| ^^

View File

@ -1,7 +1,6 @@
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
fn bar<const X: (), 'a>(_: &'a ()) {
//~^ ERROR lifetime parameters must be declared prior to const parameters

View File

@ -1,29 +1,29 @@
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:11:19
--> $DIR/const-param-elided-lifetime.rs:10:19
|
LL | struct A<const N: &u8>;
| ^ explicit lifetime name needed here
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:16:15
--> $DIR/const-param-elided-lifetime.rs:15:15
|
LL | impl<const N: &u8> A<N> {
| ^ explicit lifetime name needed here
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:19:21
--> $DIR/const-param-elided-lifetime.rs:18:21
|
LL | fn foo<const M: &u8>(&self) {}
| ^ explicit lifetime name needed here
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:24:15
--> $DIR/const-param-elided-lifetime.rs:23:15
|
LL | impl<const N: &u8> B for A<N> {}
| ^ explicit lifetime name needed here
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:28:17
--> $DIR/const-param-elided-lifetime.rs:27:17
|
LL | fn bar<const N: &u8>() {}
| ^ explicit lifetime name needed here

View File

@ -1,35 +1,35 @@
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:11:19
--> $DIR/const-param-elided-lifetime.rs:10:19
|
LL | struct A<const N: &u8>;
| ^ explicit lifetime name needed here
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:16:15
--> $DIR/const-param-elided-lifetime.rs:15:15
|
LL | impl<const N: &u8> A<N> {
| ^ explicit lifetime name needed here
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:19:21
--> $DIR/const-param-elided-lifetime.rs:18:21
|
LL | fn foo<const M: &u8>(&self) {}
| ^ explicit lifetime name needed here
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:24:15
--> $DIR/const-param-elided-lifetime.rs:23:15
|
LL | impl<const N: &u8> B for A<N> {}
| ^ explicit lifetime name needed here
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/const-param-elided-lifetime.rs:28:17
--> $DIR/const-param-elided-lifetime.rs:27:17
|
LL | fn bar<const N: &u8>() {}
| ^ explicit lifetime name needed here
error: `&'static u8` is forbidden as the type of a const generic parameter
--> $DIR/const-param-elided-lifetime.rs:11:19
--> $DIR/const-param-elided-lifetime.rs:10:19
|
LL | struct A<const N: &u8>;
| ^^^
@ -38,7 +38,7 @@ LL | struct A<const N: &u8>;
= help: more complex types are supported with `#[feature(const_generics)]`
error: `&'static u8` is forbidden as the type of a const generic parameter
--> $DIR/const-param-elided-lifetime.rs:16:15
--> $DIR/const-param-elided-lifetime.rs:15:15
|
LL | impl<const N: &u8> A<N> {
| ^^^
@ -47,7 +47,7 @@ LL | impl<const N: &u8> A<N> {
= help: more complex types are supported with `#[feature(const_generics)]`
error: `&'static u8` is forbidden as the type of a const generic parameter
--> $DIR/const-param-elided-lifetime.rs:24:15
--> $DIR/const-param-elided-lifetime.rs:23:15
|
LL | impl<const N: &u8> B for A<N> {}
| ^^^
@ -56,7 +56,7 @@ LL | impl<const N: &u8> B for A<N> {}
= help: more complex types are supported with `#[feature(const_generics)]`
error: `&'static u8` is forbidden as the type of a const generic parameter
--> $DIR/const-param-elided-lifetime.rs:28:17
--> $DIR/const-param-elided-lifetime.rs:27:17
|
LL | fn bar<const N: &u8>() {}
| ^^^
@ -65,7 +65,7 @@ LL | fn bar<const N: &u8>() {}
= help: more complex types are supported with `#[feature(const_generics)]`
error: `&'static u8` is forbidden as the type of a const generic parameter
--> $DIR/const-param-elided-lifetime.rs:19:21
--> $DIR/const-param-elided-lifetime.rs:18:21
|
LL | fn foo<const M: &u8>(&self) {}
| ^^^

View File

@ -6,7 +6,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
struct A<const N: &u8>;
//~^ ERROR `&` without an explicit lifetime name cannot be used here

View File

@ -1,5 +1,5 @@
error[E0401]: can't use generic parameters from outer function
--> $DIR/const-param-from-outer-fn.rs:9:9
--> $DIR/const-param-from-outer-fn.rs:8:9
|
LL | fn foo<const X: u32>() {
| - const parameter from outer function

View File

@ -1,5 +1,5 @@
error[E0401]: can't use generic parameters from outer function
--> $DIR/const-param-from-outer-fn.rs:9:9
--> $DIR/const-param-from-outer-fn.rs:8:9
|
LL | fn foo<const X: u32>() {
| - const parameter from outer function

View File

@ -2,7 +2,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
fn foo<const X: u32>() {
fn bar() -> u32 {

View File

@ -3,7 +3,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
macro_rules! bar {
($($t:tt)*) => { impl<const N: usize> $($t)* };

View File

@ -3,7 +3,6 @@
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
async fn foo<const N: usize>(arg: [u8; N]) -> usize { arg.len() }

View File

@ -1,3 +0,0 @@
trait Trait<const T: ()> {} //~ ERROR const generics are unstable
fn main() {}

View File

@ -1,12 +0,0 @@
error[E0658]: const generics are unstable
--> $DIR/const-param-in-trait-ungated.rs:1:19
|
LL | trait Trait<const T: ()> {}
| ^
|
= note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
= help: add `#![feature(min_const_generics)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -4,7 +4,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
trait Trait<const T: u8> {}

View File

@ -1,5 +1,3 @@
#![feature(min_const_generics)]
type N = u32;
struct Foo<const M: usize>;
fn test<const N: usize>() -> Foo<N> { //~ ERROR type provided when

View File

@ -1,5 +1,5 @@
error[E0747]: type provided when a constant was expected
--> $DIR/const-param-shadowing.rs:5:34
--> $DIR/const-param-shadowing.rs:3:34
|
LL | fn test<const N: usize>() -> Foo<N> {
| ^

View File

@ -1,11 +1,11 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:12:52
--> $DIR/const-param-type-depends-on-const-param.rs:11:52
|
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
| ^ the type must not depend on the parameter `N`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:16:40
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
|
LL | pub struct SelfDependent<const N: [u8; N]>;
| ^ the type must not depend on the parameter `N`

View File

@ -1,17 +1,17 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:12:52
--> $DIR/const-param-type-depends-on-const-param.rs:11:52
|
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
| ^ the type must not depend on the parameter `N`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:16:40
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
|
LL | pub struct SelfDependent<const N: [u8; N]>;
| ^ the type must not depend on the parameter `N`
error: `[u8; _]` is forbidden as the type of a const generic parameter
--> $DIR/const-param-type-depends-on-const-param.rs:12:47
--> $DIR/const-param-type-depends-on-const-param.rs:11:47
|
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
| ^^^^^^^
@ -20,7 +20,7 @@ LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
= help: more complex types are supported with `#[feature(const_generics)]`
error: `[u8; _]` is forbidden as the type of a const generic parameter
--> $DIR/const-param-type-depends-on-const-param.rs:16:35
--> $DIR/const-param-type-depends-on-const-param.rs:15:35
|
LL | pub struct SelfDependent<const N: [u8; N]>;
| ^^^^^^^

View File

@ -2,7 +2,6 @@
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
// Currently, const parameters cannot depend on other generic parameters,
// as our current implementation can't really support this.

View File

@ -3,7 +3,7 @@
use std::marker::PhantomData;
struct B<T, const N: T>(PhantomData<[T; N]>); //~ ERROR const generics are unstable
struct B<T, const N: T>(PhantomData<[T; N]>);
//~^ ERROR the type of const parameters must not depend on other generic parameters
fn main() {}

View File

@ -4,16 +4,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
LL | struct B<T, const N: T>(PhantomData<[T; N]>);
| ^ the type must not depend on the parameter `T`
error[E0658]: const generics are unstable
--> $DIR/const-param-type-depends-on-type-param-ungated.rs:6:19
|
LL | struct B<T, const N: T>(PhantomData<[T; N]>);
| ^
|
= note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
= help: add `#![feature(min_const_generics)]` to the crate attributes to enable
error: aborting due to previous error
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0658, E0770.
For more information about an error, try `rustc --explain E0658`.
For more information about this error, try `rustc --explain E0770`.

View File

@ -1,11 +1,11 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-type-param.rs:12:34
--> $DIR/const-param-type-depends-on-type-param.rs:11:34
|
LL | pub struct Dependent<T, const X: T>([(); X]);
| ^ the type must not depend on the parameter `T`
error[E0392]: parameter `T` is never used
--> $DIR/const-param-type-depends-on-type-param.rs:12:22
--> $DIR/const-param-type-depends-on-type-param.rs:11:22
|
LL | pub struct Dependent<T, const X: T>([(); X]);
| ^ unused parameter

View File

@ -1,11 +1,11 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-type-param.rs:12:34
--> $DIR/const-param-type-depends-on-type-param.rs:11:34
|
LL | pub struct Dependent<T, const X: T>([(); X]);
| ^ the type must not depend on the parameter `T`
error[E0392]: parameter `T` is never used
--> $DIR/const-param-type-depends-on-type-param.rs:12:22
--> $DIR/const-param-type-depends-on-type-param.rs:11:22
|
LL | pub struct Dependent<T, const X: T>([(); X]);
| ^ unused parameter

Some files were not shown because too many files have changed in this diff Show More