diff options
| author | bors <bors@rust-lang.org> | 2019-07-10 05:21:43 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-07-10 05:21:43 +0000 |
| commit | 0324a2b309cd66cb7bd4a156bd0b84cb136e254f (patch) | |
| tree | f85538e316a67aca8f749f5ebd1bb93754e6f206 /src/libsyntax | |
| parent | 3f435f622e0c05a199eb89b71a11181133fdb74c (diff) | |
| parent | 6c0a406b1c9e4c518586ac3cc2fe96c21840a5dc (diff) | |
| download | rust-0324a2b309cd66cb7bd4a156bd0b84cb136e254f.tar.gz rust-0324a2b309cd66cb7bd4a156bd0b84cb136e254f.zip | |
Auto merge of #62555 - Centril:rollup-ti46adx, r=Centril
Rollup of 5 pull requests Successful merges: - #61853 (Emit warning when trying to use PGO in conjunction with unwinding on …) - #62278 (Add Iterator::partition_in_place() and is_partitioned()) - #62283 (Target::arch can take more than listed options) - #62393 (Fix pretty-printing of `$crate` (take 4)) - #62474 (Prepare for LLVM 9 update) Failed merges: r? @ghost
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 109 |
3 files changed, 64 insertions, 49 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 15c0b6ca5aa..c0ba41b8af4 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -701,7 +701,7 @@ pub trait Resolver { fn get_module_scope(&mut self, id: ast::NodeId) -> Mark; - fn resolve_dollar_crates(&mut self, fragment: &AstFragment); + fn resolve_dollar_crates(&mut self); fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, derives: &[Mark]); fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 74ef5cbe917..053686b8b1f 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -429,7 +429,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { fn collect_invocations(&mut self, mut fragment: AstFragment, derives: &[Mark]) -> (AstFragment, Vec<Invocation>) { // Resolve `$crate`s in the fragment for pretty-printing. - self.cx.resolver.resolve_dollar_crates(&fragment); + self.cx.resolver.resolve_dollar_crates(); let invocations = { let mut collector = InvocationCollector { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 67646cce69b..7e099bc4d50 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -18,7 +18,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree}; use rustc_target::spec::abi::{self, Abi}; use syntax_pos::{self, BytePos}; -use syntax_pos::{DUMMY_SP, FileName}; +use syntax_pos::{DUMMY_SP, FileName, Span}; use std::borrow::Cow; use std::io::Read; @@ -181,7 +181,46 @@ pub fn literal_to_string(lit: token::Lit) -> String { out } +fn ident_to_string(ident: ast::Ident, is_raw: bool) -> String { + ident_to_string_ext(ident.name, is_raw, Some(ident.span)) +} + +// AST pretty-printer is used as a fallback for turning AST structures into token streams for +// proc macros. Additionally, proc macros may stringify their input and expect it survive the +// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30). +// So we need to somehow pretty-print `$crate` in a way preserving at least some of its +// hygiene data, most importantly name of the crate it refers to. +// As a result we print `$crate` as `crate` if it refers to the local crate +// and as `::other_crate_name` if it refers to some other crate. +// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing, +// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents, +// so we should not perform this lossy conversion if the top level call to the pretty-printer was +// done for a token stream or a single token. +fn ident_to_string_ext( + name: ast::Name, is_raw: bool, convert_dollar_crate: Option<Span> +) -> String { + if is_raw { + format!("r#{}", name) + } else { + if name == kw::DollarCrate { + if let Some(span) = convert_dollar_crate { + let converted = span.ctxt().dollar_crate_name(); + return if converted.is_path_segment_keyword() { + converted.to_string() + } else { + format!("::{}", converted) + } + } + } + name.to_string() + } +} + pub fn token_kind_to_string(tok: &TokenKind) -> String { + token_kind_to_string_ext(tok, None) +} + +fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>) -> String { match *tok { token::Eq => "=".to_string(), token::Lt => "<".to_string(), @@ -227,8 +266,7 @@ pub fn token_kind_to_string(tok: &TokenKind) -> String { token::Literal(lit) => literal_to_string(lit), /* Name components */ - token::Ident(s, false) => s.to_string(), - token::Ident(s, true) => format!("r#{}", s), + token::Ident(s, is_raw) => ident_to_string_ext(s, is_raw, convert_dollar_crate), token::Lifetime(s) => s.to_string(), /* Other */ @@ -243,7 +281,12 @@ pub fn token_kind_to_string(tok: &TokenKind) -> String { } pub fn token_to_string(token: &Token) -> String { - token_kind_to_string(&token.kind) + token_to_string_ext(token, false) +} + +fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String { + let convert_dollar_crate = if convert_dollar_crate { Some(token.span) } else { None }; + token_kind_to_string_ext(&token.kind, convert_dollar_crate) } crate fn nonterminal_to_string(nt: &Nonterminal) -> String { @@ -256,9 +299,8 @@ crate fn nonterminal_to_string(nt: &Nonterminal) -> String { token::NtBlock(ref e) => block_to_string(e), token::NtStmt(ref e) => stmt_to_string(e), token::NtPat(ref e) => pat_to_string(e), - token::NtIdent(e, false) => ident_to_string(e), - token::NtIdent(e, true) => format!("r#{}", ident_to_string(e)), - token::NtLifetime(e) => ident_to_string(e), + token::NtIdent(e, is_raw) => ident_to_string(e, is_raw), + token::NtLifetime(e) => e.to_string(), token::NtLiteral(ref e) => expr_to_string(e), token::NtTT(ref tree) => tt_to_string(tree.clone()), token::NtImplItem(ref e) => impl_item_to_string(e), @@ -293,15 +335,15 @@ pub fn lifetime_to_string(lt: &ast::Lifetime) -> String { } pub fn tt_to_string(tt: tokenstream::TokenTree) -> String { - to_string(|s| s.print_tt(tt)) + to_string(|s| s.print_tt(tt, false)) } pub fn tts_to_string(tts: &[tokenstream::TokenTree]) -> String { - to_string(|s| s.print_tts(tts.iter().cloned().collect())) + tokens_to_string(tts.iter().cloned().collect()) } pub fn tokens_to_string(tokens: TokenStream) -> String { - to_string(|s| s.print_tts(tokens)) + to_string(|s| s.print_tts_ext(tokens, false)) } pub fn stmt_to_string(stmt: &ast::Stmt) -> String { @@ -344,10 +386,6 @@ pub fn path_segment_to_string(p: &ast::PathSegment) -> String { to_string(|s| s.print_path_segment(p, false)) } -pub fn ident_to_string(id: ast::Ident) -> String { - to_string(|s| s.print_ident(id)) -} - pub fn vis_to_string(v: &ast::Visibility) -> String { to_string(|s| s.print_visibility(v)) } @@ -629,11 +667,7 @@ pub trait PrintState<'a> { self.writer().word("::"); } if segment.ident.name != kw::PathRoot { - if segment.ident.name == kw::DollarCrate { - self.print_dollar_crate(segment.ident); - } else { - self.writer().word(segment.ident.as_str().to_string()); - } + self.writer().word(ident_to_string(segment.ident, segment.ident.is_raw_guess())); } } } @@ -707,10 +741,10 @@ pub trait PrintState<'a> { /// appropriate macro, transcribe back into the grammar we just parsed from, /// and then pretty-print the resulting AST nodes (so, e.g., we print /// expression arguments as expressions). It can be done! I think. - fn print_tt(&mut self, tt: tokenstream::TokenTree) { + fn print_tt(&mut self, tt: tokenstream::TokenTree, convert_dollar_crate: bool) { match tt { TokenTree::Token(ref token) => { - self.writer().word(token_to_string(&token)); + self.writer().word(token_to_string_ext(&token, convert_dollar_crate)); match token.kind { token::DocComment(..) => { self.writer().hardbreak() @@ -729,12 +763,16 @@ pub trait PrintState<'a> { } fn print_tts(&mut self, tts: tokenstream::TokenStream) { + self.print_tts_ext(tts, true) + } + + fn print_tts_ext(&mut self, tts: tokenstream::TokenStream, convert_dollar_crate: bool) { self.ibox(0); for (i, tt) in tts.into_trees().enumerate() { if i != 0 { self.writer().space(); } - self.print_tt(tt); + self.print_tt(tt, convert_dollar_crate); } self.end(); } @@ -744,21 +782,6 @@ pub trait PrintState<'a> { } fn nbsp(&mut self) { self.writer().word(" ") } - - // AST pretty-printer is used as a fallback for turning AST structures into token streams for - // proc macros. Additionally, proc macros may stringify their input and expect it survive the - // stringification (especially true for proc macro derives written between Rust 1.15 and 1.30). - // So we need to somehow pretty-print `$crate` in paths in a way preserving at least some of - // its hygiene data, most importantly name of the crate it refers to. - // As a result we print `$crate` as `crate` if it refers to the local crate - // and as `::other_crate_name` if it refers to some other crate. - fn print_dollar_crate(&mut self, ident: ast::Ident) { - let name = ident.span.ctxt().dollar_crate_name(); - if !ast::Ident::with_empty_ctxt(name).is_path_segment_keyword() { - self.writer().word("::"); - } - self.writer().word(name.as_str().to_string()) - } } impl<'a> PrintState<'a> for State<'a> { @@ -2287,11 +2310,7 @@ impl<'a> State<'a> { } crate fn print_ident(&mut self, ident: ast::Ident) { - if ident.is_raw_guess() { - self.s.word(format!("r#{}", ident)); - } else { - self.s.word(ident.as_str().to_string()); - } + self.s.word(ident_to_string(ident, ident.is_raw_guess())); self.ann.post(self, AnnNode::Ident(&ident)) } @@ -2322,11 +2341,7 @@ impl<'a> State<'a> { segment: &ast::PathSegment, colons_before_params: bool) { if segment.ident.name != kw::PathRoot { - if segment.ident.name == kw::DollarCrate { - self.print_dollar_crate(segment.ident); - } else { - self.print_ident(segment.ident); - } + self.print_ident(segment.ident); if let Some(ref args) = segment.args { self.print_generic_args(args, colons_before_params); } |
