Skip to content

Commit e40d7d9

Browse files
committed
Resolve $crates for pretty-printing at more appropriate time
1 parent 24af9f8 commit e40d7d9

File tree

7 files changed

+53
-40
lines changed

7 files changed

+53
-40
lines changed

src/librustc_resolve/build_reduced_graph.rs

-11
Original file line numberDiff line numberDiff line change
@@ -1025,15 +1025,4 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
10251025
}
10261026
visit::walk_attribute(self, attr);
10271027
}
1028-
1029-
fn visit_ident(&mut self, ident: Ident) {
1030-
if ident.name == keywords::DollarCrate.name() {
1031-
let name = match self.resolver.resolve_crate_root(ident).kind {
1032-
ModuleKind::Def(_, name) if name != keywords::Invalid.name() => name,
1033-
_ => keywords::Crate.name(),
1034-
};
1035-
ident.span.ctxt().set_dollar_crate_name(name);
1036-
}
1037-
visit::walk_ident(self, ident);
1038-
}
10391028
}

src/librustc_resolve/macros.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
22
use {CrateLint, Resolver, ResolutionError, ScopeSet, Weak};
3-
use {Module, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding};
3+
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding};
44
use {is_known_tool, resolve_error};
55
use ModuleOrUniformRoot;
66
use Namespace::*;
@@ -15,12 +15,13 @@ use syntax::ast::{self, Ident};
1515
use syntax::attr;
1616
use syntax::errors::DiagnosticBuilder;
1717
use syntax::ext::base::{self, Determinacy};
18-
use syntax::ext::base::{MacroKind, SyntaxExtension};
18+
use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension};
1919
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
2020
use syntax::ext::hygiene::{self, Mark};
2121
use syntax::ext::tt::macro_rules;
2222
use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue};
2323
use syntax::symbol::{Symbol, keywords};
24+
use syntax::visit::Visitor;
2425
use syntax::util::lev_distance::find_best_match_for_name;
2526
use syntax_pos::{Span, DUMMY_SP};
2627
use errors::Applicability;
@@ -126,6 +127,26 @@ impl<'a> base::Resolver for Resolver<'a> {
126127
mark
127128
}
128129

130+
fn resolve_dollar_crates(&mut self, annotatable: &Annotatable) {
131+
pub struct ResolveDollarCrates<'a, 'b: 'a> {
132+
pub resolver: &'a mut Resolver<'b>,
133+
}
134+
impl<'a> Visitor<'a> for ResolveDollarCrates<'a, '_> {
135+
fn visit_ident(&mut self, ident: Ident) {
136+
if ident.name == keywords::DollarCrate.name() {
137+
let name = match self.resolver.resolve_crate_root(ident).kind {
138+
ModuleKind::Def(_, name) if name != keywords::Invalid.name() => name,
139+
_ => keywords::Crate.name(),
140+
};
141+
ident.span.ctxt().set_dollar_crate_name(name);
142+
}
143+
}
144+
fn visit_mac(&mut self, _: &ast::Mac) {}
145+
}
146+
147+
annotatable.visit_with(&mut ResolveDollarCrates { resolver: self });
148+
}
149+
129150
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
130151
derives: &[Mark]) {
131152
let invocation = self.invocations[&mark];

src/libsyntax/ext/base.rs

+14
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use parse::token;
1414
use ptr::P;
1515
use smallvec::SmallVec;
1616
use symbol::{keywords, Ident, Symbol};
17+
use visit::Visitor;
1718
use ThinVec;
1819

1920
use rustc_data_structures::fx::FxHashMap;
@@ -135,6 +136,17 @@ impl Annotatable {
135136
_ => false,
136137
}
137138
}
139+
140+
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
141+
match self {
142+
Annotatable::Item(item) => visitor.visit_item(item),
143+
Annotatable::TraitItem(trait_item) => visitor.visit_trait_item(trait_item),
144+
Annotatable::ImplItem(impl_item) => visitor.visit_impl_item(impl_item),
145+
Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
146+
Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
147+
Annotatable::Expr(expr) => visitor.visit_expr(expr),
148+
}
149+
}
138150
}
139151

