From 3c2fd1a72d2e8cc80b354b4d2dd7931a7afe1b02 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 14 Jul 2019 21:17:37 +0100 Subject: [PATCH] Print syntax contexts and marks when printing hygiene information --- src/librustc_driver/pretty.rs | 9 +++++-- src/libsyntax/print/pprust.rs | 2 ++ src/libsyntax_pos/hygiene.rs | 32 +++++++++++++++++++++++ src/test/ui/hygiene/unpretty-debug.stdout | 10 +++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index c4d3ad946f9..fa9504e2201 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -326,6 +326,7 @@ impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> { } fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { match node { + pprust::AnnNode::Crate(_) | pprust::AnnNode::Ident(_) | pprust::AnnNode::Name(_) => {}, @@ -431,14 +432,18 @@ impl<'a> pprust::PpAnn for HygieneAnnotation<'a> { match node { pprust::AnnNode::Ident(&ast::Ident { name, span }) => { s.s.space(); - // FIXME #16420: this doesn't display the connections - // between syntax contexts s.synth_comment(format!("{}{:?}", name.as_u32(), span.ctxt())) } pprust::AnnNode::Name(&name) => { s.s.space(); s.synth_comment(name.as_u32().to_string()) } + pprust::AnnNode::Crate(_) => { + s.s.hardbreak(); + let verbose = self.sess.verbose(); + s.synth_comment(syntax_pos::hygiene::debug_hygiene_data(verbose)); + s.s.hardbreak_if_not_bol(); + } _ => {} } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index dd8c76342e3..bf36c0d2f56 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -35,6 +35,7 @@ pub enum AnnNode<'a> { SubItem(ast::NodeId), Expr(&'a ast::Expr), Pat(&'a ast::Pat), + Crate(&'a ast::Crate), } pub trait PpAnn { @@ -140,6 +141,7 @@ pub fn print_crate<'a>(cm: &'a SourceMap, s.print_mod(&krate.module, &krate.attrs); s.print_remaining_comments(); + s.ann.post(&mut s, AnnNode::Crate(krate)); s.s.eof() } diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index f0e7344c1b9..8142d44b3f6 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -343,6 +343,38 @@ pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symb })) } +pub fn debug_hygiene_data(verbose: bool) -> String { + HygieneData::with(|data| { + if verbose { + format!("{:#?}", data) + } else { + let mut s = String::from(""); + s.push_str("Expansions:"); + data.expn_data.iter().enumerate().for_each(|(id, expn_info)| { + let expn_info = expn_info.as_ref().expect("no expansion data for an expansion ID"); + s.push_str(&format!( + "\n{}: parent: {:?}, call_site_ctxt: {:?}, kind: {:?}", + id, + expn_info.parent, + expn_info.call_site.ctxt(), + expn_info.kind, + )); + }); + s.push_str("\n\nSyntaxContexts:"); + data.syntax_context_data.iter().enumerate().for_each(|(id, ctxt)| { + s.push_str(&format!( + "\n#{}: parent: {:?}, outer_mark: ({:?}, {:?})", + id, + ctxt.parent, + ctxt.outer_expn, + ctxt.outer_transparency, + )); + }); + s + } + }) +} + impl SyntaxContext { #[inline] pub const fn root() -> Self { diff --git a/src/test/ui/hygiene/unpretty-debug.stdout b/src/test/ui/hygiene/unpretty-debug.stdout index beac4c17abf..6971873ba60 100644 --- a/src/test/ui/hygiene/unpretty-debug.stdout +++ b/src/test/ui/hygiene/unpretty-debug.stdout @@ -13,3 +13,13 @@ macro_rules! foo /* 0#0 */ { ($ x : ident) => { y + $ x } } fn bar /* 0#0 */() { let x /* 0#0 */ = 1; y /* 0#1 */ + x /* 0#0 */ } fn y /* 0#0 */() { } + +/* +Expansions: +0: parent: ExpnId(0), call_site_ctxt: #0, kind: Root +1: parent: ExpnId(0), call_site_ctxt: #0, kind: Macro(Bang, foo) + +SyntaxContexts: +#0: parent: #0, outer_mark: (ExpnId(0), Opaque) +#1: parent: #0, outer_mark: (ExpnId(1), SemiTransparent) +*/