Skip to content

Commit 9d157ad

Browse files
committed
Warn on unused doc(hidden) on trait impl items
1 parent 83322c5 commit 9d157ad

File tree

18 files changed

+225
-26
lines changed

18 files changed

+225
-26
lines changed

compiler/rustc_passes/src/check_attr.rs

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
//! conflicts between multiple such attributes attached to the same
55
//! item.
66
7-
use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
7+
use rustc_ast::tokenstream::DelimSpan;
8+
use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MacArgs, MetaItemKind, NestedMetaItem};
89
use rustc_data_structures::fx::FxHashMap;
910
use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
1011
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
@@ -810,6 +811,68 @@ impl CheckAttrVisitor<'_> {
810811
}
811812
}
812813

814+
/// Checks `#[doc(hidden)]` attributes. Returns `true` if valid.
815+
fn check_doc_hidden(
816+
&self,
817+
attr: &Attribute,
818+
meta_index: usize,
819+
meta: &NestedMetaItem,
820+
hir_id: HirId,
821+
target: Target,
822+
) -> bool {
823+
if let Target::AssocConst
824+
| Target::AssocTy
825+
| Target::Method(MethodKind::Trait { body: true }) = target
826+
{
827+
let parent_hir_id = self.tcx.hir().get_parent_item(hir_id);
828+
let containing_item = self.tcx.hir().expect_item(parent_hir_id);
829+
830+
if Target::from_item(containing_item) == Target::Impl {
831+
let meta_items = attr.meta_item_list().unwrap();
832+
833+
let (span, replacement_span) = if meta_items.len() == 1 {
834+
(attr.span, attr.span)
835+
} else {
836+
let meta_span = meta.span();
837+
(
838+
meta_span,
839+
meta_span.until(match meta_items.get(meta_index + 1) {
840+
Some(next_item) => next_item.span(),
841+
None => match attr.get_normal_item().args {
842+
MacArgs::Delimited(DelimSpan { close, .. }, ..) => close,
843+
_ => unreachable!(),
844+
},
845+
}),
846+
)
847+
};
848+
849+
// FIXME: #[doc(hidden)] was previously erroneously allowed on trait impl items,
850+
// so for backward compatibility only emit a warning and do not mark it as invalid.
851+
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, span, |lint| {
852+
lint.build("`#[doc(hidden)]` is ignored on trait impl items")
853+
.warn(
854+
"this was previously accepted by the compiler but is \
855+
being phased out; it will become a hard error in \
856+
a future release!",
857+
)
858+
.note(
859+
"whether the impl item is `doc(hidden)` or not \
860+
entirely depends on the corresponding trait item",
861+
)
862+
.span_suggestion(
863+
replacement_span,
864+
"remove this attribute",
865+
String::new(),
866+
Applicability::MachineApplicable,
867+
)
868+
.emit();
869+
});
870+
}
871+
}
872+
873+
true
874+
}
875+
813876
/// Checks that an attribute is *not* used at the crate level. Returns `true` if valid.
814877
fn check_attr_not_crate_level(
815878
&self,
@@ -928,7 +991,7 @@ impl CheckAttrVisitor<'_> {
928991
let mut is_valid = true;
929992

930993
if let Some(mi) = attr.meta() && let Some(list) = mi.meta_item_list() {
931-
for meta in list {
994+
for (meta_index, meta) in list.into_iter().enumerate() {
932995
if let Some(i_meta) = meta.meta_item() {
933996
match i_meta.name_or_empty() {
934997
sym::alias
@@ -969,6 +1032,15 @@ impl CheckAttrVisitor<'_> {
9691032
is_valid = false;
9701033
}
9711034

1035+
sym::hidden if !self.check_doc_hidden(attr,
1036+
meta_index,
1037+
meta,
1038+
hir_id,
1039+
target,
1040+
) => {
1041+
is_valid = false;
1042+
}
1043+
9721044
// no_default_passes: deprecated
9731045
// passes: deprecated
9741046
// plugins: removed, but rustdoc warns about it itself

library/alloc/src/collections/vec_deque/iter.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ impl<'a, T> Iterator for Iter<'a, T> {
122122
}
123123

124124
#[inline]
125-
#[doc(hidden)]
126125
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
127126
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
128127
// that is in bounds.

library/alloc/src/collections/vec_deque/iter_mut.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ impl<'a, T> Iterator for IterMut<'a, T> {
100100
}
101101

102102
#[inline]
103-
#[doc(hidden)]
104103
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
105104
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
106105
// that is in bounds.

library/alloc/src/vec/into_iter.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
202202
self.len()
203203
}
204204

205-
#[doc(hidden)]
206205
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
207206
where
208207
Self: TrustedRandomAccessNoCoerce,

library/core/src/convert/num.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ macro_rules! impl_float_to_int {
2525
$(
2626
#[unstable(feature = "convert_float_to_int", issue = "67057")]
2727
impl FloatToInt<$Int> for $Float {
28-
#[doc(hidden)]
2928
#[inline]
3029
unsafe fn to_int_unchecked(self) -> $Int {
3130
// SAFETY: the safety contract must be upheld by the caller.

library/core/src/iter/adapters/cloned.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ where
6060
self.it.map(T::clone).fold(init, f)
6161
}
6262

63-
#[doc(hidden)]
6463
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
6564
where
6665
Self: TrustedRandomAccessNoCoerce,

library/core/src/iter/adapters/copied.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ where
8181
self.it.advance_by(n)
8282
}
8383

84-
#[doc(hidden)]
8584
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
8685
where
8786
Self: TrustedRandomAccessNoCoerce,

library/core/src/iter/adapters/enumerate.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ where
128128
}
129129

130130
#[rustc_inherit_overflow_checks]
131-
#[doc(hidden)]
132131
#[inline]
133132
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
134133
where

library/core/src/iter/adapters/fuse.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ where
129129
}
130130

131131
#[inline]
132-
#[doc(hidden)]
133132
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
134133
where
135134
Self: TrustedRandomAccessNoCoerce,

library/core/src/iter/adapters/map.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ where
124124
self.iter.fold(init, map_fold(self.f, g))
125125
}
126126

127-
#[doc(hidden)]
128127
#[inline]
129128
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
130129
where

0 commit comments

Comments
 (0)