mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 16:15:03 +00:00
Auto merge of #43009 - GuillaumeGomez:unused-doc-comments, r=nrc
Throw errors when doc comments are added where they're unused #42617
This commit is contained in:
commit
53bf7903fa
13
src/Cargo.lock
generated
13
src/Cargo.lock
generated
@ -187,7 +187,7 @@ dependencies = [
|
||||
"curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -323,7 +323,7 @@ name = "crates-io"
|
||||
version = "0.11.0"
|
||||
dependencies = [
|
||||
"curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -436,6 +436,14 @@ dependencies = [
|
||||
"backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error-chain"
|
||||
version = "0.11.0-rc.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error_index_generator"
|
||||
version = "0.0.0"
|
||||
@ -2145,6 +2153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
|
||||
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
|
||||
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
|
||||
"checksum error-chain 0.11.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)" = "38d3a55d9a7a456748f2a3912c0941a5d9a68006eb15b3c3c9836b8420dc102d"
|
||||
"checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
|
||||
"checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c"
|
||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||
|
@ -892,6 +892,13 @@ impl Decl_ {
|
||||
DeclItem(_) => &[]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_local(&self) -> bool {
|
||||
match *self {
|
||||
Decl_::DeclLocal(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// represents one arm of a 'match'
|
||||
|
@ -458,10 +458,10 @@ impl<'tcx> RegionMaps {
|
||||
-> CodeExtent {
|
||||
if scope_a == scope_b { return scope_a; }
|
||||
|
||||
/// [1] The initial values for `a_buf` and `b_buf` are not used.
|
||||
/// The `ancestors_of` function will return some prefix that
|
||||
/// is re-initialized with new values (or else fallback to a
|
||||
/// heap-allocated vector).
|
||||
// [1] The initial values for `a_buf` and `b_buf` are not used.
|
||||
// The `ancestors_of` function will return some prefix that
|
||||
// is re-initialized with new values (or else fallback to a
|
||||
// heap-allocated vector).
|
||||
let mut a_buf: [CodeExtent; 32] = [scope_a /* [1] */; 32];
|
||||
let mut a_vec: Vec<CodeExtent> = vec![];
|
||||
let mut b_buf: [CodeExtent; 32] = [scope_b /* [1] */; 32];
|
||||
|
@ -722,6 +722,46 @@ impl EarlyLintPass for IllegalFloatLiteralPattern {
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub UNUSED_DOC_COMMENT,
|
||||
Warn,
|
||||
"detects doc comments that aren't used by rustdoc"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct UnusedDocComment;
|
||||
|
||||
impl LintPass for UnusedDocComment {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array![UNUSED_DOC_COMMENT]
|
||||
}
|
||||
}
|
||||
|
||||
impl UnusedDocComment {
|
||||
fn warn_if_doc<'a, 'tcx,
|
||||
I: Iterator<Item=&'a ast::Attribute>,
|
||||
C: LintContext<'tcx>>(&self, mut attrs: I, cx: &C) {
|
||||
if let Some(attr) = attrs.find(|a| a.is_value_str() && a.check_name("doc")) {
|
||||
cx.struct_span_lint(UNUSED_DOC_COMMENT, attr.span, "doc comment not used by rustdoc")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EarlyLintPass for UnusedDocComment {
|
||||
fn check_local(&mut self, cx: &EarlyContext, decl: &ast::Local) {
|
||||
self.warn_if_doc(decl.attrs.iter(), cx);
|
||||
}
|
||||
|
||||
fn check_arm(&mut self, cx: &EarlyContext, arm: &ast::Arm) {
|
||||
self.warn_if_doc(arm.attrs.iter(), cx);
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr) {
|
||||
self.warn_if_doc(expr.attrs.iter(), cx);
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub UNCONDITIONAL_RECURSION,
|
||||
Warn,
|
||||
|
@ -111,6 +111,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
UnusedImportBraces,
|
||||
AnonymousParameters,
|
||||
IllegalFloatLiteralPattern,
|
||||
UnusedDocComment,
|
||||
);
|
||||
|
||||
add_early_builtin_with_new!(sess,
|
||||
|
@ -89,23 +89,23 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
tcx.item_path_str(tcx.hir.local_def_id(item.id)));
|
||||
|
||||
match item.node {
|
||||
/// Right now we check that every default trait implementation
|
||||
/// has an implementation of itself. Basically, a case like:
|
||||
///
|
||||
/// `impl Trait for T {}`
|
||||
///
|
||||
/// has a requirement of `T: Trait` which was required for default
|
||||
/// method implementations. Although this could be improved now that
|
||||
/// there's a better infrastructure in place for this, it's being left
|
||||
/// for a follow-up work.
|
||||
///
|
||||
/// Since there's such a requirement, we need to check *just* positive
|
||||
/// implementations, otherwise things like:
|
||||
///
|
||||
/// impl !Send for T {}
|
||||
///
|
||||
/// won't be allowed unless there's an *explicit* implementation of `Send`
|
||||
/// for `T`
|
||||
// Right now we check that every default trait implementation
|
||||
// has an implementation of itself. Basically, a case like:
|
||||
//
|
||||
// `impl Trait for T {}`
|
||||
//
|
||||
// has a requirement of `T: Trait` which was required for default
|
||||
// method implementations. Although this could be improved now that
|
||||
// there's a better infrastructure in place for this, it's being left
|
||||
// for a follow-up work.
|
||||
//
|
||||
// Since there's such a requirement, we need to check *just* positive
|
||||
// implementations, otherwise things like:
|
||||
//
|
||||
// impl !Send for T {}
|
||||
//
|
||||
// won't be allowed unless there's an *explicit* implementation of `Send`
|
||||
// for `T`
|
||||
hir::ItemImpl(_, hir::ImplPolarity::Positive, _, _,
|
||||
ref trait_ref, ref self_ty, _) => {
|
||||
self.check_impl(item, self_ty, trait_ref);
|
||||
|
@ -733,6 +733,13 @@ impl Stmt {
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn is_item(&self) -> bool {
|
||||
match self.node {
|
||||
StmtKind::Local(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Stmt {
|
||||
|
@ -2074,14 +2074,14 @@ impl<'a> Parser<'a> {
|
||||
} else {
|
||||
Ok(self.mk_expr(span, ExprKind::Tup(es), attrs))
|
||||
}
|
||||
},
|
||||
}
|
||||
token::OpenDelim(token::Brace) => {
|
||||
return self.parse_block_expr(lo, BlockCheckMode::Default, attrs);
|
||||
},
|
||||
}
|
||||
token::BinOp(token::Or) | token::OrOr => {
|
||||
let lo = self.span;
|
||||
return self.parse_lambda_expr(lo, CaptureBy::Ref, attrs);
|
||||
},
|
||||
}
|
||||
token::OpenDelim(token::Bracket) => {
|
||||
self.bump();
|
||||
|
||||
@ -2329,7 +2329,6 @@ impl<'a> Parser<'a> {
|
||||
pub fn parse_block_expr(&mut self, lo: Span, blk_mode: BlockCheckMode,
|
||||
outer_attrs: ThinVec<Attribute>)
|
||||
-> PResult<'a, P<Expr>> {
|
||||
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
|
||||
let mut attrs = outer_attrs;
|
||||
|
@ -8,11 +8,23 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(warnings)]
|
||||
#![deny(unused_doc_comment)]
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { //~ ERROR compilation successful
|
||||
/// crash
|
||||
let x = 0;
|
||||
fn foo() {
|
||||
/// a //~ ERROR doc comment not used by rustdoc
|
||||
let x = 12;
|
||||
|
||||
/// b //~ doc comment not used by rustdoc
|
||||
match x {
|
||||
/// c //~ ERROR doc comment not used by rustdoc
|
||||
1 => {},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
/// foo //~ ERROR doc comment not used by rustdoc
|
||||
unsafe {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo();
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit 88aa6423a164774d09abc78a24e74e8e665f651b
|
||||
Subproject commit 305bc25d5e105e84ffe261655b46cf74570f6e5b
|
@ -1 +1 @@
|
||||
Subproject commit 79d659e5699fbf7db5b4819e9a442fb3f550472a
|
||||
Subproject commit 06b48d1c97dd69968a24b4f506e85e3a3efb7dea
|
Loading…
Reference in New Issue
Block a user