about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-02-08 06:47:37 +0100
committerGitHub <noreply@github.com>2022-02-08 06:47:37 +0100
commit1f90f4fb85e9924e24272f6bc12a0c561291c682 (patch)
tree802631ca0b5bbdf5274c9862a0e3d485dac9be72
parent7d5e2ac5eb78c5d3054267bbec5c31fcf8193507 (diff)
parentf026550113b62b7bbd33faf39a7048f5a34fe289 (diff)
downloadrust-1f90f4fb85e9924e24272f6bc12a0c561291c682.tar.gz
rust-1f90f4fb85e9924e24272f6bc12a0c561291c682.zip
Rollup merge of #93721 - jyn514:less-macro-special-casing, r=petrochenkov
rustdoc: Special-case macro lookups less

Previously, rustdoc had 3 fallbacks it used:
1. `resolve_macro_path`
2. `all_macros`
3. `resolve_str_path_error`

Ideally, it would only use `resolve_str_path_error`, to be consistent with other namespaces.
Unfortunately, that doesn't consider macros that aren't defined at module scope;
consider for instance
```rust
{
    struct S;

    macro_rules! mac { () => {} }
    // `mac`'s scope starts here

    /// `mac` <- `resolve_str_path_error` won't see this
   struct Z;

    //`mac`'s scope ends here
}
```

This changes it to only use `all_macros` and `resolve_str_path_error`, and gives
`resolve_str_path_error` precedence over `all_macros` in case there are two macros with the same
name in the same module.

This is a smaller version of https://github.com/rust-lang/rust/pull/91427.

r? `@petrochenkov`
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs24
-rw-r--r--src/test/rustdoc-ui/intra-doc/macro-rules.rs9
2 files changed, 14 insertions, 19 deletions
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 86662ebaaca..8621fe6ba1b 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -2,10 +2,8 @@
 //!
 //! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md
 
-use rustc_ast as ast;
 use rustc_data_structures::{fx::FxHashMap, stable_set::FxHashSet};
 use rustc_errors::{Applicability, DiagnosticBuilder};
-use rustc_expand::base::SyntaxExtensionKind;
 use rustc_hir::def::{
     DefKind,
     Namespace::{self, *},
@@ -14,7 +12,6 @@ use rustc_hir::def::{
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_ID};
 use rustc_middle::ty::{DefIdTree, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug, ty};
-use rustc_resolve::ParentScope;
 use rustc_session::lint::Lint;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{sym, Ident, Symbol};
@@ -486,23 +483,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
         path_str: &'a str,
         module_id: DefId,
     ) -> Result<Res, ResolutionFailure<'a>> {
-        let path = ast::Path::from_ident(Ident::from_str(path_str));
         self.cx.enter_resolver(|resolver| {
-            // FIXME(jynelson): does this really need 3 separate lookups?
-            if let Ok((Some(ext), res)) = resolver.resolve_macro_path(
-                &path,
-                None,
-                &ParentScope::module(resolver.graph_root(), resolver),
-                false,
-                false,
-            ) {
-                if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
-                    return Ok(res.try_into().unwrap());
-                }
-            }
-            if let Some(&res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
-                return Ok(res.try_into().unwrap());
-            }
+            // NOTE: this needs 2 separate lookups because `resolve_str_path_error` doesn't take
+            // lexical scope into account (it ignores all macros not defined at the mod-level)
             debug!("resolving {} as a macro in the module {:?}", path_str, module_id);
             if let Ok((_, res)) =
                 resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id)
@@ -512,6 +495,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     return Ok(res);
                 }
             }
+            if let Some(&res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
+                return Ok(res.try_into().unwrap());
+            }
             Err(ResolutionFailure::NotResolved {
                 module_id,
                 partial_res: None,
diff --git a/src/test/rustdoc-ui/intra-doc/macro-rules.rs b/src/test/rustdoc-ui/intra-doc/macro-rules.rs
new file mode 100644
index 00000000000..a14e4bdf1d7
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-doc/macro-rules.rs
@@ -0,0 +1,9 @@
+// check-pass
+#![allow(rustdoc::private_intra_doc_links)]
+
+macro_rules! foo {
+    () => {};
+}
+
+/// [foo!]
+pub fn baz() {}