Skip to content

Commit 1d517af

Browse files
committed
Auto merge of rust-lang#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 rust-lang#79073. # Stabilization report This is the stabilization report for `#![feature(min_const_generics)]` (tracking issue rust-lang#74878), a subset of `#![feature(const_generics)]` (tracking issue rust-lang#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 rust-lang#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 rust-lang#70562). Practical usage of this can be seen in rust-lang#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 rust-lang#79135 (comment) 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 rust-lang#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 rust-lang#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 rust-lang#44580 (comment) for a summary. Once again thank you to everybody who helped out here! [valtrees]: rust-lang#72396 --- r? `@varkor`
2 parents 0f42d47 + c4ba60a commit 1d517af

File tree

478 files changed

+699
-1118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

478 files changed

+699
-1118
lines changed

compiler/rustc_arena/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#![feature(new_uninit)]
1717
#![feature(maybe_uninit_slice)]
1818
#![feature(array_value_iter)]
19-
#![feature(min_const_generics)]
19+
#![cfg_attr(bootstrap, feature(min_const_generics))]
2020
#![feature(min_specialization)]
2121
#![cfg_attr(test, feature(test))]
2222

compiler/rustc_ast/src/ast.rs

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

compiler/rustc_ast_passes/src/ast_validation.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -773,14 +773,12 @@ fn validate_generic_param_order<'a>(
773773
err.span_suggestion(
774774
span,
775775
&format!(
776-
"reorder the parameters: lifetimes{}",
776+
"reorder the parameters: lifetimes, {}",
777777
if sess.features_untracked().const_generics {
778-
", then consts and types"
779-
} else if sess.features_untracked().min_const_generics {
780-
", then types, then consts"
778+
"then consts and types"
781779
} else {
782-
", then types"
783-
},
780+
"then types, then consts"
781+
}
784782
),
785783
ordered_params.clone(),
786784
Applicability::MachineApplicable,

compiler/rustc_ast_passes/src/feature_gate.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_ast as ast;
22
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
33
use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId};
4-
use rustc_ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
4+
use rustc_ast::{PatKind, RangeEnd, VariantData};
55
use rustc_errors::struct_span_err;
66
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
77
use rustc_feature::{Features, GateIssue};
@@ -529,19 +529,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
529529
visit::walk_fn(self, fn_kind, span)
530530
}
531531

