Skip to content

Commit dd6df0d

Browse files
Move pretty parsing into Session options
This allows us to query whether PpmEveryBodyLoops is set during expansion and run the everybody loops pass.
1 parent 516a817 commit dd6df0d

File tree

5 files changed

+300
-280
lines changed

5 files changed

+300
-280
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3506,6 +3506,7 @@ dependencies = [
35063506
"rustc_mir",
35073507
"rustc_plugin",
35083508
"rustc_plugin_impl",
3509+
"rustc_resolve",
35093510
"rustc_save_analysis",
35103511
"rustc_target",
35113512
"serialize",

src/librustc/session/config.rs

+220
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
//! Contains infrastructure for configuring the compiler, including parsing
22
//! command-line options.
33
4+
// ignore-tidy-filelength
5+
46
use crate::lint;
57
use crate::middle::cstore;
68
use crate::session::{early_error, early_warn, Session};
79
use crate::session::search_paths::SearchPath;
10+
use crate::hir::map as hir_map;
811

912
use rustc_data_structures::fx::FxHashSet;
1013

@@ -440,6 +443,8 @@ top_level_options!(
440443
// `true` if we're emitting JSON blobs about each artifact produced
441444
// by the compiler.
442445
json_artifact_notifications: bool [TRACKED],
446+
447+
pretty: Option<(PpMode, Option<UserIdentifiedItem>)> [UNTRACKED],
443448
}
444449
);
445450

@@ -621,6 +626,7 @@ impl Default for Options {
621626
remap_path_prefix: Vec::new(),
622627
edition: DEFAULT_EDITION,
623628
json_artifact_notifications: false,
629+
pretty: None,
624630
}
625631
}
626632
}
@@ -2516,6 +2522,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
25162522

25172523
let remap_path_prefix = parse_remap_path_prefix(matches, error_format);
25182524

2525+
let pretty = parse_pretty(matches, &debugging_opts, error_format);
2526+
25192527
Options {
25202528
crate_types,
25212529
optimize: opt_level,
@@ -2546,6 +2554,73 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
25462554
remap_path_prefix,
25472555
edition,
25482556
json_artifact_notifications,
2557+
pretty,
2558+
}
2559+
}
2560+
2561+
fn parse_pretty(
2562+
matches: &getopts::Matches,
2563+
debugging_opts: &DebuggingOptions,
2564+
efmt: ErrorOutputType,
2565+
) -> Option<(PpMode, Option<UserIdentifiedItem>)> {
2566+
let pretty = if debugging_opts.unstable_options {
2567+
matches.opt_default("pretty", "normal").map(|a| {
2568+
// stable pretty-print variants only
2569+
parse_pretty_inner(efmt, &a, false)
2570+
})
2571+
} else {
2572+
None
2573+
};
2574+
2575+
return if pretty.is_none() {
2576+
debugging_opts.unpretty.as_ref().map(|a| {
2577+
// extended with unstable pretty-print variants
2578+
parse_pretty_inner(efmt, &a, true)
2579+
})
2580+
} else {
2581+
pretty
2582+
};
2583+
2584+
fn parse_pretty_inner(
2585+
efmt: ErrorOutputType,
2586+
name: &str,
2587+
extended: bool,
2588+
) -> (PpMode, Option<UserIdentifiedItem>) {
2589+
use PpMode::*;
2590+
use PpSourceMode::*;
2591+
let mut split = name.splitn(2, '=');
2592+
let first = split.next().unwrap();
2593+
let opt_second = split.next();
2594+
let first = match (first, extended) {
2595+
("normal", _) => PpmSource(PpmNormal),
2596+
("identified", _) => PpmSource(PpmIdentified),
2597+
("everybody_loops", true) => PpmSource(PpmEveryBodyLoops),
2598+
("expanded", _) => PpmSource(PpmExpanded),
2599+
("expanded,identified", _) => PpmSource(PpmExpandedIdentified),
2600+
("expanded,hygiene", _) => PpmSource(PpmExpandedHygiene),
2601+
("hir", true) => PpmHir(PpmNormal),
2602+
("hir,identified", true) => PpmHir(PpmIdentified),
2603+
("hir,typed", true) => PpmHir(PpmTyped),
2604+
("hir-tree", true) => PpmHirTree(PpmNormal),
2605+
("mir", true) => PpmMir,
2606+
("mir-cfg", true) => PpmMirCFG,
2607+
_ => {
2608+
if extended {
2609+
early_error(efmt, &format!("argument to `unpretty` must be one of `normal`, \
2610+
`expanded`, `identified`, `expanded,identified`, \
2611+
`expanded,hygiene`, `everybody_loops`, \
2612+
`hir`, `hir,identified`, `hir,typed`, `hir-tree`, \
2613+
`mir` or `mir-cfg`; got {}",
2614+
name));
2615+
} else {
2616+
early_error(efmt, &format!("argument to `pretty` must be one of `normal`, \
2617+
`expanded`, `identified`, or `expanded,identified`; got {}",
2618+
name));
2619+
}
2620+
}
2621+
};
2622+
let opt_second = opt_second.and_then(|s| s.parse::<UserIdentifiedItem>().ok());
2623+
(first, opt_second)
25492624
}
25502625
}
25512626

