Skip to content

Commit 05485be

Browse files
committed
Rollup merge of rust-lang#31793 - alexcrichton:add-real-option-gating, r=nikomatsakis
This commit adds support for *truly* unstable options in the compiler, as well as adding warnings for the start of the deprecation path of unstable-but-not-really options. Specifically, the following behavior is now in place for handling unstable options: * As before, an unconditional error is emitted if an unstable option is passed and the `-Z unstable-options` flag is not present. Note that passing another `-Z` flag does not require passing `-Z unstable-options` as well. * New flags added to the compiler will be in the `Unstable` category as opposed to the `UnstableButNotReally` category which means they will unconditionally emit an error when used on stable. * All current flags are in a category where they will emit warnings when used that the option will soon be a hard error. Also as before, it is intended that `-Z` is akin to `#![feature]` in a crate where it is required to unlock unstable functionality. A nightly compiler which is used without any `-Z` flags should only be exercising stable behavior.
2 parents a48f958 + 1282833 commit 05485be

File tree

2 files changed

+215
-116
lines changed

2 files changed

+215
-116
lines changed

Diff for: src/librustc/session/config.rs

+117-64
Original file line numberDiff line numberDiff line change
@@ -749,24 +749,20 @@ pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
749749
}
750750
}
751751

752-
/// Returns the "short" subset of the stable rustc command line options.
753-
pub fn short_optgroups() -> Vec<getopts::OptGroup> {
754-
rustc_short_optgroups().into_iter()
755-
.filter(|g|g.is_stable())
756-
.map(|g|g.opt_group)
757-
.collect()
758-
}
759-
760-
/// Returns all of the stable rustc command line options.
761-
pub fn optgroups() -> Vec<getopts::OptGroup> {
762-
rustc_optgroups().into_iter()
763-
.filter(|g|g.is_stable())
764-
.map(|g|g.opt_group)
765-
.collect()
766-
}
767-
768752
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
769-
pub enum OptionStability { Stable, Unstable }
753+
pub enum OptionStability {
754+
Stable,
755+
756+
// FIXME: historically there were some options which were either `-Z` or
757+
// required the `-Z unstable-options` flag, which were all intended
758+
// to be unstable. Unfortunately we didn't actually gate usage of
759+
// these options on the stable compiler, so we still allow them there
760+
// today. There are some warnings printed out about this in the
761+
// driver.
762+
UnstableButNotReally,
763+
764+
Unstable,
765+
}
770766

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

782+
#[allow(dead_code)] // currently we have no "truly unstable" options
786783
fn unstable(g: getopts::OptGroup) -> RustcOptGroup {
787784
RustcOptGroup { opt_group: g, stability: OptionStability::Unstable }
788785
}
786+
787+
fn unstable_bnr(g: getopts::OptGroup) -> RustcOptGroup {
788+
RustcOptGroup {
789+
opt_group: g,
790+
stability: OptionStability::UnstableButNotReally,
791+
}
792+
}
789793
}
790794

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

808812
fn stable(g: getopts::OptGroup) -> R { RustcOptGroup::stable(g) }
809813
fn unstable(g: getopts::OptGroup) -> R { RustcOptGroup::unstable(g) }
814+
fn unstable_bnr(g: getopts::OptGroup) -> R { RustcOptGroup::unstable_bnr(g) }
810815

811-
// FIXME (pnkfelix): We default to stable since the current set of
812-
// options is defacto stable. However, it would be good to revise the
813-
// code so that a stable option is the thing that takes extra effort
814-
// to encode.
815-
816-
pub fn opt(a: S, b: S, c: S, d: S) -> R { stable(getopts::optopt(a, b, c, d)) }
817-
pub fn multi(a: S, b: S, c: S, d: S) -> R { stable(getopts::optmulti(a, b, c, d)) }
818-
pub fn flag(a: S, b: S, c: S) -> R { stable(getopts::optflag(a, b, c)) }
819-
pub fn flagopt(a: S, b: S, c: S, d: S) -> R { stable(getopts::optflagopt(a, b, c, d)) }
820-
pub fn flagmulti(a: S, b: S, c: S) -> R { stable(getopts::optflagmulti(a, b, c)) }
816+
pub fn opt_s(a: S, b: S, c: S, d: S) -> R {
817+
stable(getopts::optopt(a, b, c, d))
818+
}
819+
pub fn multi_s(a: S, b: S, c: S, d: S) -> R {
820+
stable(getopts::optmulti(a, b, c, d))
821+
}
822+
pub fn flag_s(a: S, b: S, c: S) -> R {
823+
stable(getopts::optflag(a, b, c))
824+
}
825+
pub fn flagopt_s(a: S, b: S, c: S, d: S) -> R {
826+
stable(getopts::optflagopt(a, b, c, d))
827+
}
828+
pub fn flagmulti_s(a: S, b: S, c: S) -> R {
829+
stable(getopts::optflagmulti(a, b, c))
830+
}
821831

