Skip to content

Commit 17dfce0

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 1d8b291 commit 17dfce0

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
@@ -3505,6 +3505,7 @@ dependencies = [
35053505
"rustc_mir",
35063506
"rustc_plugin",
35073507
"rustc_plugin_impl",
3508+
"rustc_resolve",
35083509
"rustc_save_analysis",
35093510
"rustc_target",
35103511
"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
}
@@ -2527,6 +2533,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
25272533

25282534
let remap_path_prefix = parse_remap_path_prefix(matches, error_format);
25292535

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

@@ -2667,6 +2742,151 @@ impl fmt::Display for CrateType {
26672742
}
26682743
}
26692744

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

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

291-
if let Some((ppm, opt_uii)) = pretty_info {
287+
if let Some((ppm, opt_uii)) = &sess.opts.pretty {
292288
if ppm.needs_ast_map(&opt_uii) {
293289
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
294290
let expanded_crate = compiler.expansion()?.take().0;
295291
pretty::print_after_hir_lowering(
296292
tcx,
297293
compiler.input(),
298294
&expanded_crate,
299-
ppm,
295+
*ppm,
300296
opt_uii.clone(),
301297
compiler.output_file().as_ref().map(|p| &**p),
302298
);
@@ -308,7 +304,7 @@ pub fn run_compiler(
308304
sess,
309305
&compiler.input(),
310306
&krate,
311-
ppm,
307+
*ppm,
312308
compiler.output_file().as_ref().map(|p| &**p),
313309
);
314310
}
@@ -467,28 +463,6 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option
467463
}
468464
}
469465

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

0 commit comments

Comments
 (0)