diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2020-08-01 17:37:30 +0200 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2020-08-11 23:21:06 +0200 |
| commit | 3b6e4a84f92995f75cd2ab26b9b15eb508f85336 (patch) | |
| tree | 451ee6282f0c5989c366e003db5456a1dfe9a087 /src | |
| parent | 51db2a65dd2fd9e1492a169bff424c0eae258517 (diff) | |
| download | rust-3b6e4a84f92995f75cd2ab26b9b15eb508f85336.tar.gz rust-3b6e4a84f92995f75cd2ab26b9b15eb508f85336.zip | |
Move #[doc(alias)] attribute checks in rustc
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_passes/check_attr.rs | 30 | ||||
| -rw-r--r-- | src/librustdoc/visit_ast.rs | 57 | ||||
| -rw-r--r-- | src/test/rustdoc-ui/check-doc-alias-attr-location.stderr | 12 | ||||
| -rw-r--r-- | src/test/ui/check-doc-alias-attr-location.rs | 24 | ||||
| -rw-r--r-- | src/test/ui/check-doc-alias-attr-location.stderr | 32 |
5 files changed, 92 insertions, 63 deletions
diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index d438fe35ff4..a729bb55110 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -70,7 +70,7 @@ impl CheckAttrVisitor<'tcx> { } else if self.tcx.sess.check_name(attr, sym::track_caller) { self.check_track_caller(&attr.span, attrs, span, target) } else if self.tcx.sess.check_name(attr, sym::doc) { - self.check_doc_alias(attr) + self.check_doc_alias(attr, hir_id, target) } else { true }; @@ -217,7 +217,7 @@ impl CheckAttrVisitor<'tcx> { } } - fn check_doc_alias(&self, attr: &Attribute) -> bool { + fn check_doc_alias(&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 { @@ -238,6 +238,32 @@ impl CheckAttrVisitor<'tcx> { .emit(); return false; } + if let Some(err) = match target { + Target::Impl => Some("implementation block"), + Target::ForeignMod => Some("extern block"), + Target::AssocConst | Target::AssocTy => { + let parent_hir_id = self.tcx.hir().get_parent_item(hir_id); + let containing_item = self.tcx.hir().expect_item(parent_hir_id); + if Target::from_item(containing_item) == Target::Impl { + Some(if target == Target::AssocConst { + "const in implementation block" + } else { + "type alias in implementation block" + }) + } else { + None + } + } + _ => None, + } { + self.tcx + .sess + .struct_span_err( + meta.span(), + &format!("`#[doc(alias = \"...\")]` isn't allowed on {}", err,), + ) + .emit(); + } } } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 4f347f2055e..cf57ffd0b4b 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -31,27 +31,6 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec<String> { std::iter::once(crate_name).chain(relative).collect() } -fn check_doc_alias_attrs( - attrs: &[ast::Attribute], - item_kind: &str, - diagnostic: &::rustc_errors::Handler, -) { - for attr in attrs { - if let Some(attr) = attr.meta() { - if let Some(list) = attr.meta_item_list() { - for meta in list { - if meta.check_name(sym::alias) { - diagnostic.span_err( - meta.span(), - &format!("`#[doc(alias = \"...\")]` isn't allowed on {}", item_kind), - ); - } - } - } - } - } -} - // Also, is there some reason that this doesn't use the 'visit' // framework from syntax?. @@ -408,7 +387,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { match item.kind { hir::ItemKind::ForeignMod(ref fm) => { - check_doc_alias_attrs(&item.attrs, "extern block", self.cx.sess().diagnostic()); for item in fm.items { self.visit_foreign_item(item, None, om); } @@ -583,22 +561,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self_ty, ref items, } => { - check_doc_alias_attrs( - &item.attrs, - "implementation block", - self.cx.sess().diagnostic(), - ); // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. if !self.inlining && of_trait.is_none() { - let items = items - .iter() - .map(|item| { - let item = self.cx.tcx.hir().impl_item(item.id); - self.check_impl_doc_alias_attr(item); - item - }) - .collect(); + let items = + items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect(); let i = Impl { unsafety, polarity, @@ -614,31 +581,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { vis: &item.vis, }; om.impls.push(i); - } else if of_trait.is_some() { - for item in items.iter() { - self.check_impl_doc_alias_attr(self.cx.tcx.hir().impl_item(item.id)); - } } } } } - fn check_impl_doc_alias_attr(&self, item: &hir::ImplItem<'_>) { - match item.kind { - hir::ImplItemKind::Const(_, _) => check_doc_alias_attrs( - &item.attrs, - "const in implementation block", - self.cx.sess().diagnostic(), - ), - hir::ImplItemKind::TyAlias(_) => check_doc_alias_attrs( - &item.attrs, - "type alias in implementation block", - self.cx.sess().diagnostic(), - ), - hir::ImplItemKind::Fn(_, _) => {} - } - } - fn visit_foreign_item( &mut self, item: &'tcx hir::ForeignItem<'_>, diff --git a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr index 5fe943debde..cc51101c164 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -10,18 +10,18 @@ error: `#[doc(alias = "...")]` isn't allowed on implementation block LL | #[doc(alias = "bar")] | ^^^^^^^^^^^^^ -error: `#[doc(alias = "...")]` isn't allowed on const in implementation block - --> $DIR/check-doc-alias-attr-location.rs:14:11 - | -LL | #[doc(alias = "const")] - | ^^^^^^^^^^^^^^^ - error: `#[doc(alias = "...")]` isn't allowed on implementation block --> $DIR/check-doc-alias-attr-location.rs:18:7 | LL | #[doc(alias = "foobar")] | ^^^^^^^^^^^^^^^^ +error: `#[doc(alias = "...")]` isn't allowed on const in implementation block + --> $DIR/check-doc-alias-attr-location.rs:14:11 + | +LL | #[doc(alias = "const")] + | ^^^^^^^^^^^^^^^ + error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block --> $DIR/check-doc-alias-attr-location.rs:20:11 | diff --git a/src/test/ui/check-doc-alias-attr-location.rs b/src/test/ui/check-doc-alias-attr-location.rs new file mode 100644 index 00000000000..9f0b1dcf44a --- /dev/null +++ b/src/test/ui/check-doc-alias-attr-location.rs @@ -0,0 +1,24 @@ +#![crate_type="lib"] +#![feature(doc_alias)] + +pub struct Bar; +pub trait Foo { + type X; + fn foo() -> Self::X; +} + +#[doc(alias = "foo")] //~ ERROR +extern {} + +#[doc(alias = "bar")] //~ ERROR +impl Bar { + #[doc(alias = "const")] //~ ERROR + const A: u32 = 0; +} + +#[doc(alias = "foobar")] //~ ERROR +impl Foo for Bar { + #[doc(alias = "assoc")] //~ ERROR + type X = i32; + fn foo() -> Self::X { 0 } +} diff --git a/src/test/ui/check-doc-alias-attr-location.stderr b/src/test/ui/check-doc-alias-attr-location.stderr new file mode 100644 index 00000000000..b4a0847a002 --- /dev/null +++ b/src/test/ui/check-doc-alias-attr-location.stderr @@ -0,0 +1,32 @@ +error: `#[doc(alias = "...")]` isn't allowed on extern block + --> $DIR/check-doc-alias-attr-location.rs:10:7 + | +LL | #[doc(alias = "foo")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:13:7 + | +LL | #[doc(alias = "bar")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:19:7 + | +LL | #[doc(alias = "foobar")] + | ^^^^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on const in implementation block + --> $DIR/check-doc-alias-attr-location.rs:15:11 + | +LL | #[doc(alias = "const")] + | ^^^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block + --> $DIR/check-doc-alias-attr-location.rs:21:11 + | +LL | #[doc(alias = "assoc")] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + |
