Auto merge of #50080 - klnusbaum:edition_49591, r=Manishearth

add --edition option

This adds an official `edition` flag to the rust compiler
This commit is contained in:
bors 2018-04-21 05:28:21 +00:00
commit 9af69fe232
8 changed files with 78 additions and 39 deletions

View File

@ -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, EDITION_NAME_LIST, 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 [TRACKED],
}
);
@ -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<bool> = (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<RustcOptGroup> {
`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,34 @@ 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,
};
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
@ -2171,6 +2188,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,11 +2318,12 @@ 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};
use rustc_back::target::TargetTriple;
use syntax::edition::Edition;
pub trait DepTrackingHash {
fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType);
@ -2363,8 +2382,8 @@ 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<Sanitizer>);
impl_dep_tracking_hash_via_hash!(Edition);
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);
@ -2437,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 {
@ -3081,4 +3101,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 == 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)
}
}

View File

@ -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
}
}

View File

@ -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);

View File

@ -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()
};

View File

@ -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()
};

View File

@ -24,20 +24,19 @@ 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
//
// 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 EDITION_NAME_LIST: &'static str = "2015|2018";
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 {
@ -62,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 {

View File

@ -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

View File

@ -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