diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index fc1c5e187ecc7..d14db8e2ff1ce 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -369,6 +369,7 @@ pub enum PrintRequest { CodeModels, TargetSpec, NativeStaticLibs, + UnstableFeatures, } pub enum Input { @@ -1306,6 +1307,17 @@ mod opt { /// 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 { + // FIXME: unfortunately, we need to hardcode these nightly vs. stable + // option value listings separately (rather than, say, plumbing in the + // extra nightly values with `format!`) because the `opt` interface + // requires a static lifetime + let stable_print_options = "[crate-name|file-names|sysroot|cfg|target-list|\ + target-cpus|target-features|relocation-models|\ + code-models|native-static-libs]"; + let nightly_print_options = "[crate-name|file-names|sysroot|cfg|target-list|\ + target-cpus|target-features|relocation-models|\ + code-models|native-static-libs|target-spec-json|\ + unstable-features]"; vec![ opt::flag_s("h", "help", "Display this message"), opt::multi_s("", "cfg", "Configure the compilation environment", "SPEC"), @@ -1325,10 +1337,12 @@ pub fn rustc_short_optgroups() -> Vec { the compiler to emit", "[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]"), opt::multi_s("", "print", "Comma separated list of compiler information to \ - print on stdout", - "[crate-name|file-names|sysroot|cfg|target-list|\ - target-cpus|target-features|relocation-models|\ - code-models|target-spec-json|native-static-libs]"), + print on stdout", + if nightly_options::is_nightly_build() { + nightly_print_options + } else { + stable_print_options + }), 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"), @@ -1679,6 +1693,15 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) enable the target-spec-json print option")); } }, + "unstable-features" => { + if nightly_options::is_nightly_build() { + PrintRequest::UnstableFeatures + } else { + early_error(error_format, + &format!("unstable features require a nightly \ + build of the compiler")); + } + }, req => { early_error(error_format, &format!("unknown print request `{}`", req)) } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index cd21060aff652..f461fb1a19d50 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -96,7 +96,7 @@ use std::thread; use syntax::ast; use syntax::codemap::{CodeMap, FileLoader, RealFileLoader}; -use syntax::feature_gate::{GatedCfg, UnstableFeatures}; +use syntax::feature_gate::{ACTIVE_FEATURES, GatedCfg, UnstableFeatures}; use syntax::parse::{self, PResult}; use syntax_pos::{DUMMY_SP, MultiSpan}; @@ -801,6 +801,38 @@ impl RustcDefaultCalls { PrintRequest::NativeStaticLibs => { println!("Native static libs can be printed only during linking"); } + PrintRequest::UnstableFeatures => { + let (feat_width, ver_width, iss_width) = ACTIVE_FEATURES.iter() + .map(|&(feat, ver, iss_maybe, _)| { + (feat.len(), + ver.len(), + iss_maybe.map(|no| no.to_string().len()).unwrap_or(1)) + }) + .fold((7, 7, 5), // lengths of col. headings: "feature", "version", "issue" + |max_widths, feat_widths| { + (max(max_widths.0, feat_widths.0), + max(max_widths.1, feat_widths.1), + max(max_widths.2, feat_widths.2)) + }); + println!("| {0:feat_width$} | {1:ver_width$} | {2:iss_width$} |", + "feature", "version", "issue", + feat_width = feat_width, + ver_width = ver_width, + iss_width = iss_width); + println!("{:->total_width$}", "", + // `+ 10` is for ` | ` column borders: 2 + 3 + 3 + 2 + total_width = feat_width + ver_width + iss_width + 10); + let mut features = ACTIVE_FEATURES.to_vec(); + features.sort_by_key(|&f| f.0); + for &(feature, version, issue_maybe, _) in &features { + println!("| {0:feat_width$} | {1:>ver_width$} | {2:>iss_width$} |", + feature, version, + issue_maybe.map(|no| no.to_string()).unwrap_or("—".to_owned()), + feat_width = feat_width, + ver_width = ver_width, + iss_width = iss_width); + } + } } } return Compilation::Stop; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a2f29181a20d3..e4a0f2dec3d05 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -58,7 +58,7 @@ macro_rules! declare_features { ($((active, $feature: ident, $ver: expr, $issue: expr),)+) => { /// Represents active features that are currently being implemented or /// currently being considered for addition/removal. - const ACTIVE_FEATURES: + pub const ACTIVE_FEATURES: &'static [(&'static str, &'static str, Option, fn(&mut Features, Span))] = &[$((stringify!($feature), $ver, $issue, set!($feature))),+]; @@ -84,21 +84,21 @@ macro_rules! declare_features { ($((removed, $feature: ident, $ver: expr, $issue: expr),)+) => { /// Represents unstable features which have since been removed (it was once Active) - const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option)] = &[ + pub const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option)] = &[ $((stringify!($feature), $ver, $issue)),+ ]; }; ($((stable_removed, $feature: ident, $ver: expr, $issue: expr),)+) => { /// Represents stable features which have since been removed (it was once Accepted) - const STABLE_REMOVED_FEATURES: &'static [(&'static str, &'static str, Option)] = &[ + pub const STABLE_REMOVED_FEATURES: &'static [(&'static str, &'static str, Option)] = &[ $((stringify!($feature), $ver, $issue)),+ ]; }; ($((accepted, $feature: ident, $ver: expr, $issue: expr),)+) => { /// Those language feature has since been Accepted (it was once Active) - const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option)] = &[ + pub const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option)] = &[ $((stringify!($feature), $ver, $issue)),+ ]; } diff --git a/src/test/ui/print/unstable-features.rs b/src/test/ui/print/unstable-features.rs new file mode 100644 index 0000000000000..6571fcffc9baa --- /dev/null +++ b/src/test/ui/print/unstable-features.rs @@ -0,0 +1,13 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --print unstable-features + +fn main() {} diff --git a/src/test/ui/print/unstable-features.stdout b/src/test/ui/print/unstable-features.stdout new file mode 100644 index 0000000000000..59b563aebe965 --- /dev/null +++ b/src/test/ui/print/unstable-features.stdout @@ -0,0 +1,108 @@ +| feature | version | issue | +----------------------------------------------------- +| abi_msp430_interrupt | 1.16.0 | 38487 | +| abi_ptx | 1.15.0 | — | +| abi_sysv64 | 1.13.0 | 36167 | +| abi_thiscall | 1.19.0 | — | +| abi_unadjusted | 1.16.0 | — | +| abi_vectorcall | 1.7.0 | — | +| abi_x86_interrupt | 1.17.0 | 40180 | +| advanced_slice_patterns | 1.0.0 | 23121 | +| allocator_internals | 1.20.0 | — | +| allow_fail | 1.19.0 | 42219 | +| allow_internal_unsafe | 1.0.0 | — | +| allow_internal_unstable | 1.0.0 | — | +| asm | 1.0.0 | 29722 | +| associated_type_defaults | 1.2.0 | 29661 | +| attr_literals | 1.13.0 | 34981 | +| box_patterns | 1.0.0 | 29641 | +| box_syntax | 1.0.0 | 27779 | +| catch_expr | 1.17.0 | 31436 | +| cfg_target_feature | 1.4.0 | 29717 | +| cfg_target_has_atomic | 1.9.0 | 32976 | +| cfg_target_thread_local | 1.7.0 | 29594 | +| cfg_target_vendor | 1.5.0 | 29718 | +| clone_closures | 1.22.0 | 44490 | +| compiler_builtins | 1.13.0 | — | +| concat_idents | 1.0.0 | 29599 | +| conservative_impl_trait | 1.12.0 | 34511 | +| const_fn | 1.2.0 | 24111 | +| const_indexing | 1.4.0 | 29947 | +| copy_closures | 1.22.0 | 44490 | +| custom_attribute | 1.0.0 | 29642 | +| custom_derive | 1.0.0 | 29644 | +| decl_macro | 1.17.0 | 39412 | +| default_type_parameter_fallback | 1.3.0 | 27336 | +| doc_cfg | 1.21.0 | 43781 | +| doc_masked | 1.21.0 | 44027 | +| dotdoteq_in_patterns | 1.22.0 | 28237 | +| dropck_eyepatch | 1.10.0 | 34761 | +| dropck_parametricity | 1.3.0 | 28498 | +| exclusive_range_pattern | 1.11.0 | 37854 | +| fn_must_use | 1.21.0 | 43302 | +| fundamental | 1.0.0 | 29635 | +| generators | 1.21.0 | — | +| generic_param_attrs | 1.11.0 | 34761 | +| global_allocator | 1.20.0 | — | +| global_asm | 1.18.0 | 35119 | +| i128_type | 1.16.0 | 35118 | +| inclusive_range_syntax | 1.7.0 | 28237 | +| intrinsics | 1.0.0 | — | +| lang_items | 1.0.0 | — | +| link_args | 1.0.0 | 29596 | +| link_cfg | 1.14.0 | 37406 | +| link_llvm_intrinsics | 1.0.0 | 29602 | +| linkage | 1.0.0 | 29603 | +| log_syntax | 1.0.0 | 29598 | +| macro_reexport | 1.0.0 | 29638 | +| macro_vis_matcher | 1.18.0 | 41022 | +| main | 1.0.0 | 29634 | +| match_beginning_vert | 1.21.0 | 44101 | +| match_default_bindings | 1.22.0 | 42640 | +| naked_functions | 1.9.0 | 32408 | +| needs_allocator | 1.4.0 | 27389 | +| needs_panic_runtime | 1.10.0 | 32837 | +| never_type | 1.13.0 | 35121 | +| no_core | 1.3.0 | 29639 | +| no_debug | 1.5.0 | 29721 | +| non_ascii_idents | 1.0.0 | 28979 | +| omit_gdb_pretty_printer_section | 1.5.0 | — | +| on_unimplemented | 1.0.0 | 29628 | +| optin_builtin_traits | 1.0.0 | 13231 | +| overlapping_marker_traits | 1.18.0 | 29864 | +| panic_runtime | 1.10.0 | 32837 | +| placement_in_syntax | 1.0.0 | 27779 | +| platform_intrinsics | 1.4.0 | 27731 | +| plugin | 1.0.0 | 29597 | +| plugin_registrar | 1.0.0 | 29597 | +| prelude_import | 1.2.0 | — | +| proc_macro | 1.16.0 | 38356 | +| profiler_runtime | 1.18.0 | — | +| quote | 1.0.0 | 29601 | +| repr128 | 1.16.0 | 35118 | +| repr_align | 1.17.0 | 33626 | +| repr_simd | 1.4.0 | 27731 | +| rustc_attrs | 1.0.0 | 29642 | +| rustc_const_unstable | 1.0.0 | — | +| rustc_diagnostic_macros | 1.0.0 | — | +| sanitizer_runtime | 1.17.0 | — | +| simd | 1.0.0 | 27731 | +| simd_ffi | 1.0.0 | 27731 | +| slice_patterns | 1.0.0 | 23121 | +| specialization | 1.7.0 | 31844 | +| staged_api | 1.0.0 | — | +| start | 1.0.0 | 29633 | +| static_nobundle | 1.16.0 | 37403 | +| stmt_expr_attributes | 1.6.0 | 15701 | +| structural_match | 1.8.0 | 31434 | +| target_feature | 1.15.0 | — | +| thread_local | 1.0.0 | 29594 | +| trace_macros | 1.0.0 | 29598 | +| type_ascription | 1.6.0 | 23416 | +| unboxed_closures | 1.0.0 | 29625 | +| underscore_lifetimes | 1.22.0 | 44524 | +| unsized_tuple_coercion | 1.20.0 | 42877 | +| untagged_unions | 1.13.0 | 32836 | +| unwind_attributes | 1.4.0 | — | +| use_extern_macros | 1.15.0 | 35896 | +| used | 1.18.0 | 40289 |