Centralize nightly compiler flags handling

This commit is contained in:
Guillaume Gomez
2016-03-15 09:09:29 +01:00
parent f34ae3f7ed
commit ded701bf64
4 changed files with 154 additions and 157 deletions

View File

@@ -785,12 +785,12 @@ impl RustcOptGroup {
self.stability == OptionStability::Stable self.stability == OptionStability::Stable
} }
fn stable(g: getopts::OptGroup) -> RustcOptGroup { pub fn stable(g: getopts::OptGroup) -> RustcOptGroup {
RustcOptGroup { opt_group: g, stability: OptionStability::Stable } RustcOptGroup { opt_group: g, stability: OptionStability::Stable }
} }
#[allow(dead_code)] // currently we have no "truly unstable" options #[allow(dead_code)] // currently we have no "truly unstable" options
fn unstable(g: getopts::OptGroup) -> RustcOptGroup { pub fn unstable(g: getopts::OptGroup) -> RustcOptGroup {
RustcOptGroup { opt_group: g, stability: OptionStability::Unstable } RustcOptGroup { opt_group: g, stability: OptionStability::Unstable }
} }
@@ -926,8 +926,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
pub fn rustc_optgroups() -> Vec<RustcOptGroup> { pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
let mut opts = rustc_short_optgroups(); let mut opts = rustc_short_optgroups();
opts.extend_from_slice(&[ opts.extend_from_slice(&[
opt::multi_s("", "extern", "Specify where an external rust library is \ opt::multi_s("", "extern", "Specify where an external rust library is located",
located",
"NAME=PATH"), "NAME=PATH"),
opt::opt_s("", "sysroot", "Override the system root", "PATH"), opt::opt_s("", "sysroot", "Override the system root", "PATH"),
opt::multi_ubnr("Z", "", "Set internal debugging options", "FLAG"), opt::multi_ubnr("Z", "", "Set internal debugging options", "FLAG"),
@@ -1263,7 +1262,6 @@ pub fn get_unstable_features_setting() -> UnstableFeatures {
} }
pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> { pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
let mut crate_types: Vec<CrateType> = Vec::new(); let mut crate_types: Vec<CrateType> = Vec::new();
for unparsed_crate_type in &list_list { for unparsed_crate_type in &list_list {
for part in unparsed_crate_type.split(',') { for part in unparsed_crate_type.split(',') {
@@ -1287,6 +1285,72 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
return Ok(crate_types); return Ok(crate_types);
} }
pub mod nightly_options {
use getopts;
use syntax::feature_gate::UnstableFeatures;
use super::{ErrorOutputType, OptionStability, RustcOptGroup, get_unstable_features_setting};
use session::{early_error, early_warn};
pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
is_nightly_build() && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
}
fn is_nightly_build() -> bool {
match get_unstable_features_setting() {
UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
_ => false,
}
}
pub fn check_nightly_options(matches: &getopts::Matches, flags: &[RustcOptGroup]) {
let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
let really_allows_unstable_options = match get_unstable_features_setting() {
UnstableFeatures::Disallow => false,
_ => true,
};
for opt in flags.iter() {
if opt.stability == OptionStability::Stable {
continue
}
let opt_name = if opt.opt_group.long_name.is_empty() {
&opt.opt_group.short_name
} else {
&opt.opt_group.long_name
};
if !matches.opt_present(opt_name) {
continue
}
if opt_name != "Z" && !has_z_unstable_option {
early_error(ErrorOutputType::default(),
&format!("the `-Z unstable-options` flag must also be passed to enable \
the flag `{}`",
opt_name));
}
if really_allows_unstable_options {
continue
}
match opt.stability {
OptionStability::Unstable => {
let msg = format!("the option `{}` is only accepted on the \
nightly compiler", opt_name);
early_error(ErrorOutputType::default(), &msg);
}
OptionStability::UnstableButNotReally => {
let msg = format!("the option `{}` is is unstable and should \
only be used on the nightly compiler, but \
it is currently accepted for backwards \
compatibility; this will soon change, \
see issue #31847 for more details",
opt_name);
early_warn(ErrorOutputType::default(), &msg);
}
OptionStability::Stable => {}
}
}
}
}
impl fmt::Display for CrateType { impl fmt::Display for CrateType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {

View File

@@ -68,7 +68,7 @@ use rustc_save_analysis as save;
use rustc_trans::back::link; use rustc_trans::back::link;
use rustc::session::{config, Session, build_session, CompileResult}; use rustc::session::{config, Session, build_session, CompileResult};
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType}; use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
use rustc::session::config::{get_unstable_features_setting, OptionStability}; use rustc::session::config::{get_unstable_features_setting, nightly_options};
use rustc::middle::cstore::CrateStore; use rustc::middle::cstore::CrateStore;
use rustc::lint::Lint; use rustc::lint::Lint;
use rustc::lint; use rustc::lint;
@@ -89,7 +89,7 @@ use std::str;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
use rustc::session::{early_error, early_warn}; use rustc::session::early_error;
use syntax::ast; use syntax::ast;
use syntax::parse::{self, PResult}; use syntax::parse::{self, PResult};
@@ -910,51 +910,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
// (unstable option being used on stable) // (unstable option being used on stable)
// * If we're a historically stable-but-should-be-unstable option then we // * If we're a historically stable-but-should-be-unstable option then we
// emit a warning that we're going to turn this into an error soon. // emit a warning that we're going to turn this into an error soon.
let has_z_unstable_options = matches.opt_strs("Z") nightly_options::check_nightly_options(&matches, &config::rustc_optgroups());
.iter()
.any(|x| *x == "unstable-options");
let really_allows_unstable_options = match get_unstable_features_setting() {
UnstableFeatures::Disallow => false,
_ => true,
};
for opt in config::rustc_optgroups() {
if opt.stability == OptionStability::Stable {
continue
}
let opt_name = if opt.opt_group.long_name.is_empty() {
&opt.opt_group.short_name
} else {
&opt.opt_group.long_name
};
if !matches.opt_present(opt_name) {
continue
}
if opt_name != "Z" && !has_z_unstable_options {
let msg = format!("the `-Z unstable-options` flag must also be \
passed to enable the flag `{}`", opt_name);
early_error(ErrorOutputType::default(), &msg);
}
if really_allows_unstable_options {
continue
}
match opt.stability {
OptionStability::Unstable => {
let msg = format!("the option `{}` is only accepted on the \
nightly compiler", opt_name);
early_error(ErrorOutputType::default(), &msg);
}
OptionStability::UnstableButNotReally => {
let msg = format!("the option `{}` is is unstable and should \
only be used on the nightly compiler, but \
it is currently accepted for backwards \
compatibility; this will soon change, \
see issue #31847 for more details",
opt_name);
early_warn(ErrorOutputType::default(), &msg);
}
OptionStability::Stable => {}
}
}
if matches.opt_present("h") || matches.opt_present("help") { if matches.opt_present("h") || matches.opt_present("help") {
// Only show unstable options in --help if we *really* accept unstable // Only show unstable options in --help if we *really* accept unstable
@@ -962,12 +918,11 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
// the stable channel of Rust which was accidentally allowed // the stable channel of Rust which was accidentally allowed
// historically. // historically.
usage(matches.opt_present("verbose"), usage(matches.opt_present("verbose"),
has_z_unstable_options && really_allows_unstable_options); nightly_options::is_unstable_enabled(&matches));
return None; return None;
} }
// Don't handle -W help here, because we might first load plugins. // Don't handle -W help here, because we might first load plugins.
let r = matches.opt_strs("Z"); let r = matches.opt_strs("Z");
if r.iter().any(|x| *x == "help") { if r.iter().any(|x| *x == "help") {
describe_debug_flags(); describe_debug_flags();

View File

@@ -433,10 +433,6 @@ pub fn run(mut krate: clean::Crate,
krate: krate.name.clone(), krate: krate.name.clone(),
playground_url: "".to_string(), playground_url: "".to_string(),
}, },
include_sources: true,
local_sources: HashMap::new(),
render_redirect_pages: false,
issue_tracker_base_url: None,
css_file_extension: css_file_extension, css_file_extension: css_file_extension,
}; };

View File

@@ -65,10 +65,8 @@ use std::sync::mpsc::channel;
use externalfiles::ExternalHtml; use externalfiles::ExternalHtml;
use serialize::Decodable; use serialize::Decodable;
use serialize::json::{self, Json}; use serialize::json::{self, Json};
use rustc::session::early_error;
use rustc::session::search_paths::SearchPaths; use rustc::session::search_paths::SearchPaths;
use rustc::session::config::{get_unstable_features_setting, ErrorOutputType}; use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options};
use syntax::feature_gate::UnstableFeatures;
// reexported from `clean` so it can be easily updated with the mod itself // reexported from `clean` so it can be easily updated with the mod itself
pub use clean::SCHEMA_VERSION; pub use clean::SCHEMA_VERSION;
@@ -143,86 +141,87 @@ pub fn main() {
process::exit(res as i32); process::exit(res as i32);
} }
pub fn opts() -> Vec<getopts::OptGroup> { fn stable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::stable(g) }
fn unstable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::unstable(g) }
pub fn opts() -> Vec<RustcOptGroup> {
use getopts::*; use getopts::*;
vec!( vec!(
optflag("h", "help", "show this help message"), stable(optflag("h", "help", "show this help message")),
optflag("V", "version", "print rustdoc's version"), stable(optflag("V", "version", "print rustdoc's version")),
optflag("v", "verbose", "use verbose output"), stable(optflag("v", "verbose", "use verbose output")),
optopt("r", "input-format", "the input type of the specified file", stable(optopt("r", "input-format", "the input type of the specified file",
"[rust|json]"), "[rust|json]")),
optopt("w", "output-format", "the output type to write", stable(optopt("w", "output-format", "the output type to write",
"[html|json]"), "[html|json]")),
optopt("o", "output", "where to place the output", "PATH"), stable(optopt("o", "output", "where to place the output", "PATH")),
optopt("", "crate-name", "specify the name of this crate", "NAME"), stable(optopt("", "crate-name", "specify the name of this crate", "NAME")),
optmulti("L", "library-path", "directory to add to crate search path", stable(optmulti("L", "library-path", "directory to add to crate search path",
"DIR"), "DIR")),
optmulti("", "cfg", "pass a --cfg to rustc", ""), stable(optmulti("", "cfg", "pass a --cfg to rustc", "")),
optmulti("", "extern", "pass an --extern to rustc", "NAME=PATH"), stable(optmulti("", "extern", "pass an --extern to rustc", "NAME=PATH")),
optmulti("", "plugin-path", "directory to load plugins from", "DIR"), stable(optmulti("", "plugin-path", "directory to load plugins from", "DIR")),
optmulti("", "passes", "list of passes to also run, you might want \ stable(optmulti("", "passes",
"list of passes to also run, you might want \
to pass it multiple times; a value of `list` \ to pass it multiple times; a value of `list` \
will print available passes", will print available passes",
"PASSES"), "PASSES")),
optmulti("", "plugins", "space separated list of plugins to also load", stable(optmulti("", "plugins", "space separated list of plugins to also load",
"PLUGINS"), "PLUGINS")),
optflag("", "no-defaults", "don't run the default passes"), stable(optflag("", "no-defaults", "don't run the default passes")),
optflag("", "test", "run code examples as tests"), stable(optflag("", "test", "run code examples as tests")),
optmulti("", "test-args", "arguments to pass to the test runner", stable(optmulti("", "test-args", "arguments to pass to the test runner",
"ARGS"), "ARGS")),
optopt("", "target", "target triple to document", "TRIPLE"), stable(optopt("", "target", "target triple to document", "TRIPLE")),
optmulti("", "markdown-css", "CSS files to include via <link> in a rendered Markdown file", stable(optmulti("", "markdown-css",
"FILES"), "CSS files to include via <link> in a rendered Markdown file",
optmulti("", "html-in-header", "FILES")),
stable(optmulti("", "html-in-header",
"files to include inline in the <head> section of a rendered Markdown file \ "files to include inline in the <head> section of a rendered Markdown file \
or generated documentation", or generated documentation",
"FILES"), "FILES")),
optmulti("", "html-before-content", stable(optmulti("", "html-before-content",
"files to include inline between <body> and the content of a rendered \ "files to include inline between <body> and the content of a rendered \
Markdown file or generated documentation", Markdown file or generated documentation",
"FILES"), "FILES")),
optmulti("", "html-after-content", stable(optmulti("", "html-after-content",
"files to include inline between the content and </body> of a rendered \ "files to include inline between the content and </body> of a rendered \
Markdown file or generated documentation", Markdown file or generated documentation",
"FILES"), "FILES")),
optopt("", "markdown-playground-url", stable(optopt("", "markdown-playground-url",
"URL to send code snippets to", "URL"), "URL to send code snippets to", "URL")),
optflag("", "markdown-no-toc", "don't include table of contents"), stable(optflag("", "markdown-no-toc", "don't include table of contents")),
optopt("e", "extend-css", unstable(optopt("e", "extend-css",
"to redefine some css rules with a given file to generate doc with your \ "to redefine some css rules with a given file to generate doc with your \
own theme", "PATH"), own theme", "PATH")),
optmulti("Z", "", "internal and debugging options (only on nightly build)", "FLAG"), unstable(optmulti("Z", "",
"internal and debugging options (only on nightly build)", "FLAG")),
) )
} }
pub fn usage(argv0: &str) { pub fn usage(argv0: &str) {
println!("{}", println!("{}",
getopts::usage(&format!("{} [options] <input>", argv0), getopts::usage(&format!("{} [options] <input>", argv0),
&opts())); &opts().into_iter()
} .map(|x| x.opt_group)
.collect::<Vec<getopts::OptGroup>>()));
fn check_unstable_flag_enabled(nightly_build: bool, has_z_unstable_options: bool,
flag_name: &str) {
// check if unstable for --extend-css option
let e = if !nightly_build {
format!("the option `{}` is only accepted on the nightly compiler", flag_name)
} else if !has_z_unstable_options {
format!("the `-Z unstable-options` flag must also be passed to enable the flag `{}`",
flag_name)
} else {
return
};
early_error(ErrorOutputType::default(), &e)
} }
pub fn main_args(args: &[String]) -> isize { pub fn main_args(args: &[String]) -> isize {
let matches = match getopts::getopts(&args[1..], &opts()) { let all_groups: Vec<getopts::OptGroup> = opts()
.into_iter()
.map(|x| x.opt_group)
.collect();
let matches = match getopts::getopts(&args[1..], &all_groups) {
Ok(m) => m, Ok(m) => m,
Err(err) => { Err(err) => {
println!("{}", err); println!("{}", err);
return 1; return 1;
} }
}; };
// Check for unstable options.
nightly_options::check_nightly_options(&matches, &opts());
if matches.opt_present("h") || matches.opt_present("help") { if matches.opt_present("h") || matches.opt_present("help") {
usage(&args[0]); usage(&args[0]);
return 0; return 0;
@@ -277,24 +276,7 @@ pub fn main_args(args: &[String]) -> isize {
let css_file_extension = matches.opt_str("e").map(|s| PathBuf::from(&s)); let css_file_extension = matches.opt_str("e").map(|s| PathBuf::from(&s));
let cfgs = matches.opt_strs("cfg"); let cfgs = matches.opt_strs("cfg");
// we now check if unstable options are allowed and if we're in a nightly build
let mut has_z_unstable_options = false;
for flag in matches.opt_strs("Z").iter() {
if *flag != "unstable-options" {
println!("Unknown flag for `Z` option: {}", flag);
return 1;
} else {
has_z_unstable_options = true;
}
}
let nightly_build = get_unstable_features_setting();
let nightly_build = match nightly_build {
UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
_ => false,
};
if let Some(ref p) = css_file_extension { if let Some(ref p) = css_file_extension {
check_unstable_flag_enabled(nightly_build, has_z_unstable_options, "extend-css");
if !p.is_file() { if !p.is_file() {
println!("{}", "--extend-css option must take a css file as input"); println!("{}", "--extend-css option must take a css file as input");
return 1; return 1;