From 51f51109ce8c3070ab186624c241216620942360 Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Thu, 19 Apr 2018 13:56:26 -0700 Subject: [PATCH 1/4] add --edition option --- src/librustc/session/config.rs | 71 ++++++++++++++++++++++------------ src/librustc/session/mod.rs | 4 +- src/libsyntax/edition.rs | 8 +--- 3 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2e6689efee572..2d0b4eecf63c6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -16,6 +16,8 @@ pub use self::CrateType::*; pub use self::Passes::*; pub use self::DebugInfoLevel::*; +use std::str::FromStr; + use session::{early_error, early_warn, Session}; use session::search_paths::SearchPaths; @@ -28,7 +30,7 @@ use middle::cstore; use syntax::ast::{self, IntTy, UintTy}; use syntax::codemap::{FileName, FilePathMapping}; -use syntax::edition::Edition; +use syntax::edition::{Edition, ALL_EDITIONS, DEFAULT_EDITION}; use syntax::parse::token; use syntax::parse; use syntax::symbol::Symbol; @@ -410,6 +412,7 @@ top_level_options!( // Remap source path prefixes in all output (messages, object files, debug, etc) remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED], + edition: Edition [UNTRACKED], } ); @@ -589,6 +592,7 @@ pub fn basic_options() -> Options { cli_forced_codegen_units: None, cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), + edition: DEFAULT_EDITION, } } @@ -773,8 +777,6 @@ macro_rules! options { Some("`string` or `string=string`"); pub const parse_lto: Option<&'static str> = Some("one of `thin`, `fat`, or omitted"); - pub const parse_edition: Option<&'static str> = - Some("one of: `2015`, `2018`"); } #[allow(dead_code)] @@ -782,7 +784,6 @@ macro_rules! options { use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto}; use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; use std::path::PathBuf; - use syntax::edition::Edition; $( pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { @@ -985,20 +986,6 @@ macro_rules! options { true } - fn parse_edition(slot: &mut Edition, v: Option<&str>) -> bool { - match v { - Some(s) => { - let edition = s.parse(); - if let Ok(parsed) = edition { - *slot = parsed; - true - } else { - false - } - } - _ => false, - } - } } ) } @@ -1292,10 +1279,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, `everybody_loops` (all function bodies replaced with `loop {}`), `hir` (the HIR), `hir,identified`, or `hir,typed` (HIR with types for each node)."), - edition: Edition = (Edition::Edition2015, parse_edition, [TRACKED], - "The edition to build Rust with. Newer editions may include features - that require breaking changes. The default edition is 2015 (the first - edition). Crates compiled with different editions can be linked together."), run_dsymutil: Option = (None, parse_opt_bool, [TRACKED], "run `dsymutil` and delete intermediate object files"), ui_testing: bool = (false, parse_bool, [UNTRACKED], @@ -1656,6 +1639,12 @@ pub fn rustc_optgroups() -> Vec { `expanded,identified` (fully parenthesized, AST nodes with IDs).", "TYPE", ), + opt::opt_s( + "", + "edition", + "Specify which edition of the compiler to use when compiling code.", + &edition_name_list(), + ), opt::multi_s( "", "remap-path-prefix", @@ -1715,6 +1704,22 @@ pub fn build_session_options_and_crate_config( ), }; + let edition = match matches.opt_str("edition") { + Some(arg) => match Edition::from_str(&arg){ + Ok(edition) => edition, + Err(_) => early_error( + ErrorOutputType::default(), + &format!( + "argument for --edition must be one of: \ + {}. (instead was `{}`)", + edition_name_list(), + arg + ), + ), + } + None => DEFAULT_EDITION, + }; + // We need the opts_present check because the driver will send us Matches // with only stable options if no unstable options are used. Since error-format // is unstable, it will not be present. We have to use opts_present not @@ -2171,6 +2176,7 @@ pub fn build_session_options_and_crate_config( cli_forced_codegen_units: codegen_units, cli_forced_thinlto_off: disable_thinlto, remap_path_prefix, + edition, }, cfg, ) @@ -2300,7 +2306,7 @@ mod dep_tracking { use std::hash::Hash; use std::path::PathBuf; use std::collections::hash_map::DefaultHasher; - use super::{CrateType, DebugInfoLevel, Edition, ErrorOutputType, Lto, OptLevel, OutputTypes, + use super::{CrateType, DebugInfoLevel, ErrorOutputType, Lto, OptLevel, OutputTypes, Passes, Sanitizer}; use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; @@ -2363,7 +2369,6 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind); impl_dep_tracking_hash_via_hash!(Sanitizer); impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Edition); impl_dep_tracking_hash_via_hash!(TargetTriple); impl_dep_tracking_hash_for_sortable_vec_of!(String); @@ -2422,6 +2427,11 @@ mod dep_tracking { } } +pub fn edition_name_list() -> String { + let names: Vec = ALL_EDITIONS.iter().map(|e| format!("{}", e)).collect(); + names.join("|") +} + #[cfg(test)] mod tests { use errors; @@ -3081,4 +3091,17 @@ mod tests { opts.debugging_opts.relro_level = Some(RelroLevel::Full); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } + + #[test] + fn test_edition_parsing() { + // test default edition + let options = super::basic_options(); + assert!(options.edition == Edition::DEFAULT_EDITION); + + let matches = optgroups() + .parse(&["--edition=2018".to_string()]) + .unwrap(); + let (sessopts, _) = build_session_options_and_crate_config(&matches); + assert!(sessopts.edition == Edition::Edition2018) + } } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 2993234f26625..5e4dee7fb60ca 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -934,11 +934,11 @@ impl Session { /// Are we allowed to use features from the Rust 2018 edition? pub fn rust_2018(&self) -> bool { - self.opts.debugging_opts.edition >= Edition::Edition2018 + self.opts.edition >= Edition::Edition2018 } pub fn edition(&self) -> Edition { - self.opts.debugging_opts.edition + self.opts.edition } } diff --git a/src/libsyntax/edition.rs b/src/libsyntax/edition.rs index e579fc74b4266..4c1d52d7b0766 100644 --- a/src/libsyntax/edition.rs +++ b/src/libsyntax/edition.rs @@ -27,17 +27,13 @@ pub enum Edition { // - the list in the `parse_edition` static in librustc::session::config // - add a `rust_####()` function to the session // - update the enum in Cargo's sources as well - // - // When -Zedition becomes --edition, there will - // also be a check for the edition being nightly-only - // somewhere. That will need to be updated - // whenever we're stabilizing/introducing a new edition - // as well as changing the default Cargo template. } // must be in order from oldest to newest pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; +pub const DEFAULT_EDITION: Edition = Edition::Edition2015; + impl fmt::Display for Edition { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { From 320fdaa9423ba2ae35c283707c1501a03dd511cf Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Thu, 19 Apr 2018 21:03:21 -0700 Subject: [PATCH 2/4] add EDITIONS_NAME_LIST, make edition tracked, enforce that only stable editions are allowed to be used on non-nightly builds --- src/librustc/session/config.rs | 27 ++++++++++++++++++--------- src/librustc_driver/driver.rs | 2 +- src/libsyntax/edition.rs | 12 +++++++++++- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2d0b4eecf63c6..aac1c2fc02bbe 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -30,7 +30,7 @@ use middle::cstore; use syntax::ast::{self, IntTy, UintTy}; use syntax::codemap::{FileName, FilePathMapping}; -use syntax::edition::{Edition, ALL_EDITIONS, DEFAULT_EDITION}; +use syntax::edition::{Edition, EDITION_NAME_LIST, DEFAULT_EDITION}; use syntax::parse::token; use syntax::parse; use syntax::symbol::Symbol; @@ -412,7 +412,7 @@ top_level_options!( // Remap source path prefixes in all output (messages, object files, debug, etc) remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED], - edition: Edition [UNTRACKED], + edition: Edition [TRACKED], } ); @@ -1643,7 +1643,7 @@ pub fn rustc_optgroups() -> Vec { "", "edition", "Specify which edition of the compiler to use when compiling code.", - &edition_name_list(), + EDITION_NAME_LIST, ), opt::multi_s( "", @@ -1712,7 +1712,7 @@ pub fn build_session_options_and_crate_config( &format!( "argument for --edition must be one of: \ {}. (instead was `{}`)", - edition_name_list(), + EDITION_NAME_LIST, arg ), ), @@ -1720,6 +1720,18 @@ pub fn build_session_options_and_crate_config( None => DEFAULT_EDITION, }; + if !edition.is_stable() && !nightly_options::is_nightly_build() { + early_error( + ErrorOutputType::default(), + &format!( + "Edition {} is unstable an only\ + available for nightly builds of rustc.", + edition, + ) + ) + } + + // We need the opts_present check because the driver will send us Matches // with only stable options if no unstable options are used. Since error-format // is unstable, it will not be present. We have to use opts_present not @@ -2311,6 +2323,7 @@ mod dep_tracking { use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; use rustc_back::target::TargetTriple; + use syntax::edition::Edition; pub trait DepTrackingHash { fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType); @@ -2370,6 +2383,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(Sanitizer); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(TargetTriple); + impl_dep_tracking_hash_via_hash!(Edition); impl_dep_tracking_hash_for_sortable_vec_of!(String); impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); @@ -2427,11 +2441,6 @@ mod dep_tracking { } } -pub fn edition_name_list() -> String { - let names: Vec = ALL_EDITIONS.iter().map(|e| format!("{}", e)).collect(); - names.join("|") -} - #[cfg(test)] mod tests { use errors; diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f8c0289cc98c8..2c781fda4ed03 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -691,7 +691,7 @@ where krate, &sess.parse_sess, sess.opts.test, - sess.opts.debugging_opts.edition, + sess.edition(), ); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); diff --git a/src/libsyntax/edition.rs b/src/libsyntax/edition.rs index 4c1d52d7b0766..3fc1c279f5a22 100644 --- a/src/libsyntax/edition.rs +++ b/src/libsyntax/edition.rs @@ -24,7 +24,8 @@ pub enum Edition { // when adding new editions, be sure to update: // - // - the list in the `parse_edition` static in librustc::session::config + // - Update the `ALL_EDITIONS` const + // - Update the EDITION_NAME_LIST const // - add a `rust_####()` function to the session // - update the enum in Cargo's sources as well } @@ -32,6 +33,8 @@ pub enum Edition { // must be in order from oldest to newest pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; +pub const EDITION_NAME_LIST: &'static str = "2015|2018"; + pub const DEFAULT_EDITION: Edition = Edition::Edition2015; impl fmt::Display for Edition { @@ -58,6 +61,13 @@ impl Edition { Edition::Edition2018 => "rust_2018_preview", } } + + pub fn is_stable(&self) -> bool { + match *self { + Edition::Edition2015 => true, + Edition::Edition2018 => false, + } + } } impl FromStr for Edition { From c1d8aa829c5514bb1b6c9fe41c82505bd1aa575c Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Fri, 20 Apr 2018 14:47:23 -0700 Subject: [PATCH 3/4] fix some small compile errors --- src/librustc/session/config.rs | 3 ++- src/librustdoc/core.rs | 2 +- src/librustdoc/test.rs | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index aac1c2fc02bbe..e9fe94cdb4a36 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -2456,6 +2456,7 @@ mod tests { use super::{Externs, OutputType, OutputTypes}; use rustc_back::{PanicStrategy, RelroLevel}; use syntax::symbol::Symbol; + use syntax::edition::{Edition, DEFAULT_EDITION}; use syntax; fn optgroups() -> getopts::Options { @@ -3105,7 +3106,7 @@ mod tests { fn test_edition_parsing() { // test default edition let options = super::basic_options(); - assert!(options.edition == Edition::DEFAULT_EDITION); + assert!(options.edition == DEFAULT_EDITION); let matches = optgroups() .parse(&["--edition=2018".to_string()]) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 9fb024fd90609..2bd1e72f0eb17 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -155,10 +155,10 @@ pub fn run_core(search_paths: SearchPaths, actually_rustdoc: true, debugging_opts: config::DebuggingOptions { force_unstable_if_unmarked, - edition, ..config::basic_debugging_options() }, error_format, + edition, ..config::basic_options().clone() }; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 600e9eaa05f14..24fc4224b7922 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -80,9 +80,9 @@ pub fn run(input_path: &Path, lint_cap: Some(::rustc::lint::Level::Allow), actually_rustdoc: true, debugging_opts: config::DebuggingOptions { - edition, ..config::basic_debugging_options() }, + edition, ..config::basic_options().clone() }; @@ -223,9 +223,9 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, test: as_test_harness, unstable_features: UnstableFeatures::from_environment(), debugging_opts: config::DebuggingOptions { - edition, ..config::basic_debugging_options() }, + edition, ..config::basic_options().clone() }; From c8c9bf97e3ed2eab3ed60a3412574e7c5b548eab Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Fri, 20 Apr 2018 18:51:59 -0700 Subject: [PATCH 4/4] fix two compile-fail tests that were still using -Zedition --- src/test/compile-fail/edition-raw-pointer-method-2015.rs | 2 +- src/test/compile-fail/edition-raw-pointer-method-2018.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail/edition-raw-pointer-method-2015.rs b/src/test/compile-fail/edition-raw-pointer-method-2015.rs index fdc9b4f704cd1..b304443f63145 100644 --- a/src/test/compile-fail/edition-raw-pointer-method-2015.rs +++ b/src/test/compile-fail/edition-raw-pointer-method-2015.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Zedition=2015 -Zunstable-options +// compile-flags: --edition=2015 -Zunstable-options // tests that editions work with the tyvar warning-turned-error diff --git a/src/test/compile-fail/edition-raw-pointer-method-2018.rs b/src/test/compile-fail/edition-raw-pointer-method-2018.rs index 58b34591029ba..d01cac019e36c 100644 --- a/src/test/compile-fail/edition-raw-pointer-method-2018.rs +++ b/src/test/compile-fail/edition-raw-pointer-method-2018.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Zedition=2018 -Zunstable-options +// compile-flags: --edition=2018 -Zunstable-options // tests that editions work with the tyvar warning-turned-error