140152
// A more flexible ItemDecorator.
@@ -723,6 +735,7 @@ pub trait Resolver {
723735
fn next_node_id(&mut self) -> ast::NodeId;
724736
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;
725737

738+
fn resolve_dollar_crates(&mut self, annotatable: &Annotatable);
726739
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
727740
derives: &[Mark]);
728741
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
@@ -756,6 +769,7 @@ impl Resolver for DummyResolver {
756769
fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
757770
fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
758771

772+
fn resolve_dollar_crates(&mut self, _annotatable: &Annotatable) {}
759773
fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment,
760774
_derives: &[Mark]) {}
761775
fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}

src/libsyntax/ext/expand.rs

+4
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
576576
Some(invoc.fragment_kind.expect_from_annotatables(items))
577577
}
578578
AttrProcMacro(ref mac, ..) => {
579+
// Resolve `$crate`s in case we have to go though stringification.
580+
self.cx.resolver.resolve_dollar_crates(&item);
579581
self.gate_proc_macro_attr_item(attr.span, &item);
580582
let item_tok = TokenTree::Token(DUMMY_SP, Token::interpolated(match item {
581583
Annotatable::Item(item) => token::NtItem(item),
@@ -918,6 +920,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
918920

919921
match *ext {
920922
ProcMacroDerive(ref ext, ..) => {
923+
// Resolve `$crate`s in case we have to go though stringification.
924+
self.cx.resolver.resolve_dollar_crates(&item);
921925
invoc.expansion_data.mark.set_expn_info(expn_info);
922926
let span = span.with_ctxt(self.cx.backtrace());
923927
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this

src/test/ui/proc-macro/dollar-crate-issue-57089.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-pass
12
// edition:2018
23
// aux-build:dollar-crate.rs
34

@@ -15,7 +16,7 @@ macro_rules! m {
1516
struct M($crate::S);
1617
}
1718

18-
#[dollar_crate::a] //~ ERROR expected type, found `$`
19+
#[dollar_crate::a]
1920
struct A($crate::S);
2021
};
2122
}

src/test/ui/proc-macro/dollar-crate-issue-57089.stderr

-11
This file was deleted.

src/test/ui/proc-macro/dollar-crate-issue-57089.stdout

+10-15
Original file line numberDiff line numberDiff line change
@@ -38,48 +38,43 @@ PROC MACRO INPUT: TokenStream [
3838
span: #2 bytes(LO..HI)
3939
}
4040
]
41-
ATTRIBUTE INPUT (PRETTY-PRINTED): struct A($crate::S);
41+
ATTRIBUTE INPUT (PRETTY-PRINTED): struct A(crate::S);
4242
ATTRIBUTE INPUT: TokenStream [
4343
Ident {
4444
ident: "struct",
45-
span: #0 bytes(0..0)
45+
span: #2 bytes(LO..HI)
4646
},
4747
Ident {
4848
ident: "A",
49-
span: #0 bytes(0..0)
49+
span: #2 bytes(LO..HI)
5050
},
5151
Group {
5252
delimiter: Parenthesis,
5353
stream: TokenStream [
54-
Punct {
55-
ch: '$',
56-
spacing: Alone,
57-
span: #0 bytes(0..0)
58-
},
5954
Ident {
60-
ident: "crate",
61-
span: #0 bytes(0..0)
55+
ident: "$crate",
56+
span: #2 bytes(LO..HI)
6257
},
6358
Punct {
6459
ch: ':',
6560
spacing: Joint,
66-
span: #0 bytes(0..0)
61+
span: #2 bytes(LO..HI)
6762
},
6863
Punct {
6964
ch: ':',
7065
spacing: Alone,
71-
span: #0 bytes(0..0)
66+
span: #2 bytes(LO..HI)
7267
},
7368
Ident {
7469
ident: "S",
75-
span: #0 bytes(0..0)
70+
span: #2 bytes(LO..HI)
7671
}
7772
],
78-
span: #0 bytes(0..0)
73+
span: #2 bytes(LO..HI)
7974
},
8075
Punct {
8176
ch: ';',
8277
spacing: Alone,
83-
span: #0 bytes(0..0)
78+
span: #2 bytes(LO..HI)
8479
}
8580
]

0 commit comments

Comments
 (0)