stabilize min_const_generics
This commit is contained in:
parent
1f5beec3b1
commit
06cc9c26da
17 changed files with 41 additions and 51 deletions
|
@ -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))]
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)] = &[];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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] }
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)]
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue