Skip to content

Commit 3b6e4a8

Browse files
Move #[doc(alias)] attribute checks in rustc
1 parent 51db2a6 commit 3b6e4a8

File tree

5 files changed

+92
-63
lines changed

5 files changed

+92
-63
lines changed

src/librustc_passes/check_attr.rs

+28-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl CheckAttrVisitor<'tcx> {
7070
} else if self.tcx.sess.check_name(attr, sym::track_caller) {
7171
self.check_track_caller(&attr.span, attrs, span, target)
7272
} else if self.tcx.sess.check_name(attr, sym::doc) {
73-
self.check_doc_alias(attr)
73+
self.check_doc_alias(attr, hir_id, target)
7474
} else {
7575
true
7676
};
@@ -217,7 +217,7 @@ impl CheckAttrVisitor<'tcx> {
217217
}
218218
}
219219

220-
fn check_doc_alias(&self, attr: &Attribute) -> bool {
220+
fn check_doc_alias(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
221221
if let Some(mi) = attr.meta() {
222222
if let Some(list) = mi.meta_item_list() {
223223
for meta in list {
@@ -238,6 +238,32 @@ impl CheckAttrVisitor<'tcx> {
238238
.emit();
239239
return false;
240240
}
241+
if let Some(err) = match target {
242+
Target::Impl => Some("implementation block"),
243+
Target::ForeignMod => Some("extern block"),
244+
Target::AssocConst | Target::AssocTy => {
245+
let parent_hir_id = self.tcx.hir().get_parent_item(hir_id);
246+
let containing_item = self.tcx.hir().expect_item(parent_hir_id);
247+
if Target::from_item(containing_item) == Target::Impl {
248+
Some(if target == Target::AssocConst {
249+
"const in implementation block"
250+
} else {
251+
"type alias in implementation block"
252+
})
253+
} else {
254+
None
255+
}
256+
}
257+
_ => None,
258+
} {
259+
self.tcx
260+
.sess
261+
.struct_span_err(
262+
meta.span(),
263+
&format!("`#[doc(alias = \"...\")]` isn't allowed on {}", err,),
264+
)
265+
.emit();
266+
}
241267
}
242268
}
243269
}

src/librustdoc/visit_ast.rs

+2-55
Original file line numberDiff line numberDiff line change
@@ -31,27 +31,6 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec<String> {
3131
std::iter::once(crate_name).chain(relative).collect()
3232
}
3333

34-
fn check_doc_alias_attrs(
35-
attrs: &[ast::Attribute],
36-
item_kind: &str,
37-
diagnostic: &::rustc_errors::Handler,
38-
) {
39-
for attr in attrs {
40-
if let Some(attr) = attr.meta() {
41-
if let Some(list) = attr.meta_item_list() {
42-
for meta in list {
43-
if meta.check_name(sym::alias) {
44-
diagnostic.span_err(
45-
meta.span(),
46-
&format!("`#[doc(alias = \"...\")]` isn't allowed on {}", item_kind),
47-
);
48-
}
49-
}
50-
}
51-
}
52-
}
53-
}
54-
5534
// Also, is there some reason that this doesn't use the 'visit'
5635
// framework from syntax?.
5736

@@ -408,7 +387,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
408387

409388
match item.kind {
410389
hir::ItemKind::ForeignMod(ref fm) => {
411-
check_doc_alias_attrs(&item.attrs, "extern block", self.cx.sess().diagnostic());
412390
for item in fm.items {
413391
self.visit_foreign_item(item, None, om);
414392
}
@@ -583,22 +561,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
583561
self_ty,
584562
ref items,
585563
} => {
586-
check_doc_alias_attrs(
587-
&item.attrs,
588-
"implementation block",
589-
self.cx.sess().diagnostic(),
590-
);
591564
// Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
592565
// them up regardless of where they're located.
593566
if !self.inlining && of_trait.is_none() {
594-
let items = items
595-
.iter()
596-
.map(|item| {
597-
let item = self.cx.tcx.hir().impl_item(item.id);
598-
self.check_impl_doc_alias_attr(item);
599-
item
600-
})
601-
.collect();
567+
let items =
568+
items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect();
602569
let i = Impl {
603570
unsafety,
604571
polarity,
@@ -614,31 +581,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
614581
vis: &item.vis,
615582
};
616583
om.impls.push(i);
617-
} else if of_trait.is_some() {
618-
for item in items.iter() {
619-
self.check_impl_doc_alias_attr(self.cx.tcx.hir().impl_item(item.id));
620-
}
621584
}
622585
}
623586
}
624587
}
625588

