Skip to content

Commit

Permalink
Auto merge of #74098 - GuillaumeGomez:doc-alias-checks, r=ollie27
Browse files Browse the repository at this point in the history
Doc alias checks: ensure only items appearing in search index can use it

Following the discussion in #73721, I added checks to ensure that only items appearing in the search are allowed to have doc alias.

r? @ollie27
  • Loading branch information
bors committed Aug 19, 2020
2 parents 11a44ad + fc6fb3f commit e7f6ed1
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 9 deletions.
26 changes: 24 additions & 2 deletions src/librustc_passes/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down Expand Up @@ -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 {
Expand All @@ -238,6 +238,28 @@ impl CheckAttrVisitor<'tcx> {
.emit();
return false;
}
if let Some(err) = match target {
Target::Impl => Some("implementation block"),
Target::ForeignMod => Some("extern block"),
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("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();
}
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,10 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
sess.time("missing_docs", || {
rustc_lint::check_crate(tcx, rustc_lint::builtin::MissingDoc::new);
});
for &module in tcx.hir().krate().modules.keys() {
let local_def_id = tcx.hir().local_def_id(module);
tcx.ensure().check_mod_attrs(local_def_id);
}

let access_levels = tcx.privacy_access_levels(LOCAL_CRATE);
// Convert from a HirId set to a DefId set since we don't always have easy access
Expand Down
18 changes: 15 additions & 3 deletions src/test/rustdoc-js/doc-alias.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const QUERY = [
'StructFieldItem',
'StructMethodItem',
'ImplTraitItem',
'ImplAssociatedConstItem',
'StructImplConstItem',
'ImplTraitFunction',
'EnumItem',
'VariantItem',
Expand Down Expand Up @@ -64,8 +64,16 @@ const EXPECTED = [
'others': [],
},
{
// ImplAssociatedConstItem
'others': [],
// StructImplConstItem
'others': [
{
'path': 'doc_alias::Struct',
'name': 'ImplConstItem',
'alias': 'StructImplConstItem',
'href': '../doc_alias/struct.Struct.html#associatedconstant.ImplConstItem',
'is_alias': true
},
],
},
{
'others': [
Expand Down Expand Up @@ -197,6 +205,10 @@ const EXPECTED = [
'href': '../doc_alias/constant.Const.html',
'is_alias': true
},
{
'path': 'doc_alias::Struct',
'name': 'ImplConstItem',
},
],
},
{
Expand Down
6 changes: 2 additions & 4 deletions src/test/rustdoc-js/doc-alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ pub struct Struct {
}

impl Struct {
#[doc(alias = "StructImplConstItem")]
pub const ImplConstItem: i32 = 0;
#[doc(alias = "StructMethodItem")]
pub fn method(&self) {}
}

impl Trait for Struct {
// Shouldn't be listed in aliases!
#[doc(alias = "ImplTraitItem")]
type Target = u32;
// Shouldn't be listed in aliases!
#[doc(alias = "ImplAssociatedConstItem")]
const AssociatedConst: i32 = 12;

#[doc(alias = "ImplTraitFunction")]
Expand Down
23 changes: 23 additions & 0 deletions src/test/rustdoc-ui/check-doc-alias-attr-location.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![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")]
pub const A: u32 = 0;
}

#[doc(alias = "foobar")] //~ ERROR
impl Foo for Bar {
#[doc(alias = "assoc")] //~ ERROR
type X = i32;
fn foo() -> Self::X { 0 }
}
26 changes: 26 additions & 0 deletions src/test/rustdoc-ui/check-doc-alias-attr-location.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: `#[doc(alias = "...")]` isn't allowed on extern block
--> $DIR/check-doc-alias-attr-location.rs:9:7
|
LL | #[doc(alias = "foo")]
| ^^^^^^^^^^^^^

error: `#[doc(alias = "...")]` isn't allowed on implementation block
--> $DIR/check-doc-alias-attr-location.rs:12:7
|
LL | #[doc(alias = "bar")]
| ^^^^^^^^^^^^^

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 type alias in implementation block
--> $DIR/check-doc-alias-attr-location.rs:20:11
|
LL | #[doc(alias = "assoc")]
| ^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors

10 changes: 10 additions & 0 deletions src/test/rustdoc-ui/check-doc-alias-attr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![crate_type = "lib"]
#![feature(doc_alias)]

#[doc(alias = "foo")] // ok!
pub struct Bar;

#[doc(alias)] //~ ERROR
#[doc(alias = 0)] //~ ERROR
#[doc(alias("bar"))] //~ ERROR
pub struct Foo;
20 changes: 20 additions & 0 deletions src/test/rustdoc-ui/check-doc-alias-attr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: doc alias attribute expects a string: #[doc(alias = "0")]
--> $DIR/check-doc-alias-attr.rs:7:7
|
LL | #[doc(alias)]
| ^^^^^

error: doc alias attribute expects a string: #[doc(alias = "0")]
--> $DIR/check-doc-alias-attr.rs:8:7
|
LL | #[doc(alias = 0)]
| ^^^^^^^^^

error: doc alias attribute expects a string: #[doc(alias = "0")]
--> $DIR/check-doc-alias-attr.rs:9:7
|
LL | #[doc(alias("bar"))]
| ^^^^^^^^^^^^

error: aborting due to 3 previous errors

24 changes: 24 additions & 0 deletions src/test/ui/check-doc-alias-attr-location.rs
Original file line number Diff line number Diff line change
@@ -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")]
const A: u32 = 0;
}

#[doc(alias = "foobar")] //~ ERROR
impl Foo for Bar {
#[doc(alias = "assoc")] //~ ERROR
type X = i32;
fn foo() -> Self::X { 0 }
}
26 changes: 26 additions & 0 deletions src/test/ui/check-doc-alias-attr-location.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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 type alias in implementation block
--> $DIR/check-doc-alias-attr-location.rs:21:11
|
LL | #[doc(alias = "assoc")]
| ^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors

0 comments on commit e7f6ed1

Please sign in to comment.