Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add --edition option #50080

Merged
merged 4 commits into from
Apr 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 57 additions & 24 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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],
}
);

Expand Down Expand Up @@ -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,
}
}

Expand Down Expand Up @@ -773,16 +777,13 @@ 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)]
mod $mod_set {
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 {
Expand Down Expand Up @@ -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,
}
}
}
) }

Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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: \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need to handle stability here. If the picked edition is unstable, we should throw an error if the compiler is not nightly.

You can add a .stable() method to Edition that returns true for 2015.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do I know if the compiler is nightly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvm, found it

{}. (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
Expand Down Expand Up @@ -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,
)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}
}
4 changes: 2 additions & 2 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
};

Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
};

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

Expand Down
20 changes: 13 additions & 7 deletions src/libsyntax/edition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would really like to avoid introducing this. Would be great if we could derive it some way from something that already exists so we have one less thing to change when adding an edition.

Copy link
Member

@Manishearth Manishearth Apr 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using custom derives within libsyntax itself is annoying and tricky. We'd need to do a snapshot, I think.


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 {
Expand All @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/edition-raw-pointer-method-2015.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/edition-raw-pointer-method-2018.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down