532-
fn visit_generic_param(&mut self, param: &'a GenericParam) {
533-
if let GenericParamKind::Const { .. } = param.kind {
534-
gate_feature_fn!(
535-
&self,
536-
|x: &Features| x.const_generics || x.min_const_generics,
537-
param.ident.span,
538-
sym::min_const_generics,
539-
"const generics are unstable"
540-
);
541-
}
542-
visit::walk_generic_param(self, param)
543-
}
544-
545532
fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
546533
if let AssocTyConstraintKind::Bound { .. } = constraint.kind {
547534
gate_feature_post!(

compiler/rustc_data_structures/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#![feature(thread_id_value)]
2828
#![feature(extend_one)]
2929
#![feature(const_panic)]
30-
#![feature(min_const_generics)]
30+
#![cfg_attr(bootstrap, feature(min_const_generics))]
3131
#![feature(new_uninit)]
3232
#![feature(once_cell)]
3333
#![feature(maybe_uninit_uninit_array)]

compiler/rustc_error_codes/src/error_codes/E0730.md

-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ An array without a fixed length was pattern-matched.
33
Erroneous code example:
44

55
```compile_fail,E0730
6-
#![feature(const_generics)]
7-
86
fn is_123<const N: usize>(x: [u32; N]) -> bool {
97
match x {
108
[1, 2, ..] => true, // error: cannot pattern-match on an

compiler/rustc_error_codes/src/error_codes/E0770.md

-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@ fn foo<T, const N: T>() {} // error!
1010
To fix this error, use a concrete type for the const parameter:
1111

1212
```
13-
#![feature(const_generics)]
1413
fn foo<T, const N: usize>() {}
1514
```

compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ declare_features! (
273273
/// Allows patterns with concurrent by-move and by-ref bindings.
274274
/// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
275275
(accepted, move_ref_pattern, "1.48.0", Some(68354), None),
276+
/// The smallest useful subset of `const_generics`.
277+
(accepted, min_const_generics, "1.51.0", Some(74878), None),
276278

277279
// -------------------------------------------------------------------------
278280
// feature-group-end: accepted features

compiler/rustc_feature/src/active.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -578,9 +578,6 @@ declare_features! (
578578
/// Allows calling `transmute` in const fn
579579
(active, const_fn_transmute, "1.46.0", Some(53605), None),
580580

581-
/// The smallest useful subset of `const_generics`.
582-
(active, min_const_generics, "1.47.0", Some(74878), None),
583-
584581
/// Allows `if let` guard in match arms.
585582
(active, if_let_guard, "1.47.0", Some(51114), None),
586583

@@ -651,5 +648,7 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
651648

652649
/// Some features are not allowed to be used together at the same time, if
653650
/// the two are present, produce an error.
654-
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] =
655-
&[(sym::const_generics, sym::min_const_generics)];
651+
///
652+
/// Currently empty, but we will probably need this again in the future,
653+
/// so let's keep it in for now.
654+
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[];

compiler/rustc_lint/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2299,7 +2299,7 @@ impl EarlyLintPass for IncompleteFeatures {
22992299
}
23002300
}
23012301

2302-
const HAS_MIN_FEATURES: &[Symbol] = &[sym::const_generics, sym::specialization];
2302+
const HAS_MIN_FEATURES: &[Symbol] = &[sym::specialization];
23032303

23042304
declare_lint! {
23052305
/// The `invalid_value` lint detects creating a value that is not valid,

compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,7 @@ impl<'tcx> TyCtxt<'tcx> {
13861386
#[inline]
13871387
pub fn lazy_normalization(self) -> bool {
13881388
let features = self.features();
1389-
// Note: We do not enable lazy normalization for `features.min_const_generics`.
1389+
// Note: We do not enable lazy normalization for `min_const_generics`.
13901390
features.const_generics || features.lazy_normalization_consts
13911391
}
13921392

compiler/rustc_middle/src/ty/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1638,8 +1638,6 @@ pub type PlaceholderConst<'tcx> = Placeholder<BoundConst<'tcx>>;
16381638
/// which cause cycle errors.
16391639
///
16401640
/// ```rust
1641-
/// #![feature(const_generics)]
1642-
///
16431641
/// struct A;
16441642
/// impl A {
16451643
/// fn foo<const N: usize>(&self) -> [u8; N] { [0; N] }

compiler/rustc_parse/src/parser/generics.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::{
55
self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause,
66
};
77
use rustc_errors::PResult;
8-
use rustc_span::symbol::{kw, sym};
8+
use rustc_span::symbol::kw;
99

1010
impl<'a> Parser<'a> {
1111
/// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@@ -56,8 +56,6 @@ impl<'a> Parser<'a> {
5656
self.expect(&token::Colon)?;
5757
let ty = self.parse_ty()?;
5858

59-
self.sess.gated_spans.gate(sym::min_const_generics, const_span.to(self.prev_token.span));
60-
6159
Ok(GenericParam {
6260
ident,
6361
id: ast::DUMMY_NODE_ID,

compiler/rustc_resolve/src/late/diagnostics.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1985,8 +1985,8 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
19851985
}
19861986
}
19871987

1988-
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics` so
1989-
/// this function will emit an error if `min_const_generics` is enabled, the body identified by
1988+
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
1989+
/// This function will emit an error if `const_generics` is not enabled, the body identified by
19901990
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
19911991
crate fn maybe_emit_forbidden_non_static_lifetime_error(
19921992
&self,
@@ -2002,7 +2002,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
20022002
hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore
20032003
);
20042004

2005-
if self.tcx.features().min_const_generics && is_anon_const && !is_allowed_lifetime {
2005+
if !self.tcx.lazy_normalization() && is_anon_const && !is_allowed_lifetime {
20062006
feature_err(
20072007
&self.tcx.sess.parse_sess,
20082008
sym::const_generics,

compiler/rustc_resolve/src/late/lifetimes.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1769,8 +1769,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
17691769
let result = loop {
17701770
match *scope {
17711771
Scope::Body { id, s } => {
1772-
// Non-static lifetimes are prohibited in anonymous constants under
1773-
// `min_const_generics`.
1772+
// Non-static lifetimes are prohibited in anonymous constants without
1773+
// `const_generics`.
17741774
self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref);
17751775

17761776
outermost_body = Some(id);

compiler/rustc_resolve/src/lib.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -2624,8 +2624,12 @@ impl<'a> Resolver<'a> {
26242624
continue;
26252625
}
26262626
ConstantItemRibKind(trivial) => {
2627+
let features = self.session.features_untracked();
26272628
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
2628-
if !trivial && self.session.features_untracked().min_const_generics {
2629+
if !(trivial
2630+
|| features.const_generics
2631+
|| features.lazy_normalization_consts)
2632+
{
26292633
// HACK(min_const_generics): If we encounter `Self` in an anonymous constant
26302634
// we can't easily tell if it's generic at this stage, so we instead remember
26312635
// this and then enforce the self type to be concrete later on.
@@ -2713,8 +2717,12 @@ impl<'a> Resolver<'a> {
27132717
continue;
27142718
}
27152719
ConstantItemRibKind(trivial) => {
2720+
let features = self.session.features_untracked();
27162721
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
2717-
if !trivial && self.session.features_untracked().min_const_generics {
2722+
if !(trivial
2723+
|| features.const_generics
2724+
|| features.lazy_normalization_consts)
2725+
{
27182726
if record_used {
27192727
self.report_error(
27202728
span,

compiler/rustc_serialize/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Core encoding and decoding interfaces.
1313
#![feature(never_type)]
1414
#![feature(nll)]
1515
#![feature(associated_type_bounds)]
16-
#![feature(min_const_generics)]
16+
#![cfg_attr(bootstrap, feature(min_const_generics))]
1717
#![cfg_attr(test, feature(test))]
1818
#![allow(rustc::internal)]
1919

compiler/rustc_typeck/src/check/wfcheck.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,13 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
293293

294294
let err_ty_str;
295295
let mut is_ptr = true;
296-
let err = if tcx.features().min_const_generics {
296+
let err = if tcx.features().const_generics {
297+
match ty.peel_refs().kind() {
298+
ty::FnPtr(_) => Some("function pointers"),
299+
ty::RawPtr(_) => Some("raw pointers"),
300+
_ => None,
301+
}
302+
} else {
297303
match ty.kind() {
298304
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
299305
ty::FnPtr(_) => Some("function pointers"),
@@ -304,12 +310,6 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
304310
Some(err_ty_str.as_str())
305311
}
306312
}
307-
} else {
308-
match ty.peel_refs().kind() {
309-
ty::FnPtr(_) => Some("function pointers"),
310-
ty::RawPtr(_) => Some("raw pointers"),
311-
_ => None,
312-
}
313313
};
314314
if let Some(unsupported_type) = err {
315315
if is_ptr {

compiler/rustc_typeck/src/collect.rs

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

src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// check-pass
22
// edition:2018
3-
#![feature(min_const_generics)]
43
trait ValidTrait {}
54

65
/// This has docs

src/test/rustdoc/async-fn.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
// ignore-tidy-linelength
22
// edition:2018
3-
#![feature(min_const_generics)]
4-
53
// @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option<Foo>'
64
pub async fn foo() -> Option<Foo> {
75
None

src/test/rustdoc/const-generics/auxiliary/extern_crate.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
// edition:2018
2-
#![feature(min_const_generics)]
3-
42
pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]> {
53
[[0; N]; N].iter().copied()
64
}

src/test/rustdoc/const-generics/const-generics-docs.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// edition:2018
22
// aux-build: extern_crate.rs
3-
#![feature(min_const_generics)]
43
#![crate_name = "foo"]
54

65
extern crate extern_crate;

src/test/rustdoc/const-generics/type-alias.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// ignore-tidy-linelength
2-
#![feature(min_const_generics)]
32
#![crate_name = "foo"]
43

54
// @has foo/type.CellIndex.html '//pre[@class="rust typedef"]' 'type CellIndex<const D: usize> = [i64; D];'

src/test/ui/array-slice-vec/match_arr_unknown_len.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ LL | #![feature(const_generics)]
66
|
77
= note: `#[warn(incomplete_features)]` on by default
88
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
9-
= help: consider using `min_const_generics` instead, which is more stable and complete
109

1110
error[E0308]: mismatched types
1211
--> $DIR/match_arr_unknown_len.rs:6:9

src/test/ui/associated-consts/associated-const-type-parameter-arrays.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ impl Foo for Def {
1414

1515
pub fn test<A: Foo, B: Foo>() {
1616
let _array: [u32; <A as Foo>::Y];
17-
//~^ ERROR the trait bound `A: Foo` is not satisfied [E0277]
17+
//~^ ERROR generic parameters may not be used
1818
}
1919

20-
fn main() {
21-
}
20+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
error[E0277]: the trait bound `A: Foo` is not satisfied
2-
--> $DIR/associated-const-type-parameter-arrays.rs:16:23
1+
error: generic parameters may not be used in const operations
2+
--> $DIR/associated-const-type-parameter-arrays.rs:16:24
33
|
4-
LL | const Y: usize;
5-
| --------------- required by `Foo::Y`
6-
...
74
LL | let _array: [u32; <A as Foo>::Y];
8-
| ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
5+
| ^ cannot perform const operation using `A`
96
|
10-
help: consider further restricting this bound
11-
|
12-
LL | pub fn test<A: Foo + Foo, B: Foo>() {
13-
| ^^^^^
7+
= note: type parameters may not be used in const expressions
8+
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
149

1510
error: aborting due to previous error
1611

17-
For more information about this error, try `rustc --explain E0277`.

src/test/ui/associated-item/associated-item-duplicate-bounds.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ trait Adapter {
55
struct Foo<A: Adapter> {
66
adapter: A,
77
links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
8-
//~^ ERROR: no associated item named `LINKS` found
8+
//~^ ERROR generic parameters may not be used in const operations
99
}
1010

1111
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error[E0599]: no associated item named `LINKS` found for type parameter `A` in the current scope
2-
--> $DIR/associated-item-duplicate-bounds.rs:7:21
1+
error: generic parameters may not be used in const operations
2+
--> $DIR/associated-item-duplicate-bounds.rs:7:18
33
|
44
LL | links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
5-
| ^^^^^ associated item not found in `A`
5+
| ^^^^^^^^ cannot perform const operation using `A`
66
|
7-
= help: items from traits can only be used if the type parameter is bounded by the trait
7+
= note: type parameters may not be used in const expressions
8+
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
89

910
error: aborting due to previous error
1011

11-
For more information about this error, try `rustc --explain E0599`.

src/test/ui/async-await/issues/issue-78654.full.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0573]: expected type, found built-in attribute `feature`
2-
--> $DIR/issue-78654.rs:10:15
2+
--> $DIR/issue-78654.rs:9:15
33
|
44
LL | impl<const H: feature> Foo {
55
| ^^^^^^^ not a type
66

77
error[E0207]: the const parameter `H` is not constrained by the impl trait, self type, or predicates
8-
--> $DIR/issue-78654.rs:10:12
8+
--> $DIR/issue-78654.rs:9:12
99
|
1010
LL | impl<const H: feature> Foo {
1111
| ^ unconstrained const parameter

0 commit comments

Comments
 (0)