about summary refs log tree commit diff
path: root/compiler/rustc_feature/src/lib.rs
diff options
context:
space:
mode:
authorJoshua Nelson <jyn514@gmail.com>2020-10-10 14:27:52 -0400
committerJoshua Nelson <jyn514@gmail.com>2020-11-07 13:45:11 -0500
commit622c48e4f1a5bc3727f8ead89767c8a9e367a77e (patch)
tree559b4777071477577cca6b704a6e5f70deca06e7 /compiler/rustc_feature/src/lib.rs
parentdc06a36074f04c6a77b5834f2950011d49607898 (diff)
downloadrust-622c48e4f1a5bc3727f8ead89767c8a9e367a77e.tar.gz
rust-622c48e4f1a5bc3727f8ead89767c8a9e367a77e.zip
Allow making `RUSTC_BOOTSTRAP` conditional on the crate name
The main change is that `UnstableOptions::from_environment` now requires
an (optional) crate name. If the crate name is unknown (`None`), then the new feature is not available and you still have to use `RUSTC_BOOTSTRAP=1`. In practice this means the feature is only available for `--crate-name`, not for `#![crate_name]`; I'm interested in supporting the second but I'm not sure how.

Other major changes:

- Added `Session::is_nightly_build()`, which uses the `crate_name` of
the session
- Added `nightly_options::match_is_nightly_build`, a convenience method
for looking up `--crate-name` from CLI arguments.
`Session::is_nightly_build()`should be preferred where possible, since
it will take into account `#![crate_name]` (I think).
- Added `unstable_features` to `rustdoc::RenderOptions`

  There is a user-facing change here: things like `RUSTC_BOOTSTRAP=0` no
  longer active nightly features. In practice this shouldn't be a big
  deal, since `RUSTC_BOOTSTRAP` is the opposite of stable and everyone
  uses `RUSTC_BOOTSTRAP=1` anyway.

- Add tests

  Check against `Cheat`, not whether nightly features are allowed.
  Nightly features are always allowed on the nightly channel.

- Only call `is_nightly_build()` once within a function

- Use booleans consistently for rustc_incremental

  Sessions can't be passed through threads, so `read_file` couldn't take a
  session. To be consistent, also take a boolean in `write_file_header`.
Diffstat (limited to 'compiler/rustc_feature/src/lib.rs')
-rw-r--r--compiler/rustc_feature/src/lib.rs42
1 files changed, 39 insertions, 3 deletions
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index 68ac2841fed..f965f7fdefe 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -59,7 +59,7 @@ pub enum Stability {
     Deprecated(&'static str, Option<&'static str>),
 }
 
-#[derive(Clone, Copy, Hash)]
+#[derive(Clone, Copy, Debug, Hash)]
 pub enum UnstableFeatures {
     /// Hard errors for unstable features are active, as on beta/stable channels.
     Disallow,
@@ -73,11 +73,20 @@ pub enum UnstableFeatures {
 }
 
 impl UnstableFeatures {
-    pub fn from_environment() -> UnstableFeatures {
+    /// This takes into account `RUSTC_BOOTSTRAP`.
+    ///
+    /// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly features.
+    /// Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
+    pub fn from_environment(krate: Option<&str>) -> Self {
         // `true` if this is a feature-staged build, i.e., on the beta or stable channel.
         let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
+        // Returns whether `krate` should be counted as unstable
+        let is_unstable_crate = |var: &str| {
+            krate.map_or(false, |name| var.split(',').any(|new_krate| new_krate == name))
+        };
         // `true` if we should enable unstable features for bootstrapping.
-        let bootstrap = std::env::var("RUSTC_BOOTSTRAP").is_ok();
+        let bootstrap = std::env::var("RUSTC_BOOTSTRAP")
+            .map_or(false, |var| var == "1" || is_unstable_crate(&var));
         match (disable_unstable_features, bootstrap) {
             (_, true) => UnstableFeatures::Cheat,
             (true, _) => UnstableFeatures::Disallow,
@@ -140,3 +149,30 @@ pub use builtin_attrs::{
     AttributeType, BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
 };
 pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
+
+#[cfg(test)]
+mod test {
+    use super::UnstableFeatures;
+
+    #[test]
+    fn rustc_bootstrap_parsing() {
+        let is_bootstrap = |env, krate| {
+            std::env::set_var("RUSTC_BOOTSTRAP", env);
+            matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Cheat)
+        };
+        assert!(is_bootstrap("1", None));
+        assert!(is_bootstrap("1", Some("x")));
+        // RUSTC_BOOTSTRAP allows specifying a specific crate
+        assert!(is_bootstrap("x", Some("x")));
+        // RUSTC_BOOTSTRAP allows multiple comma-delimited crates
+        assert!(is_bootstrap("x,y,z", Some("x")));
+        assert!(is_bootstrap("x,y,z", Some("y")));
+        // Crate that aren't specified do not get unstable features
+        assert!(!is_bootstrap("x", Some("a")));
+        assert!(!is_bootstrap("x,y,z", Some("a")));
+        assert!(!is_bootstrap("x,y,z", None));
+
+        // this is technically a breaking change, but there are no stability guarantees for RUSTC_BOOTSTRAP
+        assert!(!is_bootstrap("0", None));
+    }
+}