Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilise feature(const_generics_defaults) #90207

Merged
merged 5 commits into from
Dec 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,7 @@ pub type GenericBounds = Vec<GenericBound>;
pub enum ParamKindOrd {
Lifetime,
Type,
// `unordered` is only `true` if `sess.unordered_const_ty_params()`
// returns true. Specifically, if it's only `min_const_generics`, it will still require
// ordering consts after types.
Const { unordered: bool },
Const,
// `Infer` is not actually constructed directly from the AST, but is implicitly constructed
// during HIR lowering, and `ParamKindOrd` will implicitly order inferred variables last.
Infer,
Comment on lines 333 to 338
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should be able to change this to

pub enum ParamKindOrd {
    Lifetime,
    TypeOrConst,
}

should make stuff a bit cleaner.

Expand All @@ -346,11 +343,7 @@ impl Ord for ParamKindOrd {
use ParamKindOrd::*;
let to_int = |v| match v {
Lifetime => 0,
Infer | Type | Const { unordered: true } => 1,
// technically both consts should be ordered equally,
// but only one is ever encountered at a time, so this is
// fine.
Const { unordered: false } => 2,
Infer | Type | Const => 1,
};

to_int(*self).cmp(&to_int(*other))
Expand Down
28 changes: 3 additions & 25 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,6 @@ impl<'a> AstValidator<'a> {
/// Checks that generic parameters are in the correct order,
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
fn validate_generic_param_order(
sess: &Session,
handler: &rustc_errors::Handler,
generics: &[GenericParam],
span: Span,
Expand All @@ -911,8 +910,7 @@ fn validate_generic_param_order(
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident.to_string()),
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
let ty = pprust::ty_to_string(ty);
let unordered = sess.features_untracked().unordered_const_ty_params();
(ParamKindOrd::Const { unordered }, format!("const {}: {}", ident, ty))
(ParamKindOrd::Const, format!("const {}: {}", ident, ty))
}
};
param_idents.push((kind, ord_kind, bounds, idx, ident));
Expand Down Expand Up @@ -968,14 +966,7 @@ fn validate_generic_param_order(
);
err.span_suggestion(
span,
&format!(
"reorder the parameters: lifetimes, {}",
if sess.features_untracked().unordered_const_ty_params() {
"then consts and types"
} else {
"then types, then consts"
}
),
"reorder the parameters: lifetimes, then consts and types",
ordered_params.clone(),
Applicability::MachineApplicable,
);
Expand Down Expand Up @@ -1342,8 +1333,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}

fn visit_generics(&mut self, generics: &'a Generics) {
let cg_defaults = self.session.features_untracked().unordered_const_ty_params();

let mut prev_param_default = None;
for param in &generics.params {
match param.kind {
Expand All @@ -1358,25 +1347,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
span,
"generic parameters with a default must be trailing",
);
if matches!(param.kind, GenericParamKind::Const { .. }) && !cg_defaults {
err.note(
"using type defaults and const parameters \
in the same parameter list is currently not permitted",
);
}
err.emit();
break;
}
}
}
}

validate_generic_param_order(
self.session,
self.err_handler(),
&generics.params,
generics.span,
);
validate_generic_param_order(self.err_handler(), &generics.params, generics.span);