832+
pub fn opt(a: S, b: S, c: S, d: S) -> R {
833+
unstable(getopts::optopt(a, b, c, d))
834+
}
835+
pub fn multi(a: S, b: S, c: S, d: S) -> R {
836+
unstable(getopts::optmulti(a, b, c, d))
837+
}
838+
pub fn flag(a: S, b: S, c: S) -> R {
839+
unstable(getopts::optflag(a, b, c))
840+
}
841+
pub fn flagopt(a: S, b: S, c: S, d: S) -> R {
842+
unstable(getopts::optflagopt(a, b, c, d))
843+
}
844+
pub fn flagmulti(a: S, b: S, c: S) -> R {
845+
unstable(getopts::optflagmulti(a, b, c))
846+
}
822847

823-
pub fn opt_u(a: S, b: S, c: S, d: S) -> R { unstable(getopts::optopt(a, b, c, d)) }
824-
pub fn multi_u(a: S, b: S, c: S, d: S) -> R { unstable(getopts::optmulti(a, b, c, d)) }
825-
pub fn flag_u(a: S, b: S, c: S) -> R { unstable(getopts::optflag(a, b, c)) }
826-
pub fn flagopt_u(a: S, b: S, c: S, d: S) -> R { unstable(getopts::optflagopt(a, b, c, d)) }
827-
pub fn flagmulti_u(a: S, b: S, c: S) -> R { unstable(getopts::optflagmulti(a, b, c)) }
848+
// Do not use these functions for any new options added to the compiler, all
849+
// new options should use the `*_u` variants above to be truly unstable.
850+
pub fn opt_ubnr(a: S, b: S, c: S, d: S) -> R {
851+
unstable_bnr(getopts::optopt(a, b, c, d))
852+
}
853+
pub fn multi_ubnr(a: S, b: S, c: S, d: S) -> R {
854+
unstable_bnr(getopts::optmulti(a, b, c, d))
855+
}
856+
pub fn flag_ubnr(a: S, b: S, c: S) -> R {
857+
unstable_bnr(getopts::optflag(a, b, c))
858+
}
859+
pub fn flagopt_ubnr(a: S, b: S, c: S, d: S) -> R {
860+
unstable_bnr(getopts::optflagopt(a, b, c, d))
861+
}
862+
pub fn flagmulti_ubnr(a: S, b: S, c: S) -> R {
863+
unstable_bnr(getopts::optflagmulti(a, b, c))
864+
}
828865
}
829866

