about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2025-06-20 11:49:32 -0700
committerDavid Tolnay <dtolnay@gmail.com>2025-06-21 11:09:12 -0700
commite51c37c34c3f576a2e1b7b3d5f0bd5d993c87d24 (patch)
tree379cd00b609366a374a08e601becd0e321ab3caf
parentea34650916887b5075812d0f11c1d3209e7f94ab (diff)
downloadrust-e51c37c34c3f576a2e1b7b3d5f0bd5d993c87d24.tar.gz
rust-e51c37c34c3f576a2e1b7b3d5f0bd5d993c87d24.zip
Add AttributeExt::doc_resolution_scope
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs21
-rw-r--r--compiler/rustc_hir/src/hir.rs10
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs7
3 files changed, 37 insertions, 1 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 621e3042b62..755bd3577ea 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -206,6 +206,18 @@ impl AttributeExt for Attribute {
         }
     }
 
+    fn doc_resolution_scope(&self) -> Option<AttrStyle> {
+        match &self.kind {
+            AttrKind::DocComment(..) => Some(self.style),
+            AttrKind::Normal(normal)
+                if normal.item.path == sym::doc && normal.item.value_str().is_some() =>
+            {
+                Some(self.style)
+            }
+            _ => None,
+        }
+    }
+
     fn style(&self) -> AttrStyle {
         self.style
     }
@@ -806,6 +818,15 @@ pub trait AttributeExt: Debug {
     /// * `#[doc(...)]` returns `None`.
     fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)>;
 
+    /// Returns outer or inner if this is a doc attribute or a sugared doc
+    /// comment, otherwise None.
+    ///
+    /// This is used in the case of doc comments on modules, to decide whether
+    /// to resolve intra-doc links against the symbols in scope within the
+    /// commented module (for inner doc) vs within its parent module (for outer
+    /// doc).
+    fn doc_resolution_scope(&self) -> Option<AttrStyle>;
+
     fn style(&self) -> AttrStyle;
 }
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 1a526d5bce0..883161318d3 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1346,6 +1346,16 @@ impl AttributeExt for Attribute {
         }
     }
 
+    fn doc_resolution_scope(&self) -> Option<AttrStyle> {
+        match self {
+            Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style),
+            Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => {
+                Some(attr.style)
+            }
+            _ => None,
+        }
+    }
+
     #[inline]
     fn style(&self) -> AttrStyle {
         match &self {
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index fa839d2748d..931c6241bf2 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -356,7 +356,12 @@ pub fn strip_generics_from_path(path_str: &str) -> Result<Box<str>, MalformedGen
 /// If there are no doc-comments, return true.
 /// FIXME(#78591): Support both inner and outer attributes on the same item.
 pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool {
-    attrs.iter().find(|a| a.doc_str().is_some()).is_none_or(|a| a.style() == ast::AttrStyle::Inner)
+    for attr in attrs {
+        if let Some(attr_style) = attr.doc_resolution_scope() {
+            return attr_style == ast::AttrStyle::Inner;
+        }
+    }
+    true
 }
 
 /// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`.