Skip to content

rustc: Refactor how unstable flags are handled #31793

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

Merged
merged 1 commit into from
Feb 25, 2016
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
181 changes: 117 additions & 64 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,24 +749,20 @@ pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
}
}

/// Returns the "short" subset of the stable rustc command line options.
pub fn short_optgroups() -> Vec<getopts::OptGroup> {
rustc_short_optgroups().into_iter()
.filter(|g|g.is_stable())
.map(|g|g.opt_group)
.collect()
}

/// Returns all of the stable rustc command line options.
pub fn optgroups() -> Vec<getopts::OptGroup> {
rustc_optgroups().into_iter()
.filter(|g|g.is_stable())
.map(|g|g.opt_group)
.collect()
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum OptionStability { Stable, Unstable }
pub enum OptionStability {
Stable,

// FIXME: historically there were some options which were either `-Z` or
// required the `-Z unstable-options` flag, which were all intended
// to be unstable. Unfortunately we didn't actually gate usage of
// these options on the stable compiler, so we still allow them there
// today. There are some warnings printed out about this in the
// driver.
UnstableButNotReally,

Unstable,
}

#[derive(Clone, PartialEq, Eq)]
pub struct RustcOptGroup {
Expand All @@ -783,9 +779,17 @@ impl RustcOptGroup {
RustcOptGroup { opt_group: g, stability: OptionStability::Stable }
}

#[allow(dead_code)] // currently we have no "truly unstable" options
fn unstable(g: getopts::OptGroup) -> RustcOptGroup {
RustcOptGroup { opt_group: g, stability: OptionStability::Unstable }
}

fn unstable_bnr(g: getopts::OptGroup) -> RustcOptGroup {
RustcOptGroup {
opt_group: g,
stability: OptionStability::UnstableButNotReally,
}
}
}

// The `opt` local module holds wrappers around the `getopts` API that
Expand All @@ -807,69 +811,102 @@ mod opt {

fn stable(g: getopts::OptGroup) -> R { RustcOptGroup::stable(g) }
fn unstable(g: getopts::OptGroup) -> R { RustcOptGroup::unstable(g) }
fn unstable_bnr(g: getopts::OptGroup) -> R { RustcOptGroup::unstable_bnr(g) }

// FIXME (pnkfelix): We default to stable since the current set of
// options is defacto stable. However, it would be good to revise the
// code so that a stable option is the thing that takes extra effort
// to encode.

pub fn opt(a: S, b: S, c: S, d: S) -> R { stable(getopts::optopt(a, b, c, d)) }
pub fn multi(a: S, b: S, c: S, d: S) -> R { stable(getopts::optmulti(a, b, c, d)) }
pub fn flag(a: S, b: S, c: S) -> R { stable(getopts::optflag(a, b, c)) }
pub fn flagopt(a: S, b: S, c: S, d: S) -> R { stable(getopts::optflagopt(a, b, c, d)) }
pub fn flagmulti(a: S, b: S, c: S) -> R { stable(getopts::optflagmulti(a, b, c)) }
pub fn opt_s(a: S, b: S, c: S, d: S) -> R {
stable(getopts::optopt(a, b, c, d))
}
pub fn multi_s(a: S, b: S, c: S, d: S) -> R {
stable(getopts::optmulti(a, b, c, d))
}
pub fn flag_s(a: S, b: S, c: S) -> R {
stable(getopts::optflag(a, b, c))
}
pub fn flagopt_s(a: S, b: S, c: S, d: S) -> R {
stable(getopts::optflagopt(a, b, c, d))
}
pub fn flagmulti_s(a: S, b: S, c: S) -> R {
stable(getopts::optflagmulti(a, b, c))
}

pub fn opt(a: S, b: S, c: S, d: S) -> R {
unstable(getopts::optopt(a, b, c, d))
}
pub fn multi(a: S, b: S, c: S, d: S) -> R {
unstable(getopts::optmulti(a, b, c, d))
}
pub fn flag(a: S, b: S, c: S) -> R {
unstable(getopts::optflag(a, b, c))
}
pub fn flagopt(a: S, b: S, c: S, d: S) -> R {
unstable(getopts::optflagopt(a, b, c, d))
}
pub fn flagmulti(a: S, b: S, c: S) -> R {
unstable(getopts::optflagmulti(a, b, c))
}

pub fn opt_u(a: S, b: S, c: S, d: S) -> R { unstable(getopts::optopt(a, b, c, d)) }
pub fn multi_u(a: S, b: S, c: S, d: S) -> R { unstable(getopts::optmulti(a, b, c, d)) }
pub fn flag_u(a: S, b: S, c: S) -> R { unstable(getopts::optflag(a, b, c)) }
pub fn flagopt_u(a: S, b: S, c: S, d: S) -> R { unstable(getopts::optflagopt(a, b, c, d)) }
pub fn flagmulti_u(a: S, b: S, c: S) -> R { unstable(getopts::optflagmulti(a, b, c)) }
// Do not use these functions for any new options added to the compiler, all
// new options should use the `*_u` variants above to be truly unstable.
pub fn opt_ubnr(a: S, b: S, c: S, d: S) -> R {
unstable_bnr(getopts::optopt(a, b, c, d))
}
pub fn multi_ubnr(a: S, b: S, c: S, d: S) -> R {
unstable_bnr(getopts::optmulti(a, b, c, d))
}
pub fn flag_ubnr(a: S, b: S, c: S) -> R {
unstable_bnr(getopts::optflag(a, b, c))
}
pub fn flagopt_ubnr(a: S, b: S, c: S, d: S) -> R {
unstable_bnr(getopts::optflagopt(a, b, c, d))
}
pub fn flagmulti_ubnr(a: S, b: S, c: S) -> R {
unstable_bnr(getopts::optflagmulti(a, b, c))
}
}

/// Returns the "short" subset of the rustc command line options,
/// including metadata for each option, such as whether the option is
/// part of the stable long-term interface for rustc.
pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
vec![
opt::flag("h", "help", "Display this message"),
opt::multi("", "cfg", "Configure the compilation environment", "SPEC"),
opt::multi("L", "", "Add a directory to the library search path",
opt::flag_s("h", "help", "Display this message"),
opt::multi_s("", "cfg", "Configure the compilation environment", "SPEC"),
opt::multi_s("L", "", "Add a directory to the library search path",
"[KIND=]PATH"),
opt::multi("l", "", "Link the generated crate(s) to the specified native
opt::multi_s("l", "", "Link the generated crate(s) to the specified native
library NAME. The optional KIND can be one of,
static, dylib, or framework. If omitted, dylib is
assumed.", "[KIND=]NAME"),
opt::multi("", "crate-type", "Comma separated list of types of crates
opt::multi_s("", "crate-type", "Comma separated list of types of crates
for the compiler to emit",
"[bin|lib|rlib|dylib|staticlib]"),
opt::opt("", "crate-name", "Specify the name of the crate being built",
opt::opt_s("", "crate-name", "Specify the name of the crate being built",
"NAME"),
opt::multi("", "emit", "Comma separated list of types of output for \
opt::multi_s("", "emit", "Comma separated list of types of output for \
the compiler to emit",
"[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
opt::multi("", "print", "Comma separated list of compiler information to \
opt::multi_s("", "print", "Comma separated list of compiler information to \
print on stdout",
"[crate-name|file-names|sysroot|target-list]"),
opt::flagmulti("g", "", "Equivalent to -C debuginfo=2"),
opt::flagmulti("O", "", "Equivalent to -C opt-level=2"),
opt::opt("o", "", "Write output to <filename>", "FILENAME"),
opt::opt("", "out-dir", "Write output to compiler-chosen filename \
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
opt::opt_s("", "out-dir", "Write output to compiler-chosen filename \
in <dir>", "DIR"),
opt::opt("", "explain", "Provide a detailed explanation of an error \
opt::opt_s("", "explain", "Provide a detailed explanation of an error \
message", "OPT"),
opt::flag("", "test", "Build a test harness"),
opt::opt("", "target", "Target triple for which the code is compiled", "TARGET"),
opt::multi("W", "warn", "Set lint warnings", "OPT"),
opt::multi("A", "allow", "Set lint allowed", "OPT"),
opt::multi("D", "deny", "Set lint denied", "OPT"),
opt::multi("F", "forbid", "Set lint forbidden", "OPT"),
opt::multi("", "cap-lints", "Set the most restrictive lint level. \
opt::flag_s("", "test", "Build a test harness"),
opt::opt_s("", "target", "Target triple for which the code is compiled", "TARGET"),
opt::multi_s("W", "warn", "Set lint warnings", "OPT"),
opt::multi_s("A", "allow", "Set lint allowed", "OPT"),
opt::multi_s("D", "deny", "Set lint denied", "OPT"),
opt::multi_s("F", "forbid", "Set lint forbidden", "OPT"),
opt::multi_s("", "cap-lints", "Set the most restrictive lint level. \
More restrictive lints are capped at this \
level", "LEVEL"),
opt::multi("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
opt::flag("V", "version", "Print version info and exit"),
opt::flag("v", "verbose", "Use verbose output"),
opt::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
opt::flag_s("V", "version", "Print version info and exit"),
opt::flag_s("v", "verbose", "Use verbose output"),
]
}

Expand All @@ -879,31 +916,41 @@ 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("", "extern", "Specify where an external rust library is \
opt::multi_s("", "extern", "Specify where an external rust library is \
located",
"NAME=PATH"),
opt::opt("", "sysroot", "Override the system root", "PATH"),
opt::multi("Z", "", "Set internal debugging options", "FLAG"),
opt::opt_u("", "error-format", "How errors and other messages are produced", "human|json"),
opt::opt("", "color", "Configure coloring of output:
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
opt::multi_ubnr("Z", "", "Set internal debugging options", "FLAG"),
opt::opt_ubnr("", "error-format",
"How errors and other messages are produced",
"human|json"),
opt::opt_s("", "color", "Configure coloring of output:
auto = colorize, if output goes to a tty (default);
always = always colorize output;
never = never colorize output", "auto|always|never"),

opt::flagopt_u("", "pretty",
opt::flagopt_ubnr("", "pretty",
"Pretty-print the input instead of compiling;
valid types are: `normal` (un-annotated source),
`expanded` (crates expanded), or
`expanded,identified` (fully parenthesized, AST nodes with IDs).",
"TYPE"),
opt::flagopt_u("", "unpretty",
opt::flagopt_ubnr("", "unpretty",
"Present the input source, unstable (and less-pretty) variants;
valid types are any of the types for `--pretty`, as well as:
`flowgraph=<nodeid>` (graphviz formatted flowgraph for node),
`everybody_loops` (all function bodies replaced with `loop {}`),
`hir` (the HIR), `hir,identified`, or
`hir,typed` (HIR with types for each node).",
"TYPE"),

// new options here should **not** use the `_ubnr` functions, all new
// unstable options should use the short variants to indicate that they
// are truly unstable. All `_ubnr` flags are just that way because they
// were so historically.
//
// You may also wish to keep this comment at the bottom of this list to
// ensure that others see it.
]);
opts
}
Expand Down Expand Up @@ -1242,15 +1289,21 @@ impl fmt::Display for CrateType {
#[cfg(test)]
mod tests {
use middle::cstore::DummyCrateStore;
use session::config::{build_configuration, optgroups, build_session_options};
use session::config::{build_configuration, build_session_options};
use session::build_session;

use std::rc::Rc;
use getopts::getopts;
use getopts::{getopts, OptGroup};
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostics;

fn optgroups() -> Vec<OptGroup> {
super::rustc_optgroups().into_iter()
.map(|a| a.opt_group)
.collect()
}

// When the user supplies --test we should implicitly supply --cfg test
#[test]
fn test_switch_implies_cfg_test() {
Expand Down
Loading