@@ -2656,6 +2731,151 @@ impl fmt::Display for CrateType {
26562731
}
26572732
}
26582733

2734+
#[derive(Copy, Clone, PartialEq, Debug)]
2735+
pub enum PpSourceMode {
2736+
PpmNormal,
2737+
PpmEveryBodyLoops,
2738+
PpmExpanded,
2739+
PpmIdentified,
2740+
PpmExpandedIdentified,
2741+
PpmExpandedHygiene,
2742+
PpmTyped,
2743+
}
2744+
2745+
#[derive(Copy, Clone, PartialEq, Debug)]
2746+
pub enum PpMode {
2747+
PpmSource(PpSourceMode),
2748+
PpmHir(PpSourceMode),
2749+
PpmHirTree(PpSourceMode),
2750+
PpmMir,
2751+
PpmMirCFG,
2752+
}
2753+
2754+
impl PpMode {
2755+
pub fn needs_ast_map(&self, opt_uii: &Option<UserIdentifiedItem>) -> bool {
2756+
use PpMode::*;
2757+
use PpSourceMode::*;
2758+
match *self {
2759+
PpmSource(PpmNormal) |
2760+
PpmSource(PpmEveryBodyLoops) |
2761+
PpmSource(PpmIdentified) => opt_uii.is_some(),
2762+
2763+
PpmSource(PpmExpanded) |
2764+
PpmSource(PpmExpandedIdentified) |
2765+
PpmSource(PpmExpandedHygiene) |
2766+
PpmHir(_) |
2767+
PpmHirTree(_) |
2768+
PpmMir |
2769+
PpmMirCFG => true,
2770+
PpmSource(PpmTyped) => panic!("invalid state"),
2771+
}
2772+
}
2773+
2774+
pub fn needs_analysis(&self) -> bool {
2775+
use PpMode::*;
2776+
match *self {
2777+
PpmMir | PpmMirCFG => true,
2778+
_ => false,
2779+
}
2780+
}
2781+
}
2782+
2783+
#[derive(Clone, Debug)]
2784+
pub enum UserIdentifiedItem {
2785+
ItemViaNode(ast::NodeId),
2786+
ItemViaPath(Vec<String>),
2787+
}
2788+
2789+
impl FromStr for UserIdentifiedItem {
2790+
type Err = ();
2791+
fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
2792+
use UserIdentifiedItem::*;
2793+
Ok(s.parse()
2794+
.map(ast::NodeId::from_u32)
2795+
.map(ItemViaNode)
2796+
.unwrap_or_else(|_| ItemViaPath(s.split("::").map(|s| s.to_string()).collect())))
2797+
}
2798+
}
2799+
2800+
pub enum NodesMatchingUII<'a> {
2801+
NodesMatchingDirect(std::option::IntoIter<ast::NodeId>),
2802+
NodesMatchingSuffix(Box<dyn Iterator<Item = ast::NodeId> + 'a>),
2803+
}
2804+
2805+
impl<'a> Iterator for NodesMatchingUII<'a> {
2806+
type Item = ast::NodeId;
2807+
2808+
fn next(&mut self) -> Option<ast::NodeId> {
2809+
use NodesMatchingUII::*;
2810+
match self {
2811+
&mut NodesMatchingDirect(ref mut iter) => iter.next(),
2812+
&mut NodesMatchingSuffix(ref mut iter) => iter.next(),
2813+
}
2814+
}
2815+
2816+
fn size_hint(&self) -> (usize, Option<usize>) {
2817+
use NodesMatchingUII::*;
2818+
match self {
2819+
&NodesMatchingDirect(ref iter) => iter.size_hint(),
2820+
&NodesMatchingSuffix(ref iter) => iter.size_hint(),
2821+
}
2822+
}
2823+
}
2824+
2825+
impl UserIdentifiedItem {
2826+
pub fn reconstructed_input(&self) -> String {
2827+
use UserIdentifiedItem::*;
2828+
match *self {
2829+
ItemViaNode(node_id) => node_id.to_string(),
2830+
ItemViaPath(ref parts) => parts.join("::"),
2831+
}
2832+
}
2833+
2834+
pub fn all_matching_node_ids<'a, 'hir>(&'a self,
2835+
map: &'a hir_map::Map<'hir>)
2836+
-> NodesMatchingUII<'a> {
2837+
use UserIdentifiedItem::*;
2838+
use NodesMatchingUII::*;
2839+
match *self {
2840+
ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()),
2841+
ItemViaPath(ref parts) => {
2842+
NodesMatchingSuffix(Box::new(map.nodes_matching_suffix(&parts)))
2843+
}
2844+
}
2845+
}
2846+
2847+
pub fn to_one_node_id(self,
2848+
user_option: &str,
2849+
sess: &Session,
2850+
map: &hir_map::Map<'_>)
2851+
-> ast::NodeId {
2852+
let fail_because = |is_wrong_because| -> ast::NodeId {
2853+
let message = format!("{} needs NodeId (int) or unique path suffix (b::c::d); got \
2854+
{}, which {}",
2855+
user_option,
2856+
self.reconstructed_input(),
2857+
is_wrong_because);
2858+
sess.fatal(&message)
2859+
};
2860+
2861+
let mut saw_node = ast::DUMMY_NODE_ID;
2862+
let mut seen = 0;
2863+
for node in self.all_matching_node_ids(map) {
2864+
saw_node = node;
2865+
seen += 1;
2866+
if seen > 1 {
2867+
fail_because("does not resolve uniquely");
2868+
}
2869+
}
2870+
if seen == 0 {
2871+
fail_because("does not resolve to any item");
2872+
}
2873+
2874+
assert!(seen == 1);
2875+
return saw_node;
2876+
}
2877+
}
2878+
26592879
/// Command-line arguments passed to the compiler have to be incorporated with
26602880
/// the dependency tracking system for incremental compilation. This module
26612881
/// provides some utilities to make this more convenient.

