Skip to content

Commit 5a22826

Browse files
Clean up doc attributes check before adding more
1 parent 92e4fb0 commit 5a22826

File tree

1 file changed

+93
-79
lines changed

1 file changed

+93
-79
lines changed

compiler/rustc_passes/src/check_attr.rs

Lines changed: 93 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl CheckAttrVisitor<'tcx> {
7878
} else if self.tcx.sess.check_name(attr, sym::track_caller) {
7979
self.check_track_caller(&attr.span, attrs, span, target)
8080
} else if self.tcx.sess.check_name(attr, sym::doc) {
81-
self.check_doc_alias(attr, hir_id, target)
81+
self.check_doc_attrs(attr, hir_id, target)
8282
} else if self.tcx.sess.check_name(attr, sym::no_link) {
8383
self.check_no_link(&attr, span, target)
8484
} else if self.tcx.sess.check_name(attr, sym::export_name) {
@@ -297,89 +297,103 @@ impl CheckAttrVisitor<'tcx> {
297297
.emit();
298298
}
299299

300-
fn check_doc_alias(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
300+
fn check_doc_alias(&self, meta: &NestedMetaItem, hir_id: HirId, target: Target) -> bool {
301+
if !meta.is_value_str() {
302+
self.doc_alias_str_error(meta);
303+
return false;
304+
}
305+
let doc_alias = meta.value_str().map(|s| s.to_string()).unwrap_or_else(String::new);
306+
if doc_alias.is_empty() {
307+
self.doc_alias_str_error(meta);
308+
return false;
309+
}
310+
if let Some(c) =
311+
doc_alias.chars().find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' '))
312+
{
313+
self.tcx
314+
.sess
315+
.struct_span_err(
316+
meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
317+
&format!("{:?} character isn't allowed in `#[doc(alias = \"...\")]`", c,),
318+
)
319+
.emit();
320+
return false;
321+
}
322+
if doc_alias.starts_with(' ') || doc_alias.ends_with(' ') {
323+
self.tcx
324+
.sess
325+
.struct_span_err(
326+
meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
327+
"`#[doc(alias = \"...\")]` cannot start or end with ' '",
328+
)
329+
.emit();
330+
return false;
331+
}
332+
if let Some(err) = match target {
333+
Target::Impl => Some("implementation block"),
334+
Target::ForeignMod => Some("extern block"),
335+
Target::AssocTy => {
336+
let parent_hir_id = self.tcx.hir().get_parent_item(hir_id);
337+
let containing_item = self.tcx.hir().expect_item(parent_hir_id);
338+
if Target::from_item(containing_item) == Target::Impl {
339+
Some("type alias in implementation block")
340+
} else {
341+
None
342+
}
343+
}
344+
Target::AssocConst => {
345+
let parent_hir_id = self.tcx.hir().get_parent_item(hir_id);
346+
let containing_item = self.tcx.hir().expect_item(parent_hir_id);
347+
// We can't link to trait impl's consts.
348+
let err = "associated constant in trait implementation block";
349+
match containing_item.kind {
350+
ItemKind::Impl { of_trait: Some(_), .. } => Some(err),
351+
_ => None,
352+
}
353+
}
354+
_ => None,
355+
} {
356+
self.tcx
357+
.sess
358+
.struct_span_err(
359+
meta.span(),
360+
&format!("`#[doc(alias = \"...\")]` isn't allowed on {}", err),
361+
)
362+
.emit();
363+
return false;
364+
}
365+
true
366+
}
367+
368+
fn check_attr_crate_level(
369+
&self,
370+
meta: &NestedMetaItem,
371+
hir_id: HirId,
372+
attr_name: &str,
373+
) -> bool {
374+
if CRATE_HIR_ID == hir_id {
375+
self.tcx
376+
.sess
377+
.struct_span_err(
378+
meta.span(),
379+
&format!(
380+
"`#![doc({} = \"...\")]` isn't allowed as a crate level attribute",
381+
attr_name,
382+
),
383+
)
384+
.emit();
385+
return false;
386+
}
387+
}
388+
389+
fn check_doc_attrs(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
301390
if let Some(mi) = attr.meta() {
302391
if let Some(list) = mi.meta_item_list() {
303392
for meta in list {
304393
if meta.has_name(sym::alias) {
305-
if !meta.is_value_str() {
306-
self.doc_alias_str_error(meta);
307-
return false;
308-
}
309-
let doc_alias =
310-
meta.value_str().map(|s| s.to_string()).unwrap_or_else(String::new);
311-
if doc_alias.is_empty() {
312-
self.doc_alias_str_error(meta);
313-
return false;
314-
}
315-
if let Some(c) = doc_alias
316-
.chars()
317-
.find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' '))
394+
if !self.check_attr_crate_level(meta, hir_id, "alias")
395+
|| !self.check_doc_alias(meta, hir_id, target)
318396
{
319-
self.tcx
320-
.sess
321-
.struct_span_err(
322-
meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
323-
&format!(
324-
"{:?} character isn't allowed in `#[doc(alias = \"...\")]`",
325-
c,
326-
),
327-
)
328-
.emit();
329-
return false;
330-
}
331-
if doc_alias.starts_with(' ') || doc_alias.ends_with(' ') {
332-
self.tcx
333-
.sess
334-
.struct_span_err(
335-
meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
336-
"`#[doc(alias = \"...\")]` cannot start or end with ' '",
337-
)
338-
.emit();
339-
return false;
340-
}
341-
if let Some(err) = match target {
342-
Target::Impl => Some("implementation block"),
343-
Target::ForeignMod => Some("extern block"),
344-
Target::AssocTy => {
345-
let parent_hir_id = self.tcx.hir().get_parent_item(hir_id);
346-
let containing_item = self.tcx.hir().expect_item(parent_hir_id);
347-
if Target::from_item(containing_item) == Target::Impl {
348-
Some("type alias in implementation block")
349-
} else {
350-
None
351-
}
352-
}
353-
Target::AssocConst => {
354-
let parent_hir_id = self.tcx.hir().get_parent_item(hir_id);
355-
let containing_item = self.tcx.hir().expect_item(parent_hir_id);
356-
// We can't link to trait impl's consts.
357-
let err = "associated constant in trait implementation block";
358-
match containing_item.kind {
359-
ItemKind::Impl { of_trait: Some(_), .. } => Some(err),
360-
_ => None,
361-
}
362-
}
363-
_ => None,
364-
} {
365-
self.tcx
366-
.sess
367-
.struct_span_err(
368-
meta.span(),
369-
&format!("`#[doc(alias = \"...\")]` isn't allowed on {}", err),
370-
)
371-
.emit();
372-
return false;
373-
}
374-
if CRATE_HIR_ID == hir_id {
375-
self.tcx
376-
.sess
377-
.struct_span_err(
378-
meta.span(),
379-
"`#![doc(alias = \"...\")]` isn't allowed as a crate \
380-
level attribute",
381-
)
382-
.emit();
383397
return false;
384398
}
385399
}

0 commit comments

Comments
 (0)