Skip to content

Commit 230486d

Browse files
Remove doc_cfg show/hide conflict error and correctly handle values(any())
1 parent d38a2c9 commit 230486d

6 files changed

Lines changed: 209 additions & 219 deletions

File tree

compiler/rustc_attr_parsing/src/attributes/doc.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -329,17 +329,17 @@ impl DocParser {
329329
kind: LitKind::Str(symbol, _),
330330
span,
331331
..
332-
}) => match &mut cfg_values.values {
333-
DocCfgHideShowValue::Any(any_span) => {
332+
}) => match &mut cfg_values {
333+
DocCfgHideShow::Any(any_span) => {
334334
cx.emit_lint(
335335
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
336336
DocAutoCfgHideShowValuesMix { value_span: *span },
337337
*any_span,
338338
);
339339
}
340-
DocCfgHideShowValue::List(symbols) => {
340+
DocCfgHideShow::List(symbols) => {
341341
if values_set.insert(symbol) {
342-
symbols.push((*symbol, *span));
342+
symbols.push(DocCfgHideShowValue::new(*symbol, *span));
343343
}
344344
}
345345
},
@@ -358,19 +358,19 @@ impl DocParser {
358358
&& list.mixed().count() == 0
359359
{
360360
if ident.name == sym::any {
361-
if let DocCfgHideShowValue::List(values) = &cfg_values.values
362-
&& let Some((_, span)) = values.first()
361+
if let DocCfgHideShow::List(values) = &cfg_values
362+
&& let Some(value) = values.first()
363363
{
364364
cx.emit_lint(
365365
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
366-
DocAutoCfgHideShowValuesMix { value_span: *span },
366+
DocAutoCfgHideShowValuesMix { value_span: value.span },
367367
sub_item.span(),
368368
);
369369
} else {
370-
cfg_values.values = DocCfgHideShowValue::Any(sub_item.span());
370+
cfg_values.merge_with(&DocCfgHideShow::Any(sub_item.span()));
371371
}
372372
} else {
373-
cfg_values.only_key = Some(sub_item.span());
373+
cfg_values.push_none(sub_item.span());
374374
}
375375
} else {
376376
cx.emit_lint(

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 38 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -515,98 +515,68 @@ pub enum HideOrShow {
515515
Show,
516516
}
517517

518-
#[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute, PartialEq)]
519-
pub enum DocCfgHideShowValue {
520-
Any(Span),
521-
List(ThinVec<(Symbol, Span)>),
518+
#[derive(Clone, Copy, Debug, StableHash, Encodable, Decodable, PrintAttribute, PartialEq)]
519+
pub struct DocCfgHideShowValue {
520+
pub span: Span,
521+
/// If `value` is `None`, then it's a `none()` value.
522+
pub value: Option<Symbol>,
522523
}
523524

524-
#[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)]
525-
pub struct DocCfgHideShow {
526-
/// If `Some`, then `cfg` without values (like `cfg(windows)`) will be shown/hidden.
527-
/// The `Span` comes from where this value was set.
528-
pub only_key: Option<Span>,
529-
/// The values of this `cfg` to shown/hidden.
530-
pub values: DocCfgHideShowValue,
525+
impl DocCfgHideShowValue {
526+
pub fn new(value: Symbol, span: Span) -> Self {
527+
Self { span, value: Some(value) }
528+
}
529+
530+
pub fn new_none(span: Span) -> Self {
531+
Self { span, value: None }
532+
}
533+
}
534+
535+
#[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute, PartialEq)]
536+
pub enum DocCfgHideShow {
537+
Any(Span),
538+
List(ThinVec<DocCfgHideShowValue>),
531539
}
532540

533541
impl DocCfgHideShow {
534542
pub fn new() -> Self {
535-
Self { only_key: None, values: DocCfgHideShowValue::List(ThinVec::new()) }
543+
Self::List(ThinVec::new())
536544
}
537545

538546
pub fn new_with_only_key(span: Span) -> Self {
539-
Self { only_key: Some(span), values: DocCfgHideShowValue::List(ThinVec::new()) }
547+
let mut values = ThinVec::with_capacity(1);
548+
values.push(DocCfgHideShowValue { span, value: None });
549+
Self::List(values)
540550
}
541551

542-
pub fn merge_with(&mut self, other: &Self) {
543-
if self.only_key.is_none()
544-
&& let Some(span) = other.only_key
552+
pub fn push_none(&mut self, span: Span) {
553+
if let Self::List(values) = self
554+
&& !values.iter().any(|v| v.value.is_none())
545555
{
546-
self.only_key = Some(span);
556+
values.push(DocCfgHideShowValue { span, value: None });
547557
}
548-
match (&mut self.values, &other.values) {
549-
(DocCfgHideShowValue::Any(_), DocCfgHideShowValue::Any(_)) => {
558+
}
559+
560+
pub fn merge_with(&mut self, other: &Self) {
561+
match (self, other) {
562+
(Self::Any(_), Self::Any(_) | Self::List(_)) => {
550563
// Nothing to do.
551564
}
552-
(_, DocCfgHideShowValue::Any(span)) => {
565+
(s, Self::Any(span)) => {
553566
// We "upgrade" the list values to "all".
554-
self.values = DocCfgHideShowValue::Any(*span);
555-
}
556-
(DocCfgHideShowValue::List(values), DocCfgHideShowValue::List(other_values)) => {
557-
// Having duplicates is not an issue, we simply ignore them. Would be more
558-
// convenient to have a `set` type though. T_T
559-
for (other_symbol, other_span) in other_values {
560-
if !values.iter().any(|(symbol, _)| symbol == other_symbol) {
561-
values.push((*other_symbol, *other_span));
562-
}
563-
}
567+
*s = Self::Any(*span);
564568
}
565-
(DocCfgHideShowValue::Any(_), DocCfgHideShowValue::List(_)) => {
566-
// Nothing to do here either, we already accept all values.
567-
}
568-
}
569-
}
570-
571-
pub fn update_with(&mut self, other: &Self) {
572-
if self.only_key.is_none()
573-
&& let Some(span) = other.only_key
574-
{
575-
self.only_key = Some(span);
576-
}
577-
match (&mut self.values, &other.values) {
578-
(DocCfgHideShowValue::Any(_), _) => {}
579-
(DocCfgHideShowValue::List(_), DocCfgHideShowValue::Any(span)) => {
580-
self.values = DocCfgHideShowValue::Any(*span);
581-
}
582-
(DocCfgHideShowValue::List(values), DocCfgHideShowValue::List(other_values)) => {
569+
(Self::List(values), Self::List(other_values)) => {
583570
// Having duplicates is not an issue, we simply ignore them. Would be more
584571
// convenient to have a `set` type though. T_T
585-
for (other_symbol, other_span) in other_values {
586-
if !values.iter().any(|(symbol, _)| symbol == other_symbol) {
587-
values.push((*other_symbol, *other_span));
572+
for other in other_values {
573+
if !values.iter().any(|value| value.value == other.value) {
574+
values.push(*other);
588575
}
589576
}
590577
}
591578
}
592579
}
593-
594-
pub fn remove_overlap(&mut self, other: &Self) {
595-
if other.only_key.is_some() {
596-
self.only_key = None;
597-
}
598-
match (&mut self.values, &other.values) {
599-
(_, DocCfgHideShowValue::Any(_)) => {
600-
self.values = DocCfgHideShowValue::List(ThinVec::new());
601-
}
602-
(DocCfgHideShowValue::Any(_), DocCfgHideShowValue::List(values)) => {
603-
self.values = DocCfgHideShowValue::List(values.clone());
604-
}
605-
(DocCfgHideShowValue::List(current), DocCfgHideShowValue::List(values)) => {
606-
current.retain(|(name, _)| !values.iter().any(|(other, _)| other == name));
607-
}
608-
}
609-
}
610580
}
611581

612582
#[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)]

0 commit comments

Comments
 (0)