Remove edition umbrella features.
This commit is contained in:
parent
7e452c123c
commit
f481596ee4
49 changed files with 471 additions and 652 deletions
|
@ -1,8 +1,8 @@
|
|||
//! Conditional compilation stripping.
|
||||
|
||||
use crate::errors::{
|
||||
FeatureIncludedInEdition, FeatureNotAllowed, FeatureRemoved, FeatureRemovedReason, InvalidCfg,
|
||||
MalformedFeatureAttribute, MalformedFeatureAttributeHelp, RemoveExprNotSupported,
|
||||
FeatureNotAllowed, FeatureRemoved, FeatureRemovedReason, InvalidCfg, MalformedFeatureAttribute,
|
||||
MalformedFeatureAttributeHelp, RemoveExprNotSupported,
|
||||
};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{Delimiter, Token, TokenKind};
|
||||
|
@ -13,13 +13,11 @@ use rustc_ast::NodeId;
|
|||
use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem};
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_feature::Features;
|
||||
use rustc_feature::{ACCEPTED_FEATURES, REMOVED_FEATURES, UNSTABLE_FEATURES};
|
||||
use rustc_parse::validate_attr;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::edition::ALL_EDITIONS;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::Span;
|
||||
use thin_vec::ThinVec;
|
||||
|
@ -48,42 +46,6 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
|
|||
|
||||
let mut features = Features::default();
|
||||
|
||||
// The edition from `--edition`.
|
||||
let crate_edition = sess.edition();
|
||||
|
||||
// The maximum of (a) the edition from `--edition` and (b) any edition
|
||||
// umbrella feature-gates declared in the code.
|
||||
// - E.g. if `crate_edition` is 2015 but `rust_2018_preview` is present,
|
||||
// `feature_edition` is 2018
|
||||
let mut features_edition = crate_edition;
|
||||
for attr in krate_attrs {
|
||||
for mi in feature_list(attr) {
|
||||
if mi.is_word() {
|
||||
let name = mi.name_or_empty();
|
||||
let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied();
|
||||
if let Some(edition) = edition
|
||||
&& edition > features_edition
|
||||
{
|
||||
features_edition = edition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enable edition-dependent features based on `features_edition`.
|
||||
// - E.g. enable `test_2018_feature` if `features_edition` is 2018 or higher
|
||||
let mut edition_enabled_features = FxHashSet::default();
|
||||
for f in UNSTABLE_FEATURES {
|
||||
if let Some(edition) = f.feature.edition
|
||||
&& edition <= features_edition
|
||||
{
|
||||
// FIXME(Manishearth) there is currently no way to set lib features by
|
||||
// edition.
|
||||
edition_enabled_features.insert(f.feature.name);
|
||||
(f.set_enabled)(&mut features);
|
||||
}
|
||||
}
|
||||
|
||||
// Process all features declared in the code.
|
||||
for attr in krate_attrs {
|
||||
for mi in feature_list(attr) {
|
||||
|
@ -108,38 +70,6 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
|
|||
}
|
||||
};
|
||||
|
||||
// If the declared feature is an edition umbrella feature-gate,
|
||||
// warn if it was redundant w.r.t. `crate_edition`.
|
||||
// - E.g. warn if `rust_2018_preview` is declared when
|
||||
// `crate_edition` is 2018
|
||||
// - E.g. don't warn if `rust_2018_preview` is declared when
|
||||
// `crate_edition` is 2015.
|
||||
if let Some(&edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
|
||||
if edition <= crate_edition {
|
||||
sess.emit_warning(FeatureIncludedInEdition {
|
||||
span: mi.span(),
|
||||
feature: name,
|
||||
edition,
|
||||
});
|
||||
}
|
||||
features.set_declared_lang_feature(name, mi.span(), None);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the declared feature is edition-dependent and was already
|
||||
// enabled due to `feature_edition`, give a warning.
|
||||
// - E.g. warn if `test_2018_feature` is declared when
|
||||
// `feature_edition` is 2018 or higher.
|
||||
if edition_enabled_features.contains(&name) {
|
||||
sess.emit_warning(FeatureIncludedInEdition {
|
||||
span: mi.span(),
|
||||
feature: name,
|
||||
edition: features_edition,
|
||||
});
|
||||
features.set_declared_lang_feature(name, mi.span(), None);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the declared feature has been removed, issue an error.
|
||||
if let Some(f) = REMOVED_FEATURES.iter().find(|f| name == f.feature.name) {
|
||||
sess.emit_err(FeatureRemoved {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use rustc_ast::ast;
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use std::borrow::Cow;
|
||||
|
@ -168,15 +167,6 @@ pub(crate) struct TakesNoArguments<'a> {
|
|||
pub name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(expand_feature_included_in_edition, code = "E0705")]
|
||||
pub(crate) struct FeatureIncludedInEdition {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub feature: Symbol,
|
||||
pub edition: Edition,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(expand_feature_removed, code = "E0557")]
|
||||
pub(crate) struct FeatureRemoved<'a> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue