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
}
fn stable(g: getopts::OptGroup) -> RustcOptGroup {
pub fn stable(g: getopts::OptGroup) -> RustcOptGroup {
RustcOptGroup { opt_group: g, stability: OptionStability::Stable }
}
#[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 }
}
@@ -926,8 +926,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
let mut opts = rustc_short_optgroups();
opts.extend_from_slice(&[
opt::multi_s("", "extern", "Specify where an external rust library is \
located",
opt::multi_s("", "extern", "Specify where an external rust library is located",
"NAME=PATH"),
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
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> {
let mut crate_types: Vec<CrateType> = Vec::new();
for unparsed_crate_type in &list_list {
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);
}
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 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {

View File

@@ -68,7 +68,7 @@ use rustc_save_analysis as save;
use rustc_trans::back::link;
use rustc::session::{config, Session, build_session, CompileResult};
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::lint::Lint;
use rustc::lint;
@@ -89,7 +89,7 @@ use std::str;
use std::sync::{Arc, Mutex};
use std::thread;
use rustc::session::{early_error, early_warn};
use rustc::session::early_error;
use syntax::ast;
use syntax::parse::{self, PResult};
@@ -910,51 +910,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
// (unstable option being used on stable)
// * 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.
let has_z_unstable_options = 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 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 => {}
}
}
nightly_options::check_nightly_options(&matches, &config::rustc_optgroups());
if matches.opt_present("h") || matches.opt_present("help") {
// 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
// historically.
usage(matches.opt_present("verbose"),
has_z_unstable_options && really_allows_unstable_options);
nightly_options::is_unstable_enabled(&matches));
return None;
}
// Don't handle -W help here, because we might first load plugins.
let r = matches.opt_strs("Z");
if r.iter().any(|x| *x == "help") {
describe_debug_flags();

View File

@@ -433,10 +433,6 @@ pub fn run(mut krate: clean::Crate,
krate: krate.name.clone(),
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,
};

View File

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