src/librustc_driver/lib.rs

+3-29
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ extern crate lazy_static;
2525

2626
pub extern crate rustc_plugin_impl as plugin;
2727

28-
use pretty::{PpMode, UserIdentifiedItem};
29-
3028
//use rustc_resolve as resolve;
3129
use rustc_save_analysis as save;
3230
use rustc_save_analysis::DumpHandler;
@@ -285,19 +283,17 @@ pub fn run_compiler(
285283
return sess.compile_status();
286284
}
287285

288-
let pretty_info = parse_pretty(sess, &matches);
289-
290286
compiler.parse()?;
291287

292-
if let Some((ppm, opt_uii)) = pretty_info {
288+
if let Some((ppm, opt_uii)) = &sess.opts.pretty {
293289
if ppm.needs_ast_map(&opt_uii) {
294290
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
295291
let expanded_crate = compiler.expansion()?.take().0;
296292
pretty::print_after_hir_lowering(
297293
tcx,
298294
compiler.input(),
299295
&expanded_crate,
300-
ppm,
296+
*ppm,
301297
opt_uii.clone(),
302298
compiler.output_file().as_ref().map(|p| &**p),
303299
);
@@ -309,7 +305,7 @@ pub fn run_compiler(
309305
sess,
310306
&compiler.input(),
311307
&krate,
312-
ppm,
308+
*ppm,
313309
compiler.output_file().as_ref().map(|p| &**p),
314310
);
315311
}
@@ -468,28 +464,6 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option
468464
}
469465
}
470466

471-
fn parse_pretty(sess: &Session,
472-
matches: &getopts::Matches)
473-
-> Option<(PpMode, Option<UserIdentifiedItem>)> {
474-
let pretty = if sess.opts.debugging_opts.unstable_options {
475-
matches.opt_default("pretty", "normal").map(|a| {
476-
// stable pretty-print variants only
477-
pretty::parse_pretty(sess, &a, false)
478-
})
479-
} else {
480-
None
481-
};
482-
483-
if pretty.is_none() {
484-
sess.opts.debugging_opts.unpretty.as_ref().map(|a| {
485-
// extended with unstable pretty-print variants
486-
pretty::parse_pretty(sess, &a, true)
487-
})
488-
} else {
489-
pretty
490-
}
491-
}
492-
493467
// Whether to stop or continue compilation.
494468
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
495469
pub enum Compilation {

0 commit comments

Comments
 (0)