Skip to content

Commit af26fea

Browse files
Add check for usage of both doc(auto_cfg) and doc(no_auto_cfg) at the same time
1 parent 1071085 commit af26fea

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

compiler/rustc_error_messages/locales/en-US/passes.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ passes_doc_alias_malformed =
7777
7878
passes_doc_auto_cfg_malformed = `#![doc({$attr_str})]` attribute doesn't expect a value
7979
80+
passes_doc_both_auto_cfg = please don't specify both `doc(auto_cfg)` and `doc(no_auto_cfg)`
81+
.label = the other is specified here
82+
8083
passes_doc_no_auto_cfg_enabled_by_default = `doc(no_auto_cfg)` is enabled by default before the 2024 edition
8184
8285
passes_doc_auto_cfg_enabled_by_default = `doc(auto_cfg)` is enabled by default since the 2024 edition

compiler/rustc_passes/src/check_attr.rs

+23-5
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ impl CheckAttrVisitor<'_> {
9898
target,
9999
&mut specified_inline,
100100
&mut doc_aliases,
101+
&mut seen,
101102
),
102103
sym::no_link => self.check_no_link(hir_id, &attr, span, target),
103104
sym::export_name => self.check_export_name(hir_id, &attr, span, target),
@@ -948,15 +949,16 @@ impl CheckAttrVisitor<'_> {
948949

949950
/// Checks that `doc(auto_cfg)` is valid (i.e. no value) and warn if it's used whereas the
950951
/// "equivalent feature" is already enabled.
951-
fn check_auto_cfg(&self, meta: &MetaItem, hir_id: HirId) -> bool {
952+
fn check_auto_cfg(&self, meta: &MetaItem, hir_id: HirId, seen: &mut FxHashMap<Symbol, Span>) -> bool {
952953
let name = meta.name_or_empty();
953-
let mut is_valid = true;
954954
if !meta.is_word() {
955955
self.tcx
956956
.sess
957957
.emit_err(errors::DocAutoCfgMalformed { span: meta.span, attr_str: name.as_str() });
958-
is_valid = false;
959-
} else if name == sym::no_auto_cfg {
958+
return false;
959+
}
960+
let mut is_valid = true;
961+
let other = if name == sym::no_auto_cfg {
960962
if self.tcx.sess.edition() < Edition::Edition2024 {
961963
self.tcx.emit_spanned_lint(
962964
UNUSED_ATTRIBUTES,
@@ -966,6 +968,7 @@ impl CheckAttrVisitor<'_> {
966968
);
967969
is_valid = false;
968970
}
971+
sym::auto_cfg
969972
} else {
970973
if self.tcx.sess.edition() > Edition::Edition2021 {
971974
self.tcx.emit_spanned_lint(
@@ -976,7 +979,21 @@ impl CheckAttrVisitor<'_> {
976979
);
977980
is_valid = false;
978981
}
982+
sym::no_auto_cfg
983+
};
984+
985+
match seen.entry(other) {
986+
Entry::Occupied(entry) => {
987+
self.tcx
988+
.sess
989+
.emit_err(errors::BothDocAutoCfg { span: *entry.get(), attr_span: meta.span });
990+
is_valid = false;
991+
}
992+
Entry::Vacant(entry) => {
993+
entry.insert(meta.span);
994+
}
979995
}
996+
980997
is_valid
981998
}
982999

@@ -993,6 +1010,7 @@ impl CheckAttrVisitor<'_> {
9931010
target: Target,
9941011
specified_inline: &mut Option<(bool, Span)>,
9951012
aliases: &mut FxHashMap<String, Span>,
1013+
seen: &mut FxHashMap<Symbol, Span>,
9961014
) -> bool {
9971015
let mut is_valid = true;
9981016

@@ -1048,7 +1066,7 @@ impl CheckAttrVisitor<'_> {
10481066
}
10491067

10501068
sym::auto_cfg | sym::no_auto_cfg
1051-
if !self.check_auto_cfg(i_meta, hir_id) => {
1069+
if !self.check_auto_cfg(i_meta, hir_id, seen) => {
10521070
is_valid = false;
10531071
}
10541072

compiler/rustc_passes/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,15 @@ pub struct DocAutoCfgMalformed<'a> {
197197
pub attr_str: &'a str,
198198
}
199199

200+
#[derive(Diagnostic)]
201+
#[diag(passes::doc_both_auto_cfg)]
202+
pub struct BothDocAutoCfg {
203+
#[primary_span]
204+
pub span: Span,
205+
#[label]
206+
pub attr_span: Span,
207+
}
208+
200209
#[derive(LintDiagnostic)]
201210
#[diag(passes::doc_auto_cfg_enabled_by_default)]
202211
pub struct DocAutoCfgEnabledByDefault;

src/librustdoc/core.rs

+1
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ pub(crate) fn create_config(
245245
rustc_lint::builtin::UNEXPECTED_CFGS.name.to_string(),
246246
// this lint is needed to support `#[expect]` attributes
247247
rustc_lint::builtin::UNFULFILLED_LINT_EXPECTATIONS.name.to_string(),
248+
rustc_lint::builtin::UNUSED_ATTRIBUTES.name.to_string(),
248249
];
249250
lints_to_show.extend(crate::lint::RUSTDOC_LINTS.iter().map(|lint| lint.name.to_string()));
250251

0 commit comments

Comments
 (0)