about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-16 00:10:34 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-18 13:42:45 +0300
commit1b4fbfca4181c6779b75a4a1dc6c8fd538d6edcc (patch)
treec9d6cda8313c88b941b4225e1abfbc5c1fdacfca
parenta7726ce08680c8c0789286f799be13c5b0ad9a01 (diff)
downloadrust-1b4fbfca4181c6779b75a4a1dc6c8fd538d6edcc.tar.gz
rust-1b4fbfca4181c6779b75a4a1dc6c8fd538d6edcc.zip
resolve: Support resolving macro paths without macro kind restrictions
-rw-r--r--src/librustc_resolve/diagnostics.rs2
-rw-r--r--src/librustc_resolve/lib.rs8
-rw-r--r--src/librustc_resolve/macros.rs18
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs7
4 files changed, 18 insertions, 17 deletions
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 9024d2ae36f..90a4107f773 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -574,7 +574,7 @@ impl<'a> Resolver<'a> {
                         for derive in &parent_scope.derives {
                             let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope };
                             if let Ok((Some(ext), _)) = this.resolve_macro_path(
-                                derive, MacroKind::Derive, &parent_scope, false, false
+                                derive, Some(MacroKind::Derive), &parent_scope, false, false
                             ) {
                                 suggestions.extend(ext.helper_attrs.iter().map(|name| {
                                     TypoSuggestion::from_res(*name, res)
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 4679c80ee1c..ba8cfdcf535 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3684,11 +3684,9 @@ impl<'a> Resolver<'a> {
             let path = Path { segments: path.iter().map(path_seg).collect(), span };
             let parent_scope =
                 ParentScope { module: self.current_module, ..self.dummy_parent_scope() };
-            for macro_kind in &[MacroKind::Bang, MacroKind::Attr, MacroKind::Derive] {
-                if let Ok((_, res)) = self.resolve_macro_path(&path, *macro_kind,
-                                                              &parent_scope, false, false) {
-                    return Some(PartialRes::new(res));
-                }
+            if let Ok((_, res)) =
+                    self.resolve_macro_path(&path, None, &parent_scope, false, false) {
+                return Some(PartialRes::new(res));
             }
         }
 
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 9da73eb4f7c..34e85e1cf10 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -220,7 +220,7 @@ impl<'a> base::Resolver for Resolver<'a> {
         };
 
         let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope);
-        let (ext, res) = self.smart_resolve_macro_path(path, kind, &parent_scope, true, force)?;
+        let (ext, res) = self.smart_resolve_macro_path(path, kind, &parent_scope, force)?;
 
         let span = invoc.span();
         invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, fast_print_path(path)));
@@ -269,10 +269,10 @@ impl<'a> Resolver<'a> {
         path: &ast::Path,
         kind: MacroKind,
         parent_scope: &ParentScope<'a>,
-        trace: bool,
         force: bool,
     ) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> {
-        let (ext, res) = match self.resolve_macro_path(path, kind, parent_scope, trace, force) {
+        let (ext, res) = match self.resolve_macro_path(path, Some(kind), parent_scope,
+                                                       true, force) {
             Ok((Some(ext), res)) => (ext, res),
             // Use dummy syntax extensions for unresolved macros for better recovery.
             Ok((None, res)) => (self.dummy_ext(kind), res),
@@ -334,7 +334,7 @@ impl<'a> Resolver<'a> {
     pub fn resolve_macro_path(
         &mut self,
         path: &ast::Path,
-        kind: MacroKind,
+        kind: Option<MacroKind>,
         parent_scope: &ParentScope<'a>,
         trace: bool,
         force: bool,
@@ -343,7 +343,7 @@ impl<'a> Resolver<'a> {
         let mut path = Segment::from_path(path);
 
         // Possibly apply the macro helper hack
-        if kind == MacroKind::Bang && path.len() == 1 &&
+        if kind == Some(MacroKind::Bang) && path.len() == 1 &&
            path[0].ident.span.ctxt().outer_expn_info()
                .map_or(false, |info| info.local_inner_macros) {
             let root = Ident::new(kw::DollarCrate, path[0].ident.span);
@@ -364,6 +364,7 @@ impl<'a> Resolver<'a> {
             };
 
             if trace {
+                let kind = kind.expect("macro kind must be specified if tracing is enabled");
                 parent_scope.module.multi_segment_macro_resolutions.borrow_mut()
                     .push((path, path_span, kind, parent_scope.clone(), res.ok()));
             }
@@ -371,14 +372,17 @@ impl<'a> Resolver<'a> {
             self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span);
             res
         } else {
+            // Macro without a specific kind restriction is equvalent to a macro import.
+            let scope_set = kind.map_or(ScopeSet::Import(MacroNS), ScopeSet::Macro);
             let binding = self.early_resolve_ident_in_lexical_scope(
-                path[0].ident, ScopeSet::Macro(kind), parent_scope, false, force, path_span
+                path[0].ident, scope_set, parent_scope, false, force, path_span
             );
             if let Err(Determinacy::Undetermined) = binding {
                 return Err(Determinacy::Undetermined);
             }
 
             if trace {
+                let kind = kind.expect("macro kind must be specified if tracing is enabled");
                 parent_scope.module.single_segment_macro_resolutions.borrow_mut()
                     .push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
             }
@@ -452,7 +456,7 @@ impl<'a> Resolver<'a> {
                     let mut result = Err(Determinacy::Determined);
                     for derive in &parent_scope.derives {
                         let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope };
-                        match this.resolve_macro_path(derive, MacroKind::Derive,
+                        match this.resolve_macro_path(derive, Some(MacroKind::Derive),
                                                       &parent_scope, true, force) {
                             Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) {
                                 let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index c527ed02bc0..04de3374d05 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -6,6 +6,7 @@ use rustc::lint as lint;
 use rustc::ty;
 use syntax;
 use syntax::ast::{self, Ident};
+use syntax::ext::base::SyntaxExtensionKind;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::symbol::Symbol;
 use syntax_pos::DUMMY_SP;
@@ -425,12 +426,10 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
 
 /// Resolves a string as a macro.
 fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
-    use syntax::ext::base::{MacroKind, SyntaxExtensionKind};
-    let segment = ast::PathSegment::from_ident(Ident::from_str(path_str));
-    let path = ast::Path { segments: vec![segment], span: DUMMY_SP };
+    let path = ast::Path::from_ident(Ident::from_str(path_str));
     cx.enter_resolver(|resolver| {
         if let Ok((Some(ext), res)) = resolver.resolve_macro_path(
-            &path, MacroKind::Bang, &resolver.dummy_parent_scope(), false, false
+            &path, None, &resolver.dummy_parent_scope(), false, false
         ) {
             if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
                 return Some(res.map_id(|_| panic!("unexpected id")));