830867
/// Returns the "short" subset of the rustc command line options,
831868
/// including metadata for each option, such as whether the option is
832869
/// part of the stable long-term interface for rustc.
833870
pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
834871
vec![
835-
opt::flag("h", "help", "Display this message"),
836-
opt::multi("", "cfg", "Configure the compilation environment", "SPEC"),
837-
opt::multi("L", "", "Add a directory to the library search path",
872+
opt::flag_s("h", "help", "Display this message"),
873+
opt::multi_s("", "cfg", "Configure the compilation environment", "SPEC"),
874+
opt::multi_s("L", "", "Add a directory to the library search path",
838875
"[KIND=]PATH"),
839-
opt::multi("l", "", "Link the generated crate(s) to the specified native
876+
opt::multi_s("l", "", "Link the generated crate(s) to the specified native
840877
library NAME. The optional KIND can be one of,
841878
static, dylib, or framework. If omitted, dylib is
842879
assumed.", "[KIND=]NAME"),
843-
opt::multi("", "crate-type", "Comma separated list of types of crates
880+
opt::multi_s("", "crate-type", "Comma separated list of types of crates
844881
for the compiler to emit",
845882
"[bin|lib|rlib|dylib|staticlib]"),
846-
opt::opt("", "crate-name", "Specify the name of the crate being built",
883+
opt::opt_s("", "crate-name", "Specify the name of the crate being built",
847884
"NAME"),
848-
opt::multi("", "emit", "Comma separated list of types of output for \
885+
opt::multi_s("", "emit", "Comma separated list of types of output for \
849886
the compiler to emit",
850887
"[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
851-
opt::multi("", "print", "Comma separated list of compiler information to \
888+
opt::multi_s("", "print", "Comma separated list of compiler information to \
852889
print on stdout",
853890
"[crate-name|file-names|sysroot|target-list]"),
854-
opt::flagmulti("g", "", "Equivalent to -C debuginfo=2"),
855-
opt::flagmulti("O", "", "Equivalent to -C opt-level=2"),
856-
opt::opt("o", "", "Write output to <filename>", "FILENAME"),
857-
opt::opt("", "out-dir", "Write output to compiler-chosen filename \
891+
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
892+
opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
893+
opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
894+
opt::opt_s("", "out-dir", "Write output to compiler-chosen filename \
858895
in <dir>", "DIR"),
859-
opt::opt("", "explain", "Provide a detailed explanation of an error \
896+
opt::opt_s("", "explain", "Provide a detailed explanation of an error \
860897
message", "OPT"),
861-
opt::flag("", "test", "Build a test harness"),
862-
opt::opt("", "target", "Target triple for which the code is compiled", "TARGET"),
863-
opt::multi("W", "warn", "Set lint warnings", "OPT"),
864-
opt::multi("A", "allow", "Set lint allowed", "OPT"),
865-
opt::multi("D", "deny", "Set lint denied", "OPT"),
866-
opt::multi("F", "forbid", "Set lint forbidden", "OPT"),
867-
opt::multi("", "cap-lints", "Set the most restrictive lint level. \
898+
opt::flag_s("", "test", "Build a test harness"),
899+
opt::opt_s("", "target", "Target triple for which the code is compiled", "TARGET"),
900+
opt::multi_s("W", "warn", "Set lint warnings", "OPT"),
901+
opt::multi_s("A", "allow", "Set lint allowed", "OPT"),
902+
opt::multi_s("D", "deny", "Set lint denied", "OPT"),
903+
opt::multi_s("F", "forbid", "Set lint forbidden", "OPT"),
904+
opt::multi_s("", "cap-lints", "Set the most restrictive lint level. \
868905
More restrictive lints are capped at this \
869906
level", "LEVEL"),
870-
opt::multi("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
871-
opt::flag("V", "version", "Print version info and exit"),
872-
opt::flag("v", "verbose", "Use verbose output"),
907+
opt::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
908+
opt::flag_s("V", "version", "Print version info and exit"),
909+
opt::flag_s("v", "verbose", "Use verbose output"),
873910
]
874911
}
875912

@@ -879,31 +916,41 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
879916
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
880917
let mut opts = rustc_short_optgroups();
881918
opts.extend_from_slice(&[
882-
opt::multi("", "extern", "Specify where an external rust library is \
919+
opt::multi_s("", "extern", "Specify where an external rust library is \
883920
located",
884921
"NAME=PATH"),
885-
opt::opt("", "sysroot", "Override the system root", "PATH"),
886-
opt::multi("Z", "", "Set internal debugging options", "FLAG"),
887-
opt::opt_u("", "error-format", "How errors and other messages are produced", "human|json"),
888-
opt::opt("", "color", "Configure coloring of output:
922+
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
923+
opt::multi_ubnr("Z", "", "Set internal debugging options", "FLAG"),
924+
opt::opt_ubnr("", "error-format",
925+
"How errors and other messages are produced",
926+
"human|json"),
927+
opt::opt_s("", "color", "Configure coloring of output:
889928
auto = colorize, if output goes to a tty (default);
890929
always = always colorize output;
891930
never = never colorize output", "auto|always|never"),
892931

893-
opt::flagopt_u("", "pretty",
932+
opt::flagopt_ubnr("", "pretty",
894933
"Pretty-print the input instead of compiling;
895934
valid types are: `normal` (un-annotated source),
896935
`expanded` (crates expanded), or
897936
`expanded,identified` (fully parenthesized, AST nodes with IDs).",
898937
"TYPE"),
899-
opt::flagopt_u("", "unpretty",
938+
opt::flagopt_ubnr("", "unpretty",
900939
"Present the input source, unstable (and less-pretty) variants;
901940
valid types are any of the types for `--pretty`, as well as:
902941
`flowgraph=<nodeid>` (graphviz formatted flowgraph for node),
903942
`everybody_loops` (all function bodies replaced with `loop {}`),
904943
`hir` (the HIR), `hir,identified`, or
905944
`hir,typed` (HIR with types for each node).",
906945
"TYPE"),
946+
947+
// new options here should **not** use the `_ubnr` functions, all new
948+
// unstable options should use the short variants to indicate that they
949+
// are truly unstable. All `_ubnr` flags are just that way because they
950+
// were so historically.
951+
//
952+
// You may also wish to keep this comment at the bottom of this list to
953+
// ensure that others see it.
907954
]);
908955
opts
909956
}
@@ -1242,15 +1289,21 @@ impl fmt::Display for CrateType {
12421289
#[cfg(test)]
12431290
mod tests {
12441291
use middle::cstore::DummyCrateStore;
1245-
use session::config::{build_configuration, optgroups, build_session_options};
1292+
use session::config::{build_configuration, build_session_options};
12461293
use session::build_session;
12471294

12481295
use std::rc::Rc;
1249-
use getopts::getopts;
1296+
use getopts::{getopts, OptGroup};
12501297
use syntax::attr;
12511298
use syntax::attr::AttrMetaMethods;
12521299
use syntax::diagnostics;
12531300

1301+
fn optgroups() -> Vec<OptGroup> {
1302+
super::rustc_optgroups().into_iter()
1303+
.map(|a| a.opt_group)
1304+
.collect()
1305+
}
1306+
12541307
// When the user supplies --test we should implicitly supply --cfg test
12551308
#[test]
12561309
fn test_switch_implies_cfg_test() {

0 commit comments

Comments
 (0)