From 1b4fbfca4181c6779b75a4a1dc6c8fd538d6edcc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 16 Jul 2019 00:10:34 +0300 Subject: [PATCH] resolve: Support resolving macro paths without macro kind restrictions --- src/librustc_resolve/diagnostics.rs | 2 +- src/librustc_resolve/lib.rs | 8 +++----- src/librustc_resolve/macros.rs | 18 +++++++++++------- .../passes/collect_intra_doc_links.rs | 7 +++---- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 9024d2ae36fe8..90a4107f773e1 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 4679c80ee1cd7..ba8cfdcf53548 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 9da73eb4f7cd8..34e85e1cf1011 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, 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, 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 c527ed02bc05b..04de3374d0587 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 { - 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")));