about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTyler Mandry <tmandry@gmail.com>2019-03-13 16:29:24 -0700
committerTyler Mandry <tmandry@gmail.com>2019-03-14 15:42:20 -0700
commit7c59ce9f5db9cb7dbfbd07fab625e2b67aa042f5 (patch)
tree49dc11b84077d62c5fefba968d74072624b0732b /src
parentfa8fd3daa7efefd4036a377f48f755be0b6952ee (diff)
downloadrust-7c59ce9f5db9cb7dbfbd07fab625e2b67aa042f5.tar.gz
rust-7c59ce9f5db9cb7dbfbd07fab625e2b67aa042f5.zip
Add `-Z allow_features=...` flag
Diffstat (limited to 'src')
-rw-r--r--src/librustc/session/config.rs6
-rw-r--r--src/librustc_interface/passes.rs1
-rw-r--r--src/libsyntax/config.rs6
-rw-r--r--src/libsyntax/diagnostic_list.rs15
-rw-r--r--src/libsyntax/feature_gate.rs11
-rw-r--r--src/test/ui/feature-gate/allow-features-empty.rs10
-rw-r--r--src/test/ui/feature-gate/allow-features-empty.stderr21
-rw-r--r--src/test/ui/feature-gate/allow-features.rs10
-rw-r--r--src/test/ui/feature-gate/allow-features.stderr9
9 files changed, 85 insertions, 4 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index d39057cbf92..ff18678f091 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1440,6 +1440,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
         "control the operation of the MergeFunctions LLVM pass, taking
          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 {
@@ -3286,6 +3288,10 @@ mod tests {
         opts = reference.clone();
         opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled);
         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]
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 5bb47bda17b..0c710fd283b 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -243,6 +243,7 @@ pub fn register_plugins<'a>(
         krate,
         &sess.parse_sess,
         sess.edition(),
+        &sess.opts.debugging_opts.allow_features,
     );
     // these need to be set "early" so that expansion sees `quote` if enabled.
     sess.init_features(features);
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 4e4432a3f33..2abb7e407eb 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -24,8 +24,8 @@ pub struct StripUnconfigured<'a> {
 }
 
 // `cfg_attr`-process the crate's attributes and compute the crate's features.
-pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition)
-                -> (ast::Crate, Features) {
+pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition,
+                allow_features: &Option<Vec<String>>) -> (ast::Crate, Features) {
     let features;
     {
         let mut strip_unconfigured = StripUnconfigured {
@@ -43,7 +43,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition)
             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
         if err_count == sess.span_diagnostic.err_count() {
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index 2c367f1f402..ac24475cab8 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -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! {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 279e2089f5d..77e8e75d832 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -2008,7 +2008,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 }
 
 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>) {
         let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
         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(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);
                 features.declared_lang_features.push((name, mi.span, None));
                 continue
diff --git a/src/test/ui/feature-gate/allow-features-empty.rs b/src/test/ui/feature-gate/allow-features-empty.rs
new file mode 100644
index 00000000000..83250052cb5
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features-empty.rs
@@ -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() {}
diff --git a/src/test/ui/feature-gate/allow-features-empty.stderr b/src/test/ui/feature-gate/allow-features-empty.stderr
new file mode 100644
index 00000000000..cce2c4078c2
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features-empty.stderr
@@ -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`.
diff --git a/src/test/ui/feature-gate/allow-features.rs b/src/test/ui/feature-gate/allow-features.rs
new file mode 100644
index 00000000000..1cebc8f34f2
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features.rs
@@ -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() {}
diff --git a/src/test/ui/feature-gate/allow-features.stderr b/src/test/ui/feature-gate/allow-features.stderr
new file mode 100644
index 00000000000..b13560fb81c
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features.stderr
@@ -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`.