Clean up doc attributes check before adding more

This commit is contained in:
Guillaume Gomez 2020-12-01 14:11:33 +01:00
parent 92e4fb0732
commit 5a228263b8

View file

@ -78,7 +78,7 @@ impl CheckAttrVisitor<'tcx> {
} else if self.tcx.sess.check_name(attr, sym::track_caller) { } else if self.tcx.sess.check_name(attr, sym::track_caller) {
self.check_track_caller(&attr.span, attrs, span, target) self.check_track_caller(&attr.span, attrs, span, target)
} else if self.tcx.sess.check_name(attr, sym::doc) { } else if self.tcx.sess.check_name(attr, sym::doc) {
self.check_doc_alias(attr, hir_id, target) self.check_doc_attrs(attr, hir_id, target)
} else if self.tcx.sess.check_name(attr, sym::no_link) { } else if self.tcx.sess.check_name(attr, sym::no_link) {
self.check_no_link(&attr, span, target) self.check_no_link(&attr, span, target)
} else if self.tcx.sess.check_name(attr, sym::export_name) { } else if self.tcx.sess.check_name(attr, sym::export_name) {
@ -297,33 +297,24 @@ impl CheckAttrVisitor<'tcx> {
.emit(); .emit();
} }
fn check_doc_alias(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool { fn check_doc_alias(&self, meta: &NestedMetaItem, hir_id: HirId, target: Target) -> bool {
if let Some(mi) = attr.meta() {
if let Some(list) = mi.meta_item_list() {
for meta in list {
if meta.has_name(sym::alias) {
if !meta.is_value_str() { if !meta.is_value_str() {
self.doc_alias_str_error(meta); self.doc_alias_str_error(meta);
return false; return false;
} }
let doc_alias = let doc_alias = meta.value_str().map(|s| s.to_string()).unwrap_or_else(String::new);
meta.value_str().map(|s| s.to_string()).unwrap_or_else(String::new);
if doc_alias.is_empty() { if doc_alias.is_empty() {
self.doc_alias_str_error(meta); self.doc_alias_str_error(meta);
return false; return false;
} }
if let Some(c) = doc_alias if let Some(c) =
.chars() doc_alias.chars().find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' '))
.find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' '))
{ {
self.tcx self.tcx
.sess .sess
.struct_span_err( .struct_span_err(
meta.name_value_literal_span().unwrap_or_else(|| meta.span()), meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
&format!( &format!("{:?} character isn't allowed in `#[doc(alias = \"...\")]`", c,),
"{:?} character isn't allowed in `#[doc(alias = \"...\")]`",
c,
),
) )
.emit(); .emit();
return false; return false;
@ -371,18 +362,41 @@ impl CheckAttrVisitor<'tcx> {
.emit(); .emit();
return false; return false;
} }
true
}
fn check_attr_crate_level(
&self,
meta: &NestedMetaItem,
hir_id: HirId,
attr_name: &str,
) -> bool {
if CRATE_HIR_ID == hir_id { if CRATE_HIR_ID == hir_id {
self.tcx self.tcx
.sess .sess
.struct_span_err( .struct_span_err(
meta.span(), meta.span(),
"`#![doc(alias = \"...\")]` isn't allowed as a crate \ &format!(
level attribute", "`#![doc({} = \"...\")]` isn't allowed as a crate level attribute",
attr_name,
),
) )
.emit(); .emit();
return false; return false;
} }
} }
fn check_doc_attrs(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
if let Some(mi) = attr.meta() {
if let Some(list) = mi.meta_item_list() {
for meta in list {
if meta.has_name(sym::alias) {
if !self.check_attr_crate_level(meta, hir_id, "alias")
|| !self.check_doc_alias(meta, hir_id, target)
{
return false;
}
}
} }
} }
} }