Skip to content

Commit 40c0cbc

Browse files
Improve code and better check doc(cfg(...)) attributes
1 parent 72c1dad commit 40c0cbc

File tree

14 files changed

+189
-58
lines changed

14 files changed

+189
-58
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
173173
gate_doc!(
174174
"experimental" {
175175
cfg => doc_cfg
176+
auto_cfg => doc_cfg
176177
masked => doc_masked
177178
notable_trait => doc_notable_trait
178179
}

compiler/rustc_passes/messages.ftl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ passes_doc_auto_cfg_hide_show_expects_list =
189189
`#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items
190190
191191
passes_doc_auto_cfg_hide_show_unexpected_item =
192-
`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/values items
192+
`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items
193193
194194
passes_doc_auto_cfg_wrong_literal =
195195
`expected boolean for #[doc(auto_cfg = ...)]`

compiler/rustc_passes/src/check_attr.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
13191319
}
13201320
MetaItemKind::List(list) => {
13211321
for item in list {
1322-
let Some(attr_name) = item.name() else { continue };
1322+
let Some(attr_name) = item.name() else {
1323+
self.tcx.emit_node_span_lint(
1324+
INVALID_DOC_ATTRIBUTES,
1325+
hir_id,
1326+
meta.span,
1327+
errors::DocAutoCfgExpectsHideOrShow,
1328+
);
1329+
continue;
1330+
};
13231331
if attr_name != sym::hide && attr_name != sym::show {
13241332
self.tcx.emit_node_span_lint(
13251333
INVALID_DOC_ATTRIBUTES,
@@ -1338,6 +1346,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
13381346
attr_name: attr_name.as_str(),
13391347
},
13401348
);
1349+
} else if match item {
1350+
MetaItemInner::Lit(_) => true,
1351+
// We already checked above that it's not a list.
1352+
MetaItemInner::MetaItem(meta) => meta.path.segments.len() != 1,
1353+
} {
1354+
self.tcx.emit_node_span_lint(
1355+
INVALID_DOC_ATTRIBUTES,
1356+
hir_id,
1357+
item.span(),
1358+
errors::DocAutoCfgHideShowUnexpectedItem {
1359+
attr_name: attr_name.as_str(),
1360+
},
1361+
);
13411362
}
13421363
}
13431364
} else {

compiler/rustc_span/src/symbol.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,6 @@ symbols! {
11061106
hashset_iter_ty,
11071107
hexagon_target_feature,
11081108
hidden,
1109-
hidden_cfg,
11101109
hide,
11111110
hint,
11121111
homogeneous_aggregate,

library/alloc/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@
8181
doc(auto_cfg(hide(
8282
bootstrap,
8383
no_global_oom_handling,
84-
no_global_oom_handling,
8584
no_rc,
8685
no_sync,
8786
target_has_atomic = "ptr"

src/librustdoc/clean/inline.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,10 @@ pub(crate) fn build_impl(
594594
});
595595
}
596596

597+
// In here, we pass an empty `CfgInfo` because the computation of `cfg` happens later, so it
598+
// doesn't matter at this point.
599+
//
600+
// We need to pass this empty `CfgInfo` because `merge_attrs` is used when computing the `cfg`.
597601
let (merged_attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs, &mut CfgInfo::default());
598602
trace!("merged_attrs={merged_attrs:?}");
599603

src/librustdoc/clean/types.rs

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,31 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
11101110
Some(item)
11111111
}
11121112

1113+
fn check_changed_auto_active_status(
1114+
changed_auto_active_status: &mut Option<rustc_span::Span>,
1115+
attr: &ast::MetaItem,
1116+
cfg_info: &mut CfgInfo,
1117+
tcx: TyCtxt<'_>,
1118+
new_value: bool,
1119+
) -> bool {
1120+
if let Some(first_change) = changed_auto_active_status {
1121+
if cfg_info.auto_cfg_active != new_value {
1122+
tcx.sess
1123+
.dcx()
1124+
.struct_span_err(
1125+
vec![*first_change, attr.span],
1126+
"`auto_cfg` was disabled and enabled more than once on the same item",
1127+
)
1128+
.emit();
1129+
return true;
1130+
}
1131+
} else {
1132+
*changed_auto_active_status = Some(attr.span);
1133+
}
1134+
cfg_info.auto_cfg_active = new_value;
1135+
false
1136+
}
1137+
11131138
let mut new_show_attrs = FxHashMap::default();
11141139
let mut new_hide_attrs = FxHashMap::default();
11151140

@@ -1184,49 +1209,39 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
11841209
};
11851210
match &attr.kind {
11861211
MetaItemKind::Word => {
1187-
if let Some(first_change) = changed_auto_active_status {
1188-
if !cfg_info.auto_cfg_active {
1189-
tcx.sess.dcx().struct_span_err(
1190-
vec![first_change, attr.span],
1191-
"`auto_cfg` was disabled and enabled more than once on the same item",
1192-
).emit();
1193-
return None;
1194-
}
1195-
} else {
1196-
changed_auto_active_status = Some(attr.span);
1212+
if check_changed_auto_active_status(
1213+
&mut changed_auto_active_status,
1214+
attr,
1215+
cfg_info,
1216+
tcx,
1217+
true,
1218+
) {
1219+
return None;
11971220
}
1198-
cfg_info.auto_cfg_active = true;
11991221
}
12001222
MetaItemKind::NameValue(lit) => {
12011223
if let LitKind::Bool(value) = lit.kind {
1202-
if let Some(first_change) = changed_auto_active_status {
1203-
if cfg_info.auto_cfg_active != value {
1204-
tcx.sess.dcx().struct_span_err(
1205-
vec![first_change, attr.span],
1206-
"`auto_cfg` was disabled and enabled more than once on the same item",
1207-
).emit();
1208-
return None;
1209-
}
1210-
} else {
1211-
changed_auto_active_status = Some(attr.span);
1224+
if check_changed_auto_active_status(
1225+
&mut changed_auto_active_status,
1226+
attr,
1227+
cfg_info,
1228+
tcx,
1229+
value,
1230+
) {
1231+
return None;
12121232
}
1213-
cfg_info.auto_cfg_active = value;
12141233
}
12151234
}
12161235
MetaItemKind::List(sub_attrs) => {
1217-
if let Some(first_change) = changed_auto_active_status {
1218-
if !cfg_info.auto_cfg_active {
1219-
tcx.sess.dcx().struct_span_err(
1220-
vec![first_change, attr.span],
1221-
"`auto_cfg` was disabled and enabled more than once on the same item",
1222-
).emit();
1223-
return None;
1224-
}
1225-
} else {
1226-
changed_auto_active_status = Some(attr.span);
1236+
if check_changed_auto_active_status(
1237+
&mut changed_auto_active_status,
1238+
attr,
1239+
cfg_info,
1240+
tcx,
1241+
true,
1242+
) {
1243+
return None;
12271244
}
1228-
// Whatever happens next, the feature is enabled again.
1229-
cfg_info.auto_cfg_active = true;
12301245
for sub_attr in sub_attrs.iter() {
12311246
if let Some(ident) = sub_attr.ident()
12321247
&& (ident.name == sym::show || ident.name == sym::hide)

tests/rustdoc-ui/doc-cfg.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,13 @@
88
// FIXME: Should emit: WARN unexpected `cfg` condition name: `bar`
99
#[doc(cfg())] //~ ERROR
1010
#[doc(cfg(foo, bar))] //~ ERROR
11+
#[doc(auto_cfg(42))] //~ ERROR
12+
#[doc(auto_cfg(hide(true)))] //~ ERROR
13+
#[doc(auto_cfg(hide(42)))] //~ ERROR
14+
#[doc(auto_cfg(hide("a")))] //~ ERROR
15+
#[doc(auto_cfg(hide(foo::bar)))] //~ ERROR
16+
// Shouldn't lint
17+
#[doc(auto_cfg(hide(windows)))]
18+
#[doc(auto_cfg(hide(feature = "windows")))]
19+
#[doc(auto_cfg(hide(foo)))]
1120
pub fn foo() {}

tests/rustdoc-ui/doc-cfg.stderr

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
1+
error: `only "hide" or "show" are allowed in "#[doc(auto_cfg(...))]"`
2+
--> $DIR/doc-cfg.rs:11:7
3+
|
4+
LL | #[doc(auto_cfg(42))]
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: `#[deny(invalid_doc_attributes)]` on by default
8+
9+
error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
10+
--> $DIR/doc-cfg.rs:12:21
11+
|
12+
LL | #[doc(auto_cfg(hide(true)))]
13+
| ^^^^
14+
15+
error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
16+
--> $DIR/doc-cfg.rs:13:21
17+
|
18+
LL | #[doc(auto_cfg(hide(42)))]
19+
| ^^
20+
21+
error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
22+
--> $DIR/doc-cfg.rs:14:21
23+
|
24+
LL | #[doc(auto_cfg(hide("a")))]
25+
| ^^^
26+
27+
error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
28+
--> $DIR/doc-cfg.rs:15:21
29+
|
30+
LL | #[doc(auto_cfg(hide(foo::bar)))]
31+
| ^^^^^^^^
32+
133
error: `cfg` predicate is not specified
234
--> $DIR/doc-cfg.rs:3:7
335
|
@@ -22,5 +54,5 @@ error: multiple `cfg` predicates are specified
2254
LL | #[doc(cfg(foo, bar))]
2355
| ^^^
2456

25-
error: aborting due to 4 previous errors
57+
error: aborting due to 9 previous errors
2658

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![doc(auto_cfg)] //~ ERROR
2+
#![doc(auto_cfg(false))] //~ ERROR
3+
#![doc(auto_cfg(true))] //~ ERROR
4+
#![doc(auto_cfg(hide(feature = "solecism")))] //~ ERROR
5+
#![doc(auto_cfg(show(feature = "bla")))] //~ ERROR
6+
#![doc(cfg(feature = "solecism"))] //~ ERROR
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
error[E0658]: `#[doc(auto_cfg)]` is experimental
2+
--> $DIR/feature-gate-doc_cfg.rs:1:1
3+
|
4+
LL | #![doc(auto_cfg)]
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
8+
= help: add `#![feature(doc_cfg)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error[E0658]: `#[doc(auto_cfg)]` is experimental
12+
--> $DIR/feature-gate-doc_cfg.rs:2:1
13+
|
14+
LL | #![doc(auto_cfg(false))]
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^
16+
|
17+
= note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
18+
= help: add `#![feature(doc_cfg)]` to the crate attributes to enable
19+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
20+
21+
error[E0658]: `#[doc(auto_cfg)]` is experimental
22+
--> $DIR/feature-gate-doc_cfg.rs:3:1
23+
|
24+
LL | #![doc(auto_cfg(true))]
25+
| ^^^^^^^^^^^^^^^^^^^^^^^
26+
|
27+
= note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
28+
= help: add `#![feature(doc_cfg)]` to the crate attributes to enable
29+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
30+
31+
error[E0658]: `#[doc(auto_cfg)]` is experimental
32+
--> $DIR/feature-gate-doc_cfg.rs:4:1
33+
|
34+
LL | #![doc(auto_cfg(hide(feature = "solecism")))]
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
36+
|
37+
= note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
38+
= help: add `#![feature(doc_cfg)]` to the crate attributes to enable
39+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
40+
41+
error[E0658]: `#[doc(auto_cfg)]` is experimental
42+
--> $DIR/feature-gate-doc_cfg.rs:5:1
43+
|
44+
LL | #![doc(auto_cfg(show(feature = "bla")))]
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
46+
|
47+
= note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
48+
= help: add `#![feature(doc_cfg)]` to the crate attributes to enable
49+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
50+
51+
error[E0658]: `#[doc(cfg)]` is experimental
52+
--> $DIR/feature-gate-doc_cfg.rs:6:1
53+
|
54+
LL | #![doc(cfg(feature = "solecism"))]
55+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
56+
|
57+
= note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information
58+
= help: add `#![feature(doc_cfg)]` to the crate attributes to enable
59+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
60+
61+
error: aborting due to 6 previous errors
62+
63+
For more information about this error, try `rustc --explain E0658`.

tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs

Lines changed: 0 additions & 8 deletions
This file was deleted.

tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/rustdoc-ui/lints/doc_cfg_hide.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ error: `#![doc(auto_cfg(hide(...)))]` expects a list of items
1212
LL | #![doc(auto_cfg(hide))]
1313
| ^^^^^^^^^^^^^^
1414

15-
error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/values items
15+
error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items
1616
--> $DIR/doc_cfg_hide.rs:4:22
1717
|
1818
LL | #![doc(auto_cfg(hide(not(windows))))]

0 commit comments

Comments
 (0)