Skip to content

Commit 753e569

Browse files
committed
Auto merge of #90207 - BoxyUwU:stabilise_cg_defaults, r=lcnr
Stabilise `feature(const_generics_defaults)` `feature(const_generics_defaults)` is complete implementation wise and has a pretty extensive test suite so I think is ready for stabilisation. needs stabilisation report and maybe an RFC 😅 r? `@lcnr` cc `@rust-lang/project-const-generics`
2 parents 4c9bdf4 + 1e896df commit 753e569

File tree

94 files changed

+101
-380
lines changed

Some content is hidden

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

94 files changed

+101
-380
lines changed

compiler/rustc_ast/src/ast.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,7 @@ pub type GenericBounds = Vec<GenericBound>;
332332
pub enum ParamKindOrd {
333333
Lifetime,
334334
Type,
335-
// `unordered` is only `true` if `sess.unordered_const_ty_params()`
336-
// returns true. Specifically, if it's only `min_const_generics`, it will still require
337-
// ordering consts after types.
338-
Const { unordered: bool },
335+
Const,
339336
// `Infer` is not actually constructed directly from the AST, but is implicitly constructed
340337
// during HIR lowering, and `ParamKindOrd` will implicitly order inferred variables last.
341338
Infer,
@@ -346,11 +343,7 @@ impl Ord for ParamKindOrd {
346343
use ParamKindOrd::*;
347344
let to_int = |v| match v {
348345
Lifetime => 0,
349-
Infer | Type | Const { unordered: true } => 1,
350-
// technically both consts should be ordered equally,
351-
// but only one is ever encountered at a time, so this is
352-
// fine.
353-
Const { unordered: false } => 2,
346+
Infer | Type | Const => 1,
354347
};
355348

356349
to_int(*self).cmp(&to_int(*other))

compiler/rustc_ast_passes/src/ast_validation.rs

+3-25
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,6 @@ impl<'a> AstValidator<'a> {
894894
/// Checks that generic parameters are in the correct order,
895895
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
896896
fn validate_generic_param_order(
897-
sess: &Session,
898897
handler: &rustc_errors::Handler,
899898
generics: &[GenericParam],
900899
span: Span,
@@ -911,8 +910,7 @@ fn validate_generic_param_order(
911910
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident.to_string()),
912911
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
913912
let ty = pprust::ty_to_string(ty);
914-
let unordered = sess.features_untracked().unordered_const_ty_params();
915-
(ParamKindOrd::Const { unordered }, format!("const {}: {}", ident, ty))
913+
(ParamKindOrd::Const, format!("const {}: {}", ident, ty))
916914
}
917915
};
918916
param_idents.push((kind, ord_kind, bounds, idx, ident));
@@ -968,14 +966,7 @@ fn validate_generic_param_order(
968966
);
969967
err.span_suggestion(
970968
span,
971-
&format!(
972-
"reorder the parameters: lifetimes, {}",
973-
if sess.features_untracked().unordered_const_ty_params() {
974-
"then consts and types"
975-
} else {
976-
"then types, then consts"
977-
}
978-
),
969+
"reorder the parameters: lifetimes, then consts and types",
979970
ordered_params.clone(),
980971
Applicability::MachineApplicable,
981972
);
@@ -1342,8 +1333,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13421333
}
13431334

13441335
fn visit_generics(&mut self, generics: &'a Generics) {
1345-
let cg_defaults = self.session.features_untracked().unordered_const_ty_params();
1346-
13471336
let mut prev_param_default = None;
13481337
for param in &generics.params {
13491338
match param.kind {
@@ -1358,25 +1347,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13581347
span,
13591348
"generic parameters with a default must be trailing",
13601349
);
1361-
if matches!(param.kind, GenericParamKind::Const { .. }) && !cg_defaults {
1362-
err.note(
1363-
"using type defaults and const parameters \
1364-
in the same parameter list is currently not permitted",
1365-
);
1366-
}
13671350
err.emit();
13681351
break;
13691352
}
13701353
}
13711354
}
13721355
}
13731356

1374-
validate_generic_param_order(
1375-
self.session,
1376-
self.err_handler(),
1377-
&generics.params,
1378-
generics.span,
1379-
);
1357+
validate_generic_param_order(self.err_handler(), &generics.params, generics.span);
13801358

