diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0257a63e50f..82562c3a92d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -398,47 +398,42 @@ impl CheckAttrVisitor<'tcx> { target: Target, is_list: bool, ) -> bool { + let tcx = self.tcx; + let err_fn = move |span: Span, msg: &str| { + tcx.sess.span_err( + span, + &format!( + "`#[doc(alias{})]` {}", + if is_list { "(\"...\")" } else { " = \"...\"" }, + msg, + ), + ); + false + }; if doc_alias.is_empty() { - self.tcx - .sess - .struct_span_err( - meta.name_value_literal_span().unwrap_or_else(|| meta.span()), - &format!( - "`#[doc(alias{})]` attribute cannot have empty value", - if is_list { "(\"...\")" } else { " = \"...\"" }, - ), - ) - .emit(); - return false; + return err_fn( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + "attribute cannot have empty value", + ); } if let Some(c) = doc_alias.chars().find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' ')) { - self.tcx - .sess - .struct_span_err( - meta.name_value_literal_span().unwrap_or_else(|| meta.span()), - &format!( - "{:?} character isn't allowed in `#[doc(alias{})]`", - c, - if is_list { "(\"...\")" } else { " = \"...\"" }, - ), - ) - .emit(); + self.tcx.sess.span_err( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + &format!( + "{:?} character isn't allowed in `#[doc(alias{})]`", + c, + if is_list { "(\"...\")" } else { " = \"...\"" }, + ), + ); return false; } if doc_alias.starts_with(' ') || doc_alias.ends_with(' ') { - self.tcx - .sess - .struct_span_err( - meta.name_value_literal_span().unwrap_or_else(|| meta.span()), - &format!( - "`#[doc(alias{})]` cannot start or end with ' '", - if is_list { "(\"...\")" } else { " = \"...\"" }, - ), - ) - .emit(); - return false; + return err_fn( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + "cannot start or end with ' '", + ); } if let Some(err) = match target { Target::Impl => Some("implementation block"), @@ -464,32 +459,11 @@ impl CheckAttrVisitor<'tcx> { } _ => None, } { - self.tcx - .sess - .struct_span_err( - meta.span(), - &format!( - "`#[doc(alias{})]` isn't allowed on {}", - if is_list { "(\"...\")" } else { " = \"...\"" }, - err, - ), - ) - .emit(); - return false; + return err_fn(meta.span(), &format!("isn't allowed on {}", err)); } let item_name = self.tcx.hir().name(hir_id); if &*item_name.as_str() == doc_alias { - self.tcx - .sess - .struct_span_err( - meta.span(), - &format!( - "`#[doc(alias{})]` is the same as the item's name", - if is_list { "(\"...\")" } else { " = \"...\"" }, - ), - ) - .emit(); - return false; + return err_fn(meta.span(), "is the same as the item's name"); } true } @@ -510,7 +484,7 @@ impl CheckAttrVisitor<'tcx> { .sess .struct_span_err( v.span(), - "`#[doc(alias(\"a\")]` expects string literals", + "`#[doc(alias(\"a\"))]` expects string literals", ) .emit(); errors += 1; @@ -521,7 +495,7 @@ impl CheckAttrVisitor<'tcx> { .sess .struct_span_err( v.span(), - "`#[doc(alias(\"a\")]` expects string literals", + "`#[doc(alias(\"a\"))]` expects string literals", ) .emit(); errors += 1; @@ -537,7 +511,7 @@ impl CheckAttrVisitor<'tcx> { .struct_span_err( meta.span(), "doc alias attribute expects a string `#[doc(alias = \"a\")]` or a list of \ - strings: `#[doc(alias(\"a\", \"b\")]`", + strings `#[doc(alias(\"a\", \"b\"))]`", ) .emit(); false diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index b67af484510..7608b485c5b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -911,24 +911,23 @@ impl Attributes { } crate fn get_doc_aliases(&self) -> FxHashSet { - self.other_attrs - .lists(sym::doc) - .filter(|a| a.has_name(sym::alias)) - .map(|a| { - if let Some(values) = a.meta_item_list() { - values - .iter() - .map(|l| match l.literal().unwrap().kind { - ast::LitKind::Str(s, _) => s.as_str().to_string(), - _ => unreachable!(), - }) - .collect::>() - } else { - vec![a.value_str().map(|s| s.to_string()).unwrap()] + let mut aliases = FxHashSet::default(); + + for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) { + if let Some(values) = attr.meta_item_list() { + for l in values { + match l.literal().unwrap().kind { + ast::LitKind::Str(s, _) => { + aliases.insert(s.as_str().to_string()); + } + _ => unreachable!(), + } } - }) - .flatten() - .collect::>() + } else { + aliases.insert(attr.value_str().map(|s| s.to_string()).unwrap()); + } + } + aliases } }