Rollup merge of #66575 - Mark-Simulacrum:no-uii, r=petrochenkov
Remove pretty printing of specific nodes in AST The ability to print a specific item as identified by NodeId or path seems not particularly useful, and certainly carries quite a bit of complexity with it. This is intended to simplify our CLI parsing a bit and remove a non-uncomplicated piece of it; I largely did this to remove the dependency on NodeId from librustc/session but it's not really necessary to do so in this invasive a way. The alternative is moving it to librustc_interface or driver, probably.
This commit is contained in:
commit
c66b508137
9 changed files with 17 additions and 215 deletions
|
|
@ -1,13 +1,10 @@
|
|||
//! 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;
|
||||
|
||||
|
|
@ -444,7 +441,7 @@ top_level_options!(
|
|||
// by the compiler.
|
||||
json_artifact_notifications: bool [TRACKED],
|
||||
|
||||
pretty: Option<(PpMode, Option<UserIdentifiedItem>)> [UNTRACKED],
|
||||
pretty: Option<PpMode> [UNTRACKED],
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -2562,7 +2559,7 @@ fn parse_pretty(
|
|||
matches: &getopts::Matches,
|
||||
debugging_opts: &DebuggingOptions,
|
||||
efmt: ErrorOutputType,
|
||||
) -> Option<(PpMode, Option<UserIdentifiedItem>)> {
|
||||
) -> Option<PpMode> {
|
||||
let pretty = if debugging_opts.unstable_options {
|
||||
matches.opt_default("pretty", "normal").map(|a| {
|
||||
// stable pretty-print variants only
|
||||
|
|
@ -2585,13 +2582,10 @@ fn parse_pretty(
|
|||
efmt: ErrorOutputType,
|
||||
name: &str,
|
||||
extended: bool,
|
||||
) -> (PpMode, Option<UserIdentifiedItem>) {
|
||||
) -> PpMode {
|
||||
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) {
|
||||
let first = match (name, extended) {
|
||||
("normal", _) => PpmSource(PpmNormal),
|
||||
("identified", _) => PpmSource(PpmIdentified),
|
||||
("everybody_loops", true) => PpmSource(PpmEveryBodyLoops),
|
||||
|
|
@ -2619,8 +2613,7 @@ fn parse_pretty(
|
|||
}
|
||||
}
|
||||
};
|
||||
let opt_second = opt_second.and_then(|s| s.parse::<UserIdentifiedItem>().ok());
|
||||
(first, opt_second)
|
||||
first
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2752,13 +2745,13 @@ pub enum PpMode {
|
|||
}
|
||||
|
||||
impl PpMode {
|
||||
pub fn needs_ast_map(&self, opt_uii: &Option<UserIdentifiedItem>) -> bool {
|
||||
pub fn needs_ast_map(&self) -> bool {
|
||||
use PpMode::*;
|
||||
use PpSourceMode::*;
|
||||
match *self {
|
||||
PpmSource(PpmNormal) |
|
||||
PpmSource(PpmEveryBodyLoops) |
|
||||
PpmSource(PpmIdentified) => opt_uii.is_some(),
|
||||
PpmSource(PpmIdentified) => false,
|
||||
|
||||
PpmSource(PpmExpanded) |
|
||||
PpmSource(PpmExpandedIdentified) |
|
||||
|
|
@ -2780,102 +2773,6 @@ impl PpMode {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum UserIdentifiedItem {
|
||||
ItemViaNode(ast::NodeId),
|
||||
ItemViaPath(Vec<String>),
|
||||
}
|
||||
|
||||
impl FromStr for UserIdentifiedItem {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
|
||||
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<ast::NodeId>),
|
||||
NodesMatchingSuffix(Box<dyn Iterator<Item = ast::NodeId> + 'a>),
|
||||
}
|
||||
|
||||
impl<'a> Iterator for NodesMatchingUII<'a> {
|
||||
type Item = ast::NodeId;
|
||||
|
||||
fn next(&mut self) -> Option<ast::NodeId> {
|
||||
use NodesMatchingUII::*;
|
||||
match self {
|
||||
&mut NodesMatchingDirect(ref mut iter) => iter.next(),
|
||||
&mut NodesMatchingSuffix(ref mut iter) => iter.next(),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -285,8 +285,8 @@ pub fn run_compiler(
|
|||
|
||||
compiler.parse()?;
|
||||
|
||||
if let Some((ppm, opt_uii)) = &sess.opts.pretty {
|
||||
if ppm.needs_ast_map(&opt_uii) {
|
||||
if let Some(ppm) = &sess.opts.pretty {
|
||||
if ppm.needs_ast_map() {
|
||||
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
|
||||
let expanded_crate = compiler.expansion()?.take().0;
|
||||
pretty::print_after_hir_lowering(
|
||||
|
|
@ -294,7 +294,6 @@ pub fn run_compiler(
|
|||
compiler.input(),
|
||||
&expanded_crate,
|
||||
*ppm,
|
||||
opt_uii.clone(),
|
||||
compiler.output_file().as_ref().map(|p| &**p),
|
||||
);
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use rustc::hir::map as hir_map;
|
|||
use rustc::hir::print as pprust_hir;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::{PpMode, PpSourceMode, UserIdentifiedItem, Input};
|
||||
use rustc::session::config::{PpMode, PpSourceMode, Input};
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::util::common::ErrorReported;
|
||||
use rustc_mir::util::{write_mir_pretty, write_mir_graphviz};
|
||||
|
|
@ -19,7 +19,6 @@ use std::fs::File;
|
|||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
pub use self::UserIdentifiedItem::*;
|
||||
pub use self::PpSourceMode::*;
|
||||
pub use self::PpMode::*;
|
||||
use crate::abort_on_err;
|
||||
|
|
@ -444,14 +443,12 @@ pub fn print_after_hir_lowering<'tcx>(
|
|||
input: &Input,
|
||||
krate: &ast::Crate,
|
||||
ppm: PpMode,
|
||||
opt_uii: Option<UserIdentifiedItem>,
|
||||
ofile: Option<&Path>,
|
||||
) {
|
||||
if ppm.needs_analysis() {
|
||||
abort_on_err(print_with_analysis(
|
||||
tcx,
|
||||
ppm,
|
||||
opt_uii,
|
||||
ofile
|
||||
), tcx.sess);
|
||||
return;
|
||||
|
|
@ -461,8 +458,8 @@ pub fn print_after_hir_lowering<'tcx>(
|
|||
|
||||
let mut out = String::new();
|
||||
|
||||
match (ppm, opt_uii) {
|
||||
(PpmSource(s), _) => {
|
||||
match ppm {
|
||||
PpmSource(s) => {
|
||||
// Silently ignores an identified node.
|
||||
let out = &mut out;
|
||||
let src = src.clone();
|
||||
|
|
@ -479,7 +476,7 @@ pub fn print_after_hir_lowering<'tcx>(
|
|||
})
|
||||
}
|
||||
|
||||
(PpmHir(s), None) => {
|
||||
PpmHir(s) => {
|
||||
let out = &mut out;
|
||||
let src = src.clone();
|
||||
call_with_pp_support_hir(&s, tcx, move |annotation, krate| {
|
||||
|
|
@ -494,7 +491,7 @@ pub fn print_after_hir_lowering<'tcx>(
|
|||
})
|
||||
}
|
||||
|
||||
(PpmHirTree(s), None) => {
|
||||
PpmHirTree(s) => {
|
||||
let out = &mut out;
|
||||
call_with_pp_support_hir(&s, tcx, move |_annotation, krate| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
|
|
@ -502,44 +499,6 @@ pub fn print_after_hir_lowering<'tcx>(
|
|||
});
|
||||
}
|
||||
|
||||
(PpmHir(s), Some(uii)) => {
|
||||
let out = &mut out;
|
||||
let src = src.clone();
|
||||
call_with_pp_support_hir(&s, tcx, move |annotation, _| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
let hir_map = annotation.hir_map().expect("-Z unpretty missing HIR map");
|
||||
let mut pp_state = pprust_hir::State::new_from_input(sess.source_map(),
|
||||
&sess.parse_sess,
|
||||
src_name,
|
||||
src,
|
||||
annotation.pp_ann());
|
||||
for node_id in uii.all_matching_node_ids(hir_map) {
|
||||
let hir_id = tcx.hir().node_to_hir_id(node_id);
|
||||
let node = hir_map.get(hir_id);
|
||||
pp_state.print_node(node);
|
||||
pp_state.s.space();
|
||||
let path = annotation.node_path(hir_id)
|
||||
.expect("-Z unpretty missing node paths");
|
||||
pp_state.synth_comment(path);
|
||||
pp_state.s.hardbreak();
|
||||
}
|
||||
*out = pp_state.s.eof();
|
||||
})
|
||||
}
|
||||
|
||||
(PpmHirTree(s), Some(uii)) => {
|
||||
let out = &mut out;
|
||||
call_with_pp_support_hir(&s, tcx, move |_annotation, _krate| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
for node_id in uii.all_matching_node_ids(tcx.hir()) {
|
||||
let hir_id = tcx.hir().node_to_hir_id(node_id);
|
||||
let node = tcx.hir().get(hir_id);
|
||||
out.push_str(&format!("{:#?}", node));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
|
|
@ -553,27 +512,17 @@ pub fn print_after_hir_lowering<'tcx>(
|
|||
fn print_with_analysis(
|
||||
tcx: TyCtxt<'_>,
|
||||
ppm: PpMode,
|
||||
uii: Option<UserIdentifiedItem>,
|
||||
ofile: Option<&Path>,
|
||||
) -> Result<(), ErrorReported> {
|
||||
let nodeid = if let Some(uii) = uii {
|
||||
debug!("pretty printing for {:?}", uii);
|
||||
Some(uii.to_one_node_id("-Z unpretty", tcx.sess, tcx.hir()))
|
||||
} else {
|
||||
debug!("pretty printing for whole crate");
|
||||
None
|
||||
};
|
||||
|
||||
let mut out = Vec::new();
|
||||
|
||||
tcx.analysis(LOCAL_CRATE)?;
|
||||
|
||||
match ppm {
|
||||
PpmMir | PpmMirCFG => {
|
||||
let def_id = nodeid.map(|nid| tcx.hir().local_def_id_from_node_id(nid));
|
||||
match ppm {
|
||||
PpmMir => write_mir_pretty(tcx, def_id, &mut out),
|
||||
PpmMirCFG => write_mir_graphviz(tcx, def_id, &mut out),
|
||||
PpmMir => write_mir_pretty(tcx, None, &mut out),
|
||||
PpmMirCFG => write_mir_graphviz(tcx, None, &mut out),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ fn configure_and_expand_inner<'a>(
|
|||
// If we're actually rustdoc then there's no need to actually compile
|
||||
// anything, so switch everything to just looping
|
||||
let mut should_loop = sess.opts.actually_rustdoc;
|
||||
if let Some((PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops), _)) = sess.opts.pretty {
|
||||
if let Some(PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops)) = sess.opts.pretty {
|
||||
should_loop |= true;
|
||||
}
|
||||
if should_loop {
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) -o $(TMPDIR)/foo.out -Z unpretty=hir=foo input.rs
|
||||
$(RUSTC) -o $(TMPDIR)/nest_foo.out -Z unpretty=hir=nest::foo input.rs
|
||||
$(RUSTC) -o $(TMPDIR)/foo_method.out -Z unpretty=hir=foo_method input.rs
|
||||
diff -u $(TMPDIR)/foo.out foo.pp
|
||||
diff -u $(TMPDIR)/nest_foo.out nest_foo.pp
|
||||
diff -u $(TMPDIR)/foo_method.out foo_method.pp
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
pub fn foo() -> i32 { 45 } /* foo */
|
||||
|
||||
|
||||
pub fn foo() -> &'static str { "i am a foo." } /* nest::foo */
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
fn foo_method(self: &Self)
|
||||
-> &'static str { return "i am very similar to foo."; } /*
|
||||
nest::{{impl}}::foo_method */
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#![crate_type="lib"]
|
||||
|
||||
pub fn
|
||||
foo() -> i32
|
||||
{ 45 }
|
||||
|
||||
pub fn bar() -> &'static str { "i am not a foo." }
|
||||
|
||||
pub mod nest {
|
||||
pub fn foo() -> &'static str { "i am a foo." }
|
||||
|
||||
struct S;
|
||||
impl S {
|
||||
fn foo_method(&self) -> &'static str {
|
||||
return "i am very similar to foo.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
|
||||
pub fn foo() -> &'static str { "i am a foo." } /* nest::foo */
|
||||
Loading…
Add table
Add a link
Reference in a new issue