From 51f51109ce8c3070ab186624c241216620942360 Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Thu, 19 Apr 2018 13:56:26 -0700 Subject: [PATCH] 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 2e6689efee5..2d0b4eecf63 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 2993234f266..5e4dee7fb60 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 e579fc74b42..4c1d52d7b07 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 {