X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc%2Fsession%2Fconfig.rs;h=4a14960aa69bd8f340083adeb07ee77e5b7a8af0;hb=dd6df0d20ed94b46125e7b2039205674f01c95b9;hp=33b9ddaa622303f2c553810f0f686e29699a28ca;hpb=b2b35797d0a8978ac8f20b44b0bba83e1e5deaa9;p=rust.git diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 33b9ddaa622..4a14960aa69 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1,10 +1,13 @@ //! Contains infrastructure for configuring the compiler, including parsing //! command-line options. +// ignore-tidy-filelength + use crate::lint; use crate::middle::cstore; use crate::session::{early_error, early_warn, Session}; use crate::session::search_paths::SearchPath; +use crate::hir::map as hir_map; use rustc_data_structures::fx::FxHashSet; @@ -440,6 +443,8 @@ pub struct Options { // `true` if we're emitting JSON blobs about each artifact produced // by the compiler. json_artifact_notifications: bool [TRACKED], + + pretty: Option<(PpMode, Option)> [UNTRACKED], } ); @@ -621,6 +626,7 @@ fn default() -> Options { remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, json_artifact_notifications: false, + pretty: None, } } } @@ -1469,7 +1475,7 @@ fn parse_symbol_mangling_version( (such as entering an empty infinite loop) by inserting llvm.sideeffect"), } -pub fn default_lib_output() -> CrateType { +pub const fn default_lib_output() -> CrateType { CrateType::Rlib } @@ -1800,7 +1806,7 @@ pub fn rustc_optgroups() -> Vec { "", "extern", "Specify where an external rust library is located", - "NAME=PATH", + "NAME[=PATH]", ), opt::multi_s( "", @@ -2164,7 +2170,6 @@ fn collect_print_requests( cg: &mut CodegenOptions, dopts: &mut DebuggingOptions, matches: &getopts::Matches, - is_unstable_enabled: bool, error_format: ErrorOutputType, ) -> Vec { let mut prints = Vec::::new(); @@ -2206,7 +2211,7 @@ fn collect_print_requests( "tls-models" => PrintRequest::TlsModels, "native-static-libs" => PrintRequest::NativeStaticLibs, "target-spec-json" => { - if is_unstable_enabled { + if dopts.unstable_options { PrintRequest::TargetSpec } else { early_error( @@ -2370,7 +2375,6 @@ fn parse_externs( matches: &getopts::Matches, debugging_opts: &DebuggingOptions, error_format: ErrorOutputType, - is_unstable_enabled: bool, ) -> Externs { if matches.opt_present("extern-private") && !debugging_opts.unstable_options { early_error( @@ -2392,13 +2396,6 @@ fn parse_externs( let name = parts.next().unwrap_or_else(|| early_error(error_format, "--extern value must not be empty")); let location = parts.next().map(|s| s.to_string()); - if location.is_none() && !is_unstable_enabled { - early_error( - error_format, - "the `-Z unstable-options` flag must also be passed to \ - enable `--extern crate_name` without `=path`", - ); - }; let entry = externs .entry(name.to_owned()) @@ -2483,12 +2480,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { ); } - let is_unstable_enabled = nightly_options::is_unstable_enabled(matches); let prints = collect_print_requests( &mut cg, &mut debugging_opts, matches, - is_unstable_enabled, error_format, ); @@ -2521,12 +2516,14 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { ); } - let externs = parse_externs(matches, &debugging_opts, error_format, is_unstable_enabled); + let externs = parse_externs(matches, &debugging_opts, error_format); let crate_name = matches.opt_str("crate-name"); let remap_path_prefix = parse_remap_path_prefix(matches, error_format); + let pretty = parse_pretty(matches, &debugging_opts, error_format); + Options { crate_types, optimize: opt_level, @@ -2557,6 +2554,73 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { remap_path_prefix, edition, json_artifact_notifications, + pretty, + } +} + +fn parse_pretty( + matches: &getopts::Matches, + debugging_opts: &DebuggingOptions, + efmt: ErrorOutputType, +) -> Option<(PpMode, Option)> { + let pretty = if debugging_opts.unstable_options { + matches.opt_default("pretty", "normal").map(|a| { + // stable pretty-print variants only + parse_pretty_inner(efmt, &a, false) + }) + } else { + None + }; + + return if pretty.is_none() { + debugging_opts.unpretty.as_ref().map(|a| { + // extended with unstable pretty-print variants + parse_pretty_inner(efmt, &a, true) + }) + } else { + pretty + }; + + fn parse_pretty_inner( + efmt: ErrorOutputType, + name: &str, + extended: bool, + ) -> (PpMode, Option) { + use PpMode::*; + use PpSourceMode::*; + let mut split = name.splitn(2, '='); + let first = split.next().unwrap(); + let opt_second = split.next(); + let first = match (first, extended) { + ("normal", _) => PpmSource(PpmNormal), + ("identified", _) => PpmSource(PpmIdentified), + ("everybody_loops", true) => PpmSource(PpmEveryBodyLoops), + ("expanded", _) => PpmSource(PpmExpanded), + ("expanded,identified", _) => PpmSource(PpmExpandedIdentified), + ("expanded,hygiene", _) => PpmSource(PpmExpandedHygiene), + ("hir", true) => PpmHir(PpmNormal), + ("hir,identified", true) => PpmHir(PpmIdentified), + ("hir,typed", true) => PpmHir(PpmTyped), + ("hir-tree", true) => PpmHirTree(PpmNormal), + ("mir", true) => PpmMir, + ("mir-cfg", true) => PpmMirCFG, + _ => { + if extended { + early_error(efmt, &format!("argument to `unpretty` must be one of `normal`, \ + `expanded`, `identified`, `expanded,identified`, \ + `expanded,hygiene`, `everybody_loops`, \ + `hir`, `hir,identified`, `hir,typed`, `hir-tree`, \ + `mir` or `mir-cfg`; got {}", + name)); + } else { + early_error(efmt, &format!("argument to `pretty` must be one of `normal`, \ + `expanded`, `identified`, or `expanded,identified`; got {}", + name)); + } + } + }; + let opt_second = opt_second.and_then(|s| s.parse::().ok()); + (first, opt_second) } } @@ -2667,6 +2731,151 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum PpSourceMode { + PpmNormal, + PpmEveryBodyLoops, + PpmExpanded, + PpmIdentified, + PpmExpandedIdentified, + PpmExpandedHygiene, + PpmTyped, +} + +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum PpMode { + PpmSource(PpSourceMode), + PpmHir(PpSourceMode), + PpmHirTree(PpSourceMode), + PpmMir, + PpmMirCFG, +} + +impl PpMode { + pub fn needs_ast_map(&self, opt_uii: &Option) -> bool { + use PpMode::*; + use PpSourceMode::*; + match *self { + PpmSource(PpmNormal) | + PpmSource(PpmEveryBodyLoops) | + PpmSource(PpmIdentified) => opt_uii.is_some(), + + PpmSource(PpmExpanded) | + PpmSource(PpmExpandedIdentified) | + PpmSource(PpmExpandedHygiene) | + PpmHir(_) | + PpmHirTree(_) | + PpmMir | + PpmMirCFG => true, + PpmSource(PpmTyped) => panic!("invalid state"), + } + } + + pub fn needs_analysis(&self) -> bool { + use PpMode::*; + match *self { + PpmMir | PpmMirCFG => true, + _ => false, + } + } +} + +#[derive(Clone, Debug)] +pub enum UserIdentifiedItem { + ItemViaNode(ast::NodeId), + ItemViaPath(Vec), +} + +impl FromStr for UserIdentifiedItem { + type Err = (); + fn from_str(s: &str) -> Result { + use UserIdentifiedItem::*; + Ok(s.parse() + .map(ast::NodeId::from_u32) + .map(ItemViaNode) + .unwrap_or_else(|_| ItemViaPath(s.split("::").map(|s| s.to_string()).collect()))) + } +} + +pub enum NodesMatchingUII<'a> { + NodesMatchingDirect(std::option::IntoIter), + NodesMatchingSuffix(Box + 'a>), +} + +impl<'a> Iterator for NodesMatchingUII<'a> { + type Item = ast::NodeId; + + fn next(&mut self) -> Option { + use NodesMatchingUII::*; + match self { + &mut NodesMatchingDirect(ref mut iter) => iter.next(), + &mut NodesMatchingSuffix(ref mut iter) => iter.next(), + } + } + + fn size_hint(&self) -> (usize, Option) { + use NodesMatchingUII::*; + match self { + &NodesMatchingDirect(ref iter) => iter.size_hint(), + &NodesMatchingSuffix(ref iter) => iter.size_hint(), + } + } +} + +impl UserIdentifiedItem { + pub fn reconstructed_input(&self) -> String { + use UserIdentifiedItem::*; + match *self { + ItemViaNode(node_id) => node_id.to_string(), + ItemViaPath(ref parts) => parts.join("::"), + } + } + + pub fn all_matching_node_ids<'a, 'hir>(&'a self, + map: &'a hir_map::Map<'hir>) + -> NodesMatchingUII<'a> { + use UserIdentifiedItem::*; + use NodesMatchingUII::*; + match *self { + ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()), + ItemViaPath(ref parts) => { + NodesMatchingSuffix(Box::new(map.nodes_matching_suffix(&parts))) + } + } + } + + pub fn to_one_node_id(self, + user_option: &str, + sess: &Session, + map: &hir_map::Map<'_>) + -> ast::NodeId { + let fail_because = |is_wrong_because| -> ast::NodeId { + let message = format!("{} needs NodeId (int) or unique path suffix (b::c::d); got \ + {}, which {}", + user_option, + self.reconstructed_input(), + is_wrong_because); + sess.fatal(&message) + }; + + let mut saw_node = ast::DUMMY_NODE_ID; + let mut seen = 0; + for node in self.all_matching_node_ids(map) { + saw_node = node; + seen += 1; + if seen > 1 { + fail_because("does not resolve uniquely"); + } + } + if seen == 0 { + fail_because("does not resolve to any item"); + } + + assert!(seen == 1); + return saw_node; + } +} + /// Command-line arguments passed to the compiler have to be incorporated with /// the dependency tracking system for incremental compilation. This module /// provides some utilities to make this more convenient.