626-
fn check_impl_doc_alias_attr(&self, item: &hir::ImplItem<'_>) {
627-
match item.kind {
628-
hir::ImplItemKind::Const(_, _) => check_doc_alias_attrs(
629-
&item.attrs,
630-
"const in implementation block",
631-
self.cx.sess().diagnostic(),
632-
),
633-
hir::ImplItemKind::TyAlias(_) => check_doc_alias_attrs(
634-
&item.attrs,
635-
"type alias in implementation block",
636-
self.cx.sess().diagnostic(),
637-
),
638-
hir::ImplItemKind::Fn(_, _) => {}
639-
}
640-
}
641-
642589
fn visit_foreign_item(
643590
&mut self,
644591
item: &'tcx hir::ForeignItem<'_>,

src/test/rustdoc-ui/check-doc-alias-attr-location.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ error: `#[doc(alias = "...")]` isn't allowed on implementation block
1010
LL | #[doc(alias = "bar")]
1111
| ^^^^^^^^^^^^^
1212

13-
error: `#[doc(alias = "...")]` isn't allowed on const in implementation block
14-
--> $DIR/check-doc-alias-attr-location.rs:14:11
15-
|
16-
LL | #[doc(alias = "const")]
17-
| ^^^^^^^^^^^^^^^
18-
1913
error: `#[doc(alias = "...")]` isn't allowed on implementation block
2014
--> $DIR/check-doc-alias-attr-location.rs:18:7
2115
|
2216
LL | #[doc(alias = "foobar")]
2317
| ^^^^^^^^^^^^^^^^
2418

19+
error: `#[doc(alias = "...")]` isn't allowed on const in implementation block
20+
--> $DIR/check-doc-alias-attr-location.rs:14:11
21+
|
22+
LL | #[doc(alias = "const")]
23+
| ^^^^^^^^^^^^^^^
24+
2525
error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block
2626
--> $DIR/check-doc-alias-attr-location.rs:20:11
2727
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![crate_type="lib"]
2+
#![feature(doc_alias)]
3+
4+
pub struct Bar;
5+
pub trait Foo {
6+
type X;
7+
fn foo() -> Self::X;
8+
}
9+
10+
#[doc(alias = "foo")] //~ ERROR
11+
extern {}
12+
13+
#[doc(alias = "bar")] //~ ERROR
14+
impl Bar {
15+
#[doc(alias = "const")] //~ ERROR
16+
const A: u32 = 0;
17+
}
18+
19+
#[doc(alias = "foobar")] //~ ERROR
20+
impl Foo for Bar {
21+
#[doc(alias = "assoc")] //~ ERROR
22+
type X = i32;
23+
fn foo() -> Self::X { 0 }
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
error: `#[doc(alias = "...")]` isn't allowed on extern block
2+
--> $DIR/check-doc-alias-attr-location.rs:10:7
3+
|
4+
LL | #[doc(alias = "foo")]
5+
| ^^^^^^^^^^^^^
6+
7+
error: `#[doc(alias = "...")]` isn't allowed on implementation block
8+
--> $DIR/check-doc-alias-attr-location.rs:13:7
9+
|
10+
LL | #[doc(alias = "bar")]
11+
| ^^^^^^^^^^^^^
12+
13+
error: `#[doc(alias = "...")]` isn't allowed on implementation block
14+
--> $DIR/check-doc-alias-attr-location.rs:19:7
15+
|
16+
LL | #[doc(alias = "foobar")]
17+
| ^^^^^^^^^^^^^^^^
18+
19+
error: `#[doc(alias = "...")]` isn't allowed on const in implementation block
20+
--> $DIR/check-doc-alias-attr-location.rs:15:11
21+
|
22+
LL | #[doc(alias = "const")]
23+
| ^^^^^^^^^^^^^^^
24+
25+
error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block
26+
--> $DIR/check-doc-alias-attr-location.rs:21:11
27+
|
28+
LL | #[doc(alias = "assoc")]
29+
| ^^^^^^^^^^^^^^^
30+
31+
error: aborting due to 5 previous errors
32+

0 commit comments

Comments
 (0)