about summary refs log tree commit diff
path: root/src/librustc_resolve
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-12-28 02:54:14 +0000
committerbors <bors@rust-lang.org>2018-12-28 02:54:14 +0000
commite8ca35e63dda82a8b5fa8eb72cf3e490a5794a46 (patch)
tree190e1b7ce725d1fdfaf44e49c34a9465d558ac0a /src/librustc_resolve
parentf8caa321c7c7214a6c5415e4b3694e65b4ff73a7 (diff)
parente40d7d9643b810b2bc62f279e1d6f4ad68a35bc2 (diff)
Auto merge of #57155 - petrochenkov:dcrate3, r=dtolnay
Resolve `$crate`s for pretty-printing at more appropriate time

Doing it in `BuildReducedGraphVisitor` wasn't a good idea, identifiers wasn't actually visited half of the time.
As a result some `$crate`s weren't resolved and were therefore pretty-printed as `$crate` literally, which turns into two tokens during re-parsing of the pretty-printed text.

Now we are visiting and resolving `$crate` identifiers in an item right before sending that item to a proc macro attribute or derive.

Fixes https://github.com/rust-lang/rust/issues/57089
Diffstat (limited to 'src/librustc_resolve')
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs11
-rw-r--r--src/librustc_resolve/macros.rs25
2 files changed, 23 insertions, 13 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 8f5d110655a..21fb29974c8 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -1025,15 +1025,4 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
         }
         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);
-    }
 }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 182dcfe4098..5f6ef934c1a 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -1,6 +1,6 @@
 use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
 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 ModuleOrUniformRoot;
 use Namespace::*;
@@ -15,12 +15,13 @@ use syntax::ast::{self, Ident};
 use syntax::attr;
 use syntax::errors::DiagnosticBuilder;
 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::hygiene::{self, Mark};
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue};
 use syntax::symbol::{Symbol, keywords};
+use syntax::visit::Visitor;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::{Span, DUMMY_SP};
 use errors::Applicability;
@@ -126,6 +127,26 @@ impl<'a> base::Resolver for Resolver<'a> {
         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,
                                             derives: &[Mark]) {
         let invocation = self.invocations[&mark];