Skip to content

Commit d88598f

Browse files
Emit an error if shww/hide the same cfg on a same item
1 parent 392b710 commit d88598f

File tree

1 file changed

+44
-6
lines changed

1 file changed

+44
-6
lines changed

src/librustdoc/clean/types.rs

+44-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use arrayvec::ArrayVec;
77
use rustc_abi::{ExternAbi, VariantIdx};
88
use rustc_ast::ast::{LitKind, MetaItemInner, MetaItemKind};
99
use rustc_attr_parsing::{AttributeKind, ConstStability, Deprecation, Stability, StableSince};
10-
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
10+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
1111
use rustc_hir::def::{CtorKind, DefKind, Res};
1212
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
1313
use rustc_hir::lang_items::LangItem;
@@ -1030,17 +1030,50 @@ impl Default for CfgInfo {
10301030
}
10311031
}
10321032

1033-
fn handle_auto_cfg_hide_show(cfg_info: &mut CfgInfo, sub_attr: &MetaItemInner, is_show: bool) {
1033+
fn show_hide_show_conflict_error(
1034+
tcx: TyCtxt<'_>,
1035+
item_span: rustc_span::Span,
1036+
previous: rustc_span::Span,
1037+
) {
1038+
tcx.sess
1039+
.dcx()
1040+
.struct_span_err(
1041+
item_span,
1042+
format!(
1043+
"same `cfg` was in `auto_cfg(hide(...))` and `auto_cfg(show(...))` on the same item"
1044+
),
1045+
)
1046+
.span_note(previous, "first change was here");
1047+
}
1048+
1049+
fn handle_auto_cfg_hide_show(
1050+
tcx: TyCtxt<'_>,
1051+
cfg_info: &mut CfgInfo,
1052+
sub_attr: &MetaItemInner,
1053+
is_show: bool,
1054+
new_show_attrs: &mut FxHashMap<(Symbol, Option<Symbol>), rustc_span::Span>,
1055+
new_hide_attrs: &mut FxHashMap<(Symbol, Option<Symbol>), rustc_span::Span>,
1056+
) {
10341057
if let MetaItemInner::MetaItem(item) = sub_attr
10351058
&& let MetaItemKind::List(items) = &item.kind
10361059
{
10371060
for item in items {
1038-
// Errors should already have been reported in `rustc_passes::check_attr`.
1039-
if let Ok(cfg) = Cfg::parse(item) {
1061+
// Cfg parsing errors should already have been reported in `rustc_passes::check_attr`.
1062+
if let Ok(Cfg::Cfg(key, value)) = Cfg::parse(item) {
10401063
if is_show {
1041-
cfg_info.hidden_cfg.remove(&cfg);
1064+
if let Some(span) = new_hide_attrs.get(&(key, value)) {
1065+
show_hide_show_conflict_error(tcx, item.span(), *span);
1066+
} else {
1067+
new_hide_attrs.insert((key, value), item.span());
1068+
}
1069+
cfg_info.hidden_cfg.remove(&Cfg::Cfg(key, value));
10421070
} else {
1043-
cfg_info.hidden_cfg.insert(cfg);
1071+
if let Some(span) = new_show_attrs.get(&(key, value)) {
1072+
show_hide_show_conflict_error(tcx, item.span(), *span);
1073+
} else {
1074+
new_show_attrs.insert((key, value), item.span());
1075+
}
1076+
cfg_info.hidden_cfg.insert(Cfg::Cfg(key, value));
10441077
}
10451078
}
10461079
}
@@ -1061,6 +1094,8 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
10611094
Some(item)
10621095
}
10631096

1097+
let mut new_show_attrs = FxHashMap::default();
1098+
let mut new_hide_attrs = FxHashMap::default();
10641099
let mut enable_auto_cfg = true;
10651100
let mut cfg = Cfg::True;
10661101

@@ -1172,9 +1207,12 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
11721207
&& (ident.name == sym::show || ident.name == sym::hide)
11731208
{
11741209
handle_auto_cfg_hide_show(
1210+
tcx,
11751211
cfg_info,
11761212
&sub_attr,
11771213
ident.name == sym::show,
1214+
&mut new_show_attrs,
1215+
&mut new_hide_attrs,
11781216
);
11791217
}
11801218
}

0 commit comments

Comments
 (0)