for predicate in &generics.where_clause.predicates {
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -724,10 +724,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(half_open_range_patterns, "half-open range patterns are unstable");
gate_all!(inline_const, "inline-const is experimental");
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
gate_all!(
const_generics_defaults,
"default values for const generic parameters are experimental"
);
if sess.parse_sess.span_diagnostic.err_count() == 0 {
// Errors for `destructuring_assignment` can get quite noisy, especially where `_` is
// involved, so we only emit errors where there are no other parsing errors.
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ declare_features! (
(accepted, const_fn_union, "1.56.0", Some(51909), None),
/// Allows unsizing coercions in `const fn`.
(accepted, const_fn_unsize, "1.54.0", Some(64992), None),
/// Allows const generics to have default values (e.g. `struct Foo<const N: usize = 3>(...);`).
(accepted, const_generics_defaults, "1.59.0", Some(44580), None),
/// Allows the use of `if` and `match` in constants.
(accepted, const_if_match, "1.46.0", Some(49146), None),
/// Allows indexing into constant arrays.
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ macro_rules! declare_features {
}
}

pub fn unordered_const_ty_params(&self) -> bool {
self.const_generics_defaults || self.generic_const_exprs || self.adt_const_params
}

/// Some features are known to be incomplete and using them is likely to have
/// unanticipated results, such as compiler crashes. We warn the user about these
/// to alert them.
Expand Down Expand Up @@ -334,8 +330,6 @@ declare_features! (
(active, const_fn_trait_bound, "1.53.0", Some(57563), None),
/// Allows `for _ in _` loops in const contexts.
(active, const_for, "1.56.0", Some(87575), None),
/// Allows const generics to have default values (e.g. `struct Foo<const N: usize = 3>(...);`).
(active, const_generics_defaults, "1.51.0", Some(44580), None),
/// Allows argument and return position `impl Trait` in a `const fn`.
(active, const_impl_trait, "1.48.0", Some(77463), None),
/// Allows using `&mut` in constant functions.
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,13 +325,11 @@ impl GenericArg<'_> {
}
}

pub fn to_ord(&self, feats: &rustc_feature::Features) -> ast::ParamKindOrd {
pub fn to_ord(&self) -> ast::ParamKindOrd {
match self {
GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
GenericArg::Type(_) => ast::ParamKindOrd::Type,
GenericArg::Const(_) => {
ast::ParamKindOrd::Const { unordered: feats.unordered_const_ty_params() }
}
GenericArg::Const(_) => ast::ParamKindOrd::Const,
GenericArg::Infer(_) => ast::ParamKindOrd::Infer,
}
}
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_middle/src/ty/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@ impl GenericParamDefKind {
GenericParamDefKind::Const { .. } => "constant",
}
}
pub fn to_ord(&self, tcx: TyCtxt<'_>) -> ast::ParamKindOrd {
pub fn to_ord(&self) -> ast::ParamKindOrd {
match self {
GenericParamDefKind::Lifetime => ast::ParamKindOrd::Lifetime,
GenericParamDefKind::Type { .. } => ast::ParamKindOrd::Type,
GenericParamDefKind::Const { .. } => {
ast::ParamKindOrd::Const { unordered: tcx.features().unordered_const_ty_params() }
}
GenericParamDefKind::Const { .. } => ast::ParamKindOrd::Const,
}
}
}
Expand Down
17 changes: 3 additions & 14 deletions compiler/rustc_parse/src/parser/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 `+`.
Expand Down Expand Up @@ -59,19 +59,8 @@ impl<'a> Parser<'a> {
self.expect(&token::Colon)?;
let ty = self.parse_ty()?;

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

Ok(GenericParam {
ident,
Expand Down
36 changes: 4 additions & 32 deletions compiler/rustc_typeck/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
_ => {}
}

let kind_ord = param.kind.to_ord(tcx);
let arg_ord = arg.to_ord(tcx.features());
let kind_ord = param.kind.to_ord();
let arg_ord = arg.to_ord();

// This note is only true when generic parameters are strictly ordered by their kind.
if possible_ordering_error && kind_ord.cmp(&arg_ord) != core::cmp::Ordering::Equal {
Expand Down Expand Up @@ -298,26 +298,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.params
.clone()
.into_iter()
.map(|param| {
(
match param.kind {
GenericParamDefKind::Lifetime => {
ParamKindOrd::Lifetime
}
GenericParamDefKind::Type { .. } => {
ParamKindOrd::Type
}
GenericParamDefKind::Const { .. } => {
ParamKindOrd::Const {
unordered: tcx
.features()
.unordered_const_ty_params(),
}
}
},
param,
)
})
.map(|param| (param.kind.to_ord(), param))
.collect::<Vec<(ParamKindOrd, GenericParamDef)>>();
param_types_present.sort_by_key(|(ord, _)| *ord);
let (mut param_types_present, ordered_params): (
Expand All @@ -330,16 +311,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx,
arg,
param,
!args_iter.clone().is_sorted_by_key(|arg| match arg {
GenericArg::Lifetime(_) => ParamKindOrd::Lifetime,
GenericArg::Type(_) => ParamKindOrd::Type,
GenericArg::Const(_) => ParamKindOrd::Const {
unordered: tcx
.features()
.unordered_const_ty_params(),
},
GenericArg::Infer(_) => ParamKindOrd::Infer,
}),
!args_iter.clone().is_sorted_by_key(|arg| arg.to_ord()),
Some(&format!(
"reorder the arguments: {}: `<{}>`",
param_types_present
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,6 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => (),

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// revisions: cfail
#![feature(generic_const_exprs, adt_const_params, const_generics_defaults)]
#![feature(generic_const_exprs, adt_const_params)]
#![allow(incomplete_features)]
// regression test for #77650
struct C<T, const N: core::num::NonZeroUsize>([T; N.get()])
Expand Down
1 change: 0 additions & 1 deletion src/test/rustdoc/const-generics/const-generic-defaults.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![crate_name = "foo"]
#![feature(const_generics_defaults)]

// @has foo/struct.Foo.html '//pre[@class="rust struct"]' \
// 'pub struct Foo<const M: usize = 10_usize, const N: usize = M, T = i32>(_);'
Expand Down
30 changes: 0 additions & 30 deletions src/test/ui/const-generics/argument_order.min.stderr

This file was deleted.

5 changes: 0 additions & 5 deletions src/test/ui/const-generics/argument_order.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// revisions: full min
#![cfg_attr(full, feature(const_generics_defaults))]

struct Bad<const N: usize, T> {
//[min]~^ ERROR type parameters must be declared prior to const parameters
arr: [u8; { N }],
another: T,
}

struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
//~^ ERROR lifetime parameters must be declared prior
//[min]~^^ ERROR type parameters must be declared prior to const parameters
a: &'a T,
b: &'b U,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error: lifetime parameters must be declared prior to const parameters
--> $DIR/argument_order.rs:10:32
--> $DIR/argument_order.rs:6: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:18:23
--> $DIR/argument_order.rs:13:23
|
LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
| ^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ error[E0747]: constant provided when a type was expected
|
LL | fn foo<const N: usize>() -> Array<N, ()> {
| ^
|
= note: type arguments must be provided before constant arguments
= help: reorder the arguments: types, then consts: `<T, N>`

error: aborting due to previous error

Expand Down

This file was deleted.

5 changes: 0 additions & 5 deletions src/test/ui/const-generics/const-param-before-other-params.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
// revisions: full min
#![cfg_attr(full, feature(const_generics_defaults))]
#![cfg_attr(full, allow(incomplete_features))]

fn bar<const X: u8, 'a>(_: &'a ()) {
//~^ ERROR lifetime parameters must be declared prior to const parameters
}

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

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: lifetime parameters must be declared prior to const parameters
--> $DIR/const-param-before-other-params.rs:5:21
--> $DIR/const-param-before-other-params.rs:1:21
|
LL | fn bar<const X: u8, 'a>(_: &'a ()) {
| --------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const X: u8>`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(const_generics_defaults)]

pub struct Defaulted<const N: usize=3>;
impl Defaulted {
pub fn new() -> Self {
Expand Down
Loading