1
Fork 0

stabilize min_const_generics

This commit is contained in:
Bastian Kauschke 2020-11-17 10:55:13 +01:00
parent 1f5beec3b1
commit 06cc9c26da
17 changed files with 41 additions and 51 deletions

View file

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

View file

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

View file

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

View file

@ -1,7 +1,7 @@
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId}; 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_errors::struct_span_err;
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
use rustc_feature::{Features, GateIssue}; use rustc_feature::{Features, GateIssue};
@ -529,19 +529,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
visit::walk_fn(self, fn_kind, span) 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) { fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
if let AssocTyConstraintKind::Bound { .. } = constraint.kind { if let AssocTyConstraintKind::Bound { .. } = constraint.kind {
gate_feature_post!( gate_feature_post!(

View file

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

View file

@ -273,6 +273,8 @@ declare_features! (
/// Allows patterns with concurrent by-move and by-ref bindings. /// 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. /// 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), (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 // feature-group-end: accepted features

View file

@ -578,9 +578,6 @@ declare_features! (
/// Allows calling `transmute` in const fn /// Allows calling `transmute` in const fn
(active, const_fn_transmute, "1.46.0", Some(53605), None), (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. /// Allows `if let` guard in match arms.
(active, if_let_guard, "1.47.0", Some(51114), None), (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 /// Some features are not allowed to be used together at the same time, if
/// the two are present, produce an error. /// 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! { declare_lint! {
/// The `invalid_value` lint detects creating a value that is not valid, /// The `invalid_value` lint detects creating a value that is not valid,

View file

@ -1386,7 +1386,7 @@ impl<'tcx> TyCtxt<'tcx> {
#[inline] #[inline]
pub fn lazy_normalization(self) -> bool { pub fn lazy_normalization(self) -> bool {
let features = self.features(); 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 features.const_generics || features.lazy_normalization_consts
} }

View file

@ -1638,8 +1638,6 @@ pub type PlaceholderConst<'tcx> = Placeholder<BoundConst<'tcx>>;
/// which cause cycle errors. /// which cause cycle errors.
/// ///
/// ```rust /// ```rust
/// #![feature(const_generics)]
///
/// struct A; /// struct A;
/// impl A { /// impl A {
/// fn foo<const N: usize>(&self) -> [u8; N] { [0; N] } /// 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, self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause,
}; };
use rustc_errors::PResult; use rustc_errors::PResult;
use rustc_span::symbol::{kw, sym}; use rustc_span::symbol::kw;
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
/// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`. /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@ -56,8 +56,6 @@ impl<'a> Parser<'a> {
self.expect(&token::Colon)?; self.expect(&token::Colon)?;
let ty = self.parse_ty()?; let ty = self.parse_ty()?;
self.sess.gated_spans.gate(sym::min_const_generics, const_span.to(self.prev_token.span));
Ok(GenericParam { Ok(GenericParam {
ident, ident,
id: ast::DUMMY_NODE_ID, 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 /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
/// this function will emit an error if `min_const_generics` is enabled, the body identified by /// 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. /// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
crate fn maybe_emit_forbidden_non_static_lifetime_error( crate fn maybe_emit_forbidden_non_static_lifetime_error(
&self, &self,
@ -2002,7 +2002,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore 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( feature_err(
&self.tcx.sess.parse_sess, &self.tcx.sess.parse_sess,
sym::const_generics, sym::const_generics,

View file

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

View file

@ -2624,8 +2624,12 @@ impl<'a> Resolver<'a> {
continue; continue;
} }
ConstantItemRibKind(trivial) => { ConstantItemRibKind(trivial) => {
let features = self.session.features_untracked();
// HACK(min_const_generics): We currently only allow `N` or `{ N }`. // 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 // 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 // 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. // this and then enforce the self type to be concrete later on.
@ -2713,8 +2717,12 @@ impl<'a> Resolver<'a> {
continue; continue;
} }
ConstantItemRibKind(trivial) => { ConstantItemRibKind(trivial) => {
let features = self.session.features_untracked();
// HACK(min_const_generics): We currently only allow `N` or `{ N }`. // 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 { if record_used {
self.report_error( self.report_error(
span, span,

View file

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

View file

@ -293,7 +293,13 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
let err_ty_str; let err_ty_str;
let mut is_ptr = true; 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() { match ty.kind() {
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None, ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
ty::FnPtr(_) => Some("function pointers"), ty::FnPtr(_) => Some("function pointers"),
@ -304,12 +310,6 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
Some(err_ty_str.as_str()) 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 let Some(unsupported_type) = err {
if is_ptr { 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. // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
// //
// Note that we do not supply the parent generics when using // 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()) Some(parent_def_id.to_def_id())
} else { } else {
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));