13811359
for predicate in &generics.where_clause.predicates {
13821360
if let WherePredicate::EqPredicate(ref predicate) = *predicate {

compiler/rustc_ast_passes/src/feature_gate.rs

-4
Original file line numberDiff line numberDiff line change
@@ -724,10 +724,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
724724
gate_all!(half_open_range_patterns, "half-open range patterns are unstable");
725725
gate_all!(inline_const, "inline-const is experimental");
726726
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
727-
gate_all!(
728-
const_generics_defaults,
729-
"default values for const generic parameters are experimental"
730-
);
731727
if sess.parse_sess.span_diagnostic.err_count() == 0 {
732728
// Errors for `destructuring_assignment` can get quite noisy, especially where `_` is
733729
// involved, so we only emit errors where there are no other parsing errors.

compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ declare_features! (
9090
(accepted, const_fn_union, "1.56.0", Some(51909), None),
9191
/// Allows unsizing coercions in `const fn`.
9292
(accepted, const_fn_unsize, "1.54.0", Some(64992), None),
93+
/// Allows const generics to have default values (e.g. `struct Foo<const N: usize = 3>(...);`).
94+
(accepted, const_generics_defaults, "1.59.0", Some(44580), None),
9395
/// Allows the use of `if` and `match` in constants.
9496
(accepted, const_if_match, "1.46.0", Some(49146), None),
9597
/// Allows indexing into constant arrays.

compiler/rustc_feature/src/active.rs

-6
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ macro_rules! declare_features {
6969
}
7070
}
7171

72-
pub fn unordered_const_ty_params(&self) -> bool {
73-
self.const_generics_defaults || self.generic_const_exprs || self.adt_const_params
74-
}
75-
7672
/// Some features are known to be incomplete and using them is likely to have
7773
/// unanticipated results, such as compiler crashes. We warn the user about these
7874
/// to alert them.
@@ -334,8 +330,6 @@ declare_features! (
334330
(active, const_fn_trait_bound, "1.53.0", Some(57563), None),
335331
/// Allows `for _ in _` loops in const contexts.
336332
(active, const_for, "1.56.0", Some(87575), None),
337-
/// Allows const generics to have default values (e.g. `struct Foo<const N: usize = 3>(...);`).
338-
(active, const_generics_defaults, "1.51.0", Some(44580), None),
339333
/// Allows argument and return position `impl Trait` in a `const fn`.
340334
(active, const_impl_trait, "1.48.0", Some(77463), None),
341335
/// Allows using `&mut` in constant functions.

compiler/rustc_hir/src/hir.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,11 @@ impl GenericArg<'_> {
325325
}
326326
}
327327

328-
pub fn to_ord(&self, feats: &rustc_feature::Features) -> ast::ParamKindOrd {
328+
pub fn to_ord(&self) -> ast::ParamKindOrd {
329329
match self {
330330
GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
331331
GenericArg::Type(_) => ast::ParamKindOrd::Type,
332-
GenericArg::Const(_) => {
333-
ast::ParamKindOrd::Const { unordered: feats.unordered_const_ty_params() }
334-
}
332+
GenericArg::Const(_) => ast::ParamKindOrd::Const,
335333
GenericArg::Infer(_) => ast::ParamKindOrd::Infer,
336334
}
337335
}

compiler/rustc_middle/src/ty/generics.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ impl GenericParamDefKind {
2424
GenericParamDefKind::Const { .. } => "constant",
2525
}
2626
}
27-
pub fn to_ord(&self, tcx: TyCtxt<'_>) -> ast::ParamKindOrd {
27+
pub fn to_ord(&self) -> ast::ParamKindOrd {
2828
match self {
2929
GenericParamDefKind::Lifetime => ast::ParamKindOrd::Lifetime,
3030
GenericParamDefKind::Type { .. } => ast::ParamKindOrd::Type,
31-
GenericParamDefKind::Const { .. } => {
32-
ast::ParamKindOrd::Const { unordered: tcx.features().unordered_const_ty_params() }
33-
}
31+
GenericParamDefKind::Const { .. } => ast::ParamKindOrd::Const,
3432
}
3533
}
3634
}

compiler/rustc_parse/src/parser/generics.rs

+3-14
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 `+`.
@@ -59,19 +59,8 @@ impl<'a> Parser<'a> {
5959
self.expect(&token::Colon)?;
6060
let ty = self.parse_ty()?;
6161

62-
// Parse optional const generics default value, taking care of feature gating the spans
63-
// with the unstable syntax mechanism.
64-
let default = if self.eat(&token::Eq) {
65-
// The gated span goes from the `=` to the end of the const argument that follows (and
66-
// which could be a block expression).
67-
let start = self.prev_token.span;
68-
let const_arg = self.parse_const_arg()?;
69-
let span = start.to(const_arg.value.span);
70-
self.sess.gated_spans.gate(sym::const_generics_defaults, span);
71-
Some(const_arg)
72-
} else {
73-
None
74-
};
62+
// Parse optional const generics default value.
63+
let default = if self.eat(&token::Eq) { Some(self.parse_const_arg()?) } else { None };
7564

7665
Ok(GenericParam {
7766
ident,

compiler/rustc_typeck/src/astconv/generics.rs

+4-32
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
131131
_ => {}
132132
}
133133

134-
let kind_ord = param.kind.to_ord(tcx);
135-
let arg_ord = arg.to_ord(tcx.features());
134+
let kind_ord = param.kind.to_ord();
135+
let arg_ord = arg.to_ord();
136136

137137
// This note is only true when generic parameters are strictly ordered by their kind.
138138
if possible_ordering_error && kind_ord.cmp(&arg_ord) != core::cmp::Ordering::Equal {
@@ -298,26 +298,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
298298
.params
299299
.clone()
300300
.into_iter()
301-
.map(|param| {
302-
(
303-
match param.kind {
304-
GenericParamDefKind::Lifetime => {
305-
ParamKindOrd::Lifetime
306-
}
307-
GenericParamDefKind::Type { .. } => {
308-
ParamKindOrd::Type
309-
}
310-
GenericParamDefKind::Const { .. } => {
311-
ParamKindOrd::Const {
312-
unordered: tcx
313-
.features()
314-
.unordered_const_ty_params(),
315-
}
316-
}
317-
},
318-
param,
319-
)
320-
})
301+
.map(|param| (param.kind.to_ord(), param))
321302
.collect::<Vec<(ParamKindOrd, GenericParamDef)>>();
322303
param_types_present.sort_by_key(|(ord, _)| *ord);
323304
let (mut param_types_present, ordered_params): (
@@ -330,16 +311,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
330311
tcx,
331312
arg,
332313
param,
333-
!args_iter.clone().is_sorted_by_key(|arg| match arg {
334-
GenericArg::Lifetime(_) => ParamKindOrd::Lifetime,
335-
GenericArg::Type(_) => ParamKindOrd::Type,
336-
GenericArg::Const(_) => ParamKindOrd::Const {
337-
unordered: tcx
338-
.features()
339-
.unordered_const_ty_params(),
340-
},
341-
GenericArg::Infer(_) => ParamKindOrd::Infer,
342-
}),
314+
!args_iter.clone().is_sorted_by_key(|arg| arg.to_ord()),
343315
Some(&format!(
344316
"reorder the arguments: {}: `<{}>`",
345317
param_types_present

compiler/rustc_typeck/src/check/wfcheck.rs

-1
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,6 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
697697
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => (),
698698

699699
// Const parameters are well formed if their type is structural match.
700-
// FIXME(const_generics_defaults): we also need to check that the `default` is wf.
701700
hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
702701
let ty = tcx.type_of(tcx.hir().local_def_id(param.hir_id));
703702

src/test/incremental/const-generics/hash-tyvid-regression-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// revisions: cfail
2-
#![feature(generic_const_exprs, adt_const_params, const_generics_defaults)]
2+
#![feature(generic_const_exprs, adt_const_params)]
33
#![allow(incomplete_features)]
44
// regression test for #77650
55
struct C<T, const N: core::num::NonZeroUsize>([T; N.get()])

src/test/rustdoc/const-generics/const-generic-defaults.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#![crate_name = "foo"]
2-
#![feature(const_generics_defaults)]
32

43
// @has foo/struct.Foo.html '//pre[@class="rust struct"]' \
54
// 'pub struct Foo<const M: usize = 10_usize, const N: usize = M, T = i32>(_);'

src/test/ui/const-generics/argument_order.min.stderr

-30
This file was deleted.

src/test/ui/const-generics/argument_order.rs

-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
// revisions: full min
2-
#![cfg_attr(full, feature(const_generics_defaults))]
3-
41
struct Bad<const N: usize, T> {
5-
//[min]~^ ERROR type parameters must be declared prior to const parameters
62
arr: [u8; { N }],
73
another: T,
84
}
95

106
struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
117
//~^ ERROR lifetime parameters must be declared prior
12-
//[min]~^^ ERROR type parameters must be declared prior to const parameters
138
a: &'a T,
149
b: &'b U,
1510
}

src/test/ui/const-generics/argument_order.full.stderr src/test/ui/const-generics/argument_order.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: lifetime parameters must be declared prior to const parameters
2-
--> $DIR/argument_order.rs:10:32
2+
--> $DIR/argument_order.rs:6:32
33
|
44
LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
55
| -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>`
66

77
error[E0747]: lifetime provided when a type was expected
8-
--> $DIR/argument_order.rs:18:23
8+
--> $DIR/argument_order.rs:13:23
99
|
1010
LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
1111
| ^^^^^^^

src/test/ui/const-generics/const-arg-type-arg-misordered.stderr

-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ error[E0747]: constant provided when a type was expected
33
|
44
LL | fn foo<const N: usize>() -> Array<N, ()> {
55
| ^
6-
|
7-
= note: type arguments must be provided before constant arguments
8-
= help: reorder the arguments: types, then consts: `<T, N>`
96

107
error: aborting due to previous error
118

src/test/ui/const-generics/const-param-before-other-params.min.stderr

-14
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
// revisions: full min
2-
#![cfg_attr(full, feature(const_generics_defaults))]
3-
#![cfg_attr(full, allow(incomplete_features))]
4-
51
fn bar<const X: u8, 'a>(_: &'a ()) {
62
//~^ ERROR lifetime parameters must be declared prior to const parameters
73
}
84

95
fn foo<const X: u8, T>(_: &T) {}
10-
//[min]~^ ERROR type parameters must be declared prior to const parameters
116

127
fn main() {}

src/test/ui/const-generics/const-param-before-other-params.full.stderr src/test/ui/const-generics/const-param-before-other-params.stderr

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

src/test/ui/const-generics/defaults/auxiliary/const_defaulty.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(const_generics_defaults)]
2-
31
pub struct Defaulted<const N: usize=3>;
42
impl Defaulted {
53
pub fn new() -> Self {

0 commit comments

Comments
 (0)