about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2020-08-01 17:37:30 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2020-08-11 23:21:06 +0200
commit3b6e4a84f92995f75cd2ab26b9b15eb508f85336 (patch)
tree451ee6282f0c5989c366e003db5456a1dfe9a087 /src
parent51db2a65dd2fd9e1492a169bff424c0eae258517 (diff)
downloadrust-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.rs30
-rw-r--r--src/librustdoc/visit_ast.rs57
-rw-r--r--src/test/rustdoc-ui/check-doc-alias-attr-location.stderr12
-rw-r--r--src/test/ui/check-doc-alias-attr-location.rs24
-rw-r--r--src/test/ui/check-doc-alias-attr-location.stderr32
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
+