Add -Z allow_features=... flag

This commit is contained in:
Tyler Mandry
2019-03-13 16:29:24 -07:00
parent fa8fd3daa7
commit 7c59ce9f5d
9 changed files with 85 additions and 4 deletions

View File

@@ -1440,6 +1440,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED], merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
"control the operation of the MergeFunctions LLVM pass, taking "control the operation of the MergeFunctions LLVM pass, taking
the same values as the target option of the same name"), the same values as the target option of the same name"),
allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
"only allow the listed language features to be enabled in code (space separated)"),
} }
pub fn default_lib_output() -> CrateType { pub fn default_lib_output() -> CrateType {
@@ -3286,6 +3288,10 @@ mod tests {
opts = reference.clone(); opts = reference.clone();
opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled); opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
opts = reference.clone();
opts.debugging_opts.allow_features = Some(vec![String::from("lang_items")]);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
} }
#[test] #[test]

View File

@@ -243,6 +243,7 @@ pub fn register_plugins<'a>(
krate, krate,
&sess.parse_sess, &sess.parse_sess,
sess.edition(), sess.edition(),
&sess.opts.debugging_opts.allow_features,
); );
// these need to be set "early" so that expansion sees `quote` if enabled. // these need to be set "early" so that expansion sees `quote` if enabled.
sess.init_features(features); sess.init_features(features);

View File

@@ -24,8 +24,8 @@ pub struct StripUnconfigured<'a> {
} }
// `cfg_attr`-process the crate's attributes and compute the crate's features. // `cfg_attr`-process the crate's attributes and compute the crate's features.
pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition) pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition,
-> (ast::Crate, Features) { allow_features: &Option<Vec<String>>) -> (ast::Crate, Features) {
let features; let features;
{ {
let mut strip_unconfigured = StripUnconfigured { let mut strip_unconfigured = StripUnconfigured {
@@ -43,7 +43,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition)
return (krate, Features::new()); return (krate, Features::new());
} }
features = get_features(&sess.span_diagnostic, &krate.attrs, edition); features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features);
// Avoid reconfiguring malformed `cfg_attr`s // Avoid reconfiguring malformed `cfg_attr`s
if err_count == sess.span_diagnostic.err_count() { if err_count == sess.span_diagnostic.err_count() {

View File

@@ -378,6 +378,21 @@ Erroneous code example:
"##, "##,
E0725: r##"
A feature attribute named a feature that was disallowed in the compiler
command line flags.
Erroneous code example:
```ignore (can't specify compiler flags from doctests)
#![feature(never_type)] // error: the feature `never_type` is not in
// the list of allowed features
```
Delete the offending feature attribute, or add it to the list of allowed
features in the `-Z allow_features` flag.
"##,
} }
register_diagnostics! { register_diagnostics! {

View File

@@ -2008,7 +2008,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
} }
pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
crate_edition: Edition) -> Features { crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features {
fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
if let Some(reason) = reason { if let Some(reason) = reason {
@@ -2127,6 +2127,15 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
} }
if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
if let Some(allowed) = allow_features.as_ref() {
if allowed.iter().find(|f| *f == name.as_str()).is_none() {
span_err!(span_handler, mi.span, E0725,
"the feature `{}` is not in the list of allowed features",
name);
continue;
}
}
set(&mut features, mi.span); set(&mut features, mi.span);
features.declared_lang_features.push((name, mi.span, None)); features.declared_lang_features.push((name, mi.span, None));
continue continue

View File

@@ -0,0 +1,10 @@
// compile-flags: -Z allow_features=
// Note: This test uses rustc internal flags because they will never stabilize.
#![feature(rustc_diagnostic_macros)] //~ ERROR
#![feature(rustc_const_unstable)] //~ ERROR
#![feature(lang_items)] //~ ERROR
fn main() {}

View File

@@ -0,0 +1,21 @@
error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features
--> $DIR/allow-features-empty.rs:4:12
|
LL | #![feature(rustc_diagnostic_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
--> $DIR/allow-features-empty.rs:6:12
|
LL | #![feature(rustc_const_unstable)]
| ^^^^^^^^^^^^^^^^^^^^
error[E0725]: the feature `lang_items` is not in the list of allowed features
--> $DIR/allow-features-empty.rs:8:12
|
LL | #![feature(lang_items)]
| ^^^^^^^^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0725`.

View File

@@ -0,0 +1,10 @@
// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items
// Note: This test uses rustc internal flags because they will never stabilize.
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_const_unstable)] //~ ERROR
#![feature(lang_items)]
fn main() {}

View File

@@ -0,0 +1,9 @@
error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
--> $DIR/allow-features.rs:6:12
|
LL | #![feature(rustc_const_unstable)]
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0725`.