Resolve $crate
s for pretty-printing at more appropriate time
This commit is contained in:
parent
24af9f88a5
commit
e40d7d9643
7 changed files with 53 additions and 40 deletions
|
@ -1025,15 +1025,4 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
|
||||||
}
|
}
|
||||||
visit::walk_attribute(self, attr);
|
visit::walk_attribute(self, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ident(&mut self, ident: Ident) {
|
|
||||||
if ident.name == keywords::DollarCrate.name() {
|
|
||||||
let name = match self.resolver.resolve_crate_root(ident).kind {
|
|
||||||
ModuleKind::Def(_, name) if name != keywords::Invalid.name() => name,
|
|
||||||
_ => keywords::Crate.name(),
|
|
||||||
};
|
|
||||||
ident.span.ctxt().set_dollar_crate_name(name);
|
|
||||||
}
|
|
||||||
visit::walk_ident(self, ident);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
|
use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
|
||||||
use {CrateLint, Resolver, ResolutionError, ScopeSet, Weak};
|
use {CrateLint, Resolver, ResolutionError, ScopeSet, Weak};
|
||||||
use {Module, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding};
|
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding};
|
||||||
use {is_known_tool, resolve_error};
|
use {is_known_tool, resolve_error};
|
||||||
use ModuleOrUniformRoot;
|
use ModuleOrUniformRoot;
|
||||||
use Namespace::*;
|
use Namespace::*;
|
||||||
|
@ -15,12 +15,13 @@ use syntax::ast::{self, Ident};
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::errors::DiagnosticBuilder;
|
use syntax::errors::DiagnosticBuilder;
|
||||||
use syntax::ext::base::{self, Determinacy};
|
use syntax::ext::base::{self, Determinacy};
|
||||||
use syntax::ext::base::{MacroKind, SyntaxExtension};
|
use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension};
|
||||||
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
|
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
|
||||||
use syntax::ext::hygiene::{self, Mark};
|
use syntax::ext::hygiene::{self, Mark};
|
||||||
use syntax::ext::tt::macro_rules;
|
use syntax::ext::tt::macro_rules;
|
||||||
use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue};
|
use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue};
|
||||||
use syntax::symbol::{Symbol, keywords};
|
use syntax::symbol::{Symbol, keywords};
|
||||||
|
use syntax::visit::Visitor;
|
||||||
use syntax::util::lev_distance::find_best_match_for_name;
|
use syntax::util::lev_distance::find_best_match_for_name;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
use errors::Applicability;
|
use errors::Applicability;
|
||||||
|
@ -126,6 +127,26 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
mark
|
mark
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_dollar_crates(&mut self, annotatable: &Annotatable) {
|
||||||
|
pub struct ResolveDollarCrates<'a, 'b: 'a> {
|
||||||
|
pub resolver: &'a mut Resolver<'b>,
|
||||||
|
}
|
||||||
|
impl<'a> Visitor<'a> for ResolveDollarCrates<'a, '_> {
|
||||||
|
fn visit_ident(&mut self, ident: Ident) {
|
||||||
|
if ident.name == keywords::DollarCrate.name() {
|
||||||
|
let name = match self.resolver.resolve_crate_root(ident).kind {
|
||||||
|
ModuleKind::Def(_, name) if name != keywords::Invalid.name() => name,
|
||||||
|
_ => keywords::Crate.name(),
|
||||||
|
};
|
||||||
|
ident.span.ctxt().set_dollar_crate_name(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn visit_mac(&mut self, _: &ast::Mac) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
annotatable.visit_with(&mut ResolveDollarCrates { resolver: self });
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
|
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
|
||||||
derives: &[Mark]) {
|
derives: &[Mark]) {
|
||||||
let invocation = self.invocations[&mark];
|
let invocation = self.invocations[&mark];
|
||||||
|
|
|
@ -14,6 +14,7 @@ use parse::token;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use symbol::{keywords, Ident, Symbol};
|
use symbol::{keywords, Ident, Symbol};
|
||||||
|
use visit::Visitor;
|
||||||
use ThinVec;
|
use ThinVec;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
@ -135,6 +136,17 @@ impl Annotatable {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
|
||||||
|
match self {
|
||||||
|
Annotatable::Item(item) => visitor.visit_item(item),
|
||||||
|
Annotatable::TraitItem(trait_item) => visitor.visit_trait_item(trait_item),
|
||||||
|
Annotatable::ImplItem(impl_item) => visitor.visit_impl_item(impl_item),
|
||||||
|
Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
|
||||||
|
Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
|
||||||
|
Annotatable::Expr(expr) => visitor.visit_expr(expr),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A more flexible ItemDecorator.
|
// A more flexible ItemDecorator.
|
||||||
|
@ -723,6 +735,7 @@ pub trait Resolver {
|
||||||
fn next_node_id(&mut self) -> ast::NodeId;
|
fn next_node_id(&mut self) -> ast::NodeId;
|
||||||
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;
|
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;
|
||||||
|
|
||||||
|
fn resolve_dollar_crates(&mut self, annotatable: &Annotatable);
|
||||||
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
|
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
|
||||||
derives: &[Mark]);
|
derives: &[Mark]);
|
||||||
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
|
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
|
||||||
|
@ -756,6 +769,7 @@ impl Resolver for DummyResolver {
|
||||||
fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
|
fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
|
||||||
fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
|
fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
|
||||||
|
|
||||||
|
fn resolve_dollar_crates(&mut self, _annotatable: &Annotatable) {}
|
||||||
fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment,
|
fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment,
|
||||||
_derives: &[Mark]) {}
|
_derives: &[Mark]) {}
|
||||||
fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}
|
fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}
|
||||||
|
|
|
@ -576,6 +576,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
Some(invoc.fragment_kind.expect_from_annotatables(items))
|
Some(invoc.fragment_kind.expect_from_annotatables(items))
|
||||||
}
|
}
|
||||||
AttrProcMacro(ref mac, ..) => {
|
AttrProcMacro(ref mac, ..) => {
|
||||||
|
// Resolve `$crate`s in case we have to go though stringification.
|
||||||
|
self.cx.resolver.resolve_dollar_crates(&item);
|
||||||
self.gate_proc_macro_attr_item(attr.span, &item);
|
self.gate_proc_macro_attr_item(attr.span, &item);
|
||||||
let item_tok = TokenTree::Token(DUMMY_SP, Token::interpolated(match item {
|
let item_tok = TokenTree::Token(DUMMY_SP, Token::interpolated(match item {
|
||||||
Annotatable::Item(item) => token::NtItem(item),
|
Annotatable::Item(item) => token::NtItem(item),
|
||||||
|
@ -918,6 +920,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
|
|
||||||
match *ext {
|
match *ext {
|
||||||
ProcMacroDerive(ref ext, ..) => {
|
ProcMacroDerive(ref ext, ..) => {
|
||||||
|
// Resolve `$crate`s in case we have to go though stringification.
|
||||||
|
self.cx.resolver.resolve_dollar_crates(&item);
|
||||||
invoc.expansion_data.mark.set_expn_info(expn_info);
|
invoc.expansion_data.mark.set_expn_info(expn_info);
|
||||||
let span = span.with_ctxt(self.cx.backtrace());
|
let span = span.with_ctxt(self.cx.backtrace());
|
||||||
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
|
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// compile-pass
|
||||||
// edition:2018
|
// edition:2018
|
||||||
// aux-build:dollar-crate.rs
|
// aux-build:dollar-crate.rs
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ macro_rules! m {
|
||||||
struct M($crate::S);
|
struct M($crate::S);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dollar_crate::a] //~ ERROR expected type, found `$`
|
#[dollar_crate::a]
|
||||||
struct A($crate::S);
|
struct A($crate::S);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
error: expected type, found `$`
|
|
||||||
--> $DIR/dollar-crate-in-tokens.rs:18:9
|
|
||||||
|
|
|
||||||
LL | #[dollar_crate::a] //~ ERROR expected type, found `$`
|
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | m!();
|
|
||||||
| ----- in this macro invocation
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
|
@ -38,48 +38,43 @@ PROC MACRO INPUT: TokenStream [
|
||||||
span: #2 bytes(LO..HI)
|
span: #2 bytes(LO..HI)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
ATTRIBUTE INPUT (PRETTY-PRINTED): struct A($crate::S);
|
ATTRIBUTE INPUT (PRETTY-PRINTED): struct A(crate::S);
|
||||||
ATTRIBUTE INPUT: TokenStream [
|
ATTRIBUTE INPUT: TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
span: #0 bytes(0..0)
|
span: #2 bytes(LO..HI)
|
||||||
},
|
},
|
||||||
Ident {
|
Ident {
|
||||||
ident: "A",
|
ident: "A",
|
||||||
span: #0 bytes(0..0)
|
span: #2 bytes(LO..HI)
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
delimiter: Parenthesis,
|
delimiter: Parenthesis,
|
||||||
stream: TokenStream [
|
stream: TokenStream [
|
||||||
Punct {
|
|
||||||
ch: '$',
|
|
||||||
spacing: Alone,
|
|
||||||
span: #0 bytes(0..0)
|
|
||||||
},
|
|
||||||
Ident {
|
Ident {
|
||||||
ident: "crate",
|
ident: "$crate",
|
||||||
span: #0 bytes(0..0)
|
span: #2 bytes(LO..HI)
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
ch: ':',
|
ch: ':',
|
||||||
spacing: Joint,
|
spacing: Joint,
|
||||||
span: #0 bytes(0..0)
|
span: #2 bytes(LO..HI)
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
ch: ':',
|
ch: ':',
|
||||||
spacing: Alone,
|
spacing: Alone,
|
||||||
span: #0 bytes(0..0)
|
span: #2 bytes(LO..HI)
|
||||||
},
|
},
|
||||||
Ident {
|
Ident {
|
||||||
ident: "S",
|
ident: "S",
|
||||||
span: #0 bytes(0..0)
|
span: #2 bytes(LO..HI)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
span: #0 bytes(0..0)
|
span: #2 bytes(LO..HI)
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
ch: ';',
|
ch: ';',
|
||||||
spacing: Alone,
|
spacing: Alone,
|
||||||
span: #0 bytes(0..0)
|
span: #2 bytes(LO..HI)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue