return spans out of is_doc_comment to reduce reliance on .span() on attrs

This commit is contained in:
Jana Dönszelmann 2025-10-14 15:21:27 +02:00
parent 956f47c32f
commit 3941b42993
No known key found for this signature in database
10 changed files with 22 additions and 17 deletions

View file

@ -86,10 +86,10 @@ impl AttributeExt for Attribute {
/// Returns `true` if it is a sugared doc comment (`///` or `//!` for example).
/// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not
/// a doc comment) will return `false`.
fn is_doc_comment(&self) -> bool {
fn is_doc_comment(&self) -> Option<Span> {
match self.kind {
AttrKind::Normal(..) => false,
AttrKind::DocComment(..) => true,
AttrKind::Normal(..) => None,
AttrKind::DocComment(..) => Some(self.span),
}
}
@ -776,7 +776,7 @@ pub trait AttributeExt: Debug {
/// Returns `true` if it is a sugared doc comment (`///` or `//!` for example).
/// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not
/// a doc comment) will return `false`.
fn is_doc_comment(&self) -> bool;
fn is_doc_comment(&self) -> Option<Span>;
#[inline]
fn has_name(&self, name: Symbol) -> bool {
@ -863,8 +863,9 @@ impl Attribute {
AttributeExt::path_matches(self, name)
}
// on ast attributes we return a bool since that's what most code already expects
pub fn is_doc_comment(&self) -> bool {
AttributeExt::is_doc_comment(self)
AttributeExt::is_doc_comment(self).is_some()
}
#[inline]

View file

@ -28,7 +28,8 @@ pub fn parse_version(s: Symbol) -> Option<RustcVersion> {
}
pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool {
attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name))
attr.is_doc_comment().is_some()
|| attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name))
}
pub fn is_doc_alias_attrs_contain_symbol<'tcx, T: AttributeExt + 'tcx>(

View file

@ -1304,8 +1304,12 @@ impl AttributeExt for Attribute {
}
#[inline]
fn is_doc_comment(&self) -> bool {
matches!(self, Attribute::Parsed(AttributeKind::DocComment { .. }))
fn is_doc_comment(&self) -> Option<Span> {
if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = self {
Some(*span)
} else {
None
}
}
#[inline]
@ -1425,7 +1429,7 @@ impl Attribute {
}
#[inline]
pub fn is_doc_comment(&self) -> bool {
pub fn is_doc_comment(&self) -> Option<Span> {
AttributeExt::is_doc_comment(self)
}

View file

@ -391,7 +391,7 @@ pub struct MissingDoc;
impl_lint_pass!(MissingDoc => [MISSING_DOCS]);
fn has_doc(attr: &hir::Attribute) -> bool {
if attr.is_doc_comment() {
if attr.is_doc_comment().is_some() {
return true;
}

View file

@ -22,7 +22,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for [hir::Attribute] {
let filtered: SmallVec<[&hir::Attribute; 8]> = self
.iter()
.filter(|attr| {
!attr.is_doc_comment()
attr.is_doc_comment().is_none()
// FIXME(jdonszelmann) have a better way to handle ignored attrs
&& !attr.ident().is_some_and(|ident| hcx.is_ignored_attr(ident.name))
})

View file

@ -214,8 +214,7 @@ pub fn attrs_to_doc_fragments<'a, A: AttributeExt + Clone + 'a>(
for (attr, item_id) in attrs {
if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() {
let doc = beautify_doc_string(doc_str, comment_kind);
let (span, kind, from_expansion) = if attr.is_doc_comment() {
let span = attr.span();
let (span, kind, from_expansion) = if let Some(span) = attr.is_doc_comment() {
(span, DocFragmentKind::SugaredDoc, span.from_expansion())
} else {
let attr_span = attr.span();

View file

@ -2719,7 +2719,7 @@ fn add_without_unwanted_attributes<'hir>(
import_parent: Option<DefId>,
) {
for attr in new_attrs {
if attr.is_doc_comment() {
if attr.is_doc_comment().is_some() {
attrs.push((Cow::Borrowed(attr), import_parent));
continue;
}

View file

@ -65,7 +65,7 @@ fn filter_non_cfg_tokens_from_list(args_tokens: &TokenStream) -> Vec<TokenTree>
/// it and put them into `attrs`.
fn add_only_cfg_attributes(attrs: &mut Vec<Attribute>, new_attrs: &[Attribute]) {
for attr in new_attrs {
if attr.is_doc_comment() {
if attr.is_doc_comment().is_some() {
continue;
}
let mut attr = attr.clone();

View file

@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for FourForwardSlashes {
.tcx
.hir_attrs(item.hir_id())
.iter()
.filter(|i| i.is_doc_comment())
.filter(|i| i.is_doc_comment().is_some())
.fold(item.span.shrink_to_lo(), |span, attr| span.to(attr.span()));
let (Some(file), _, _, end_line, _) = sm.span_to_location_info(span) else {
return;

View file

@ -475,7 +475,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span {
span.to(cx.tcx.hir_attrs(hir_id).iter().fold(span, |acc, attr| {
if attr.is_doc_comment() {
if attr.is_doc_comment().is_some() {
return acc;
}
acc.to(attr.span())