From 0ee393cf01b59d55a54e9e4299797bd0f7339d58 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 17 Feb 2020 01:17:14 +0100 Subject: [PATCH] Add tests and improve checks. --- clippy_lints/src/doc.rs | 29 +++++++++++++++----------- clippy_lints/src/utils/paths.rs | 1 + tests/ui/doc_errors.rs | 37 +++++++++++++++++++++++++++++++++ tests/ui/doc_errors.stderr | 32 ++++++++++++++++++++++++---- 4 files changed, 83 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 4b1f2ec68cb..133a20b669a 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -1,4 +1,4 @@ -use crate::utils::{is_entrypoint_fn, match_type, paths, return_ty, span_lint}; +use crate::utils::{get_trait_def_id, implements_trait, is_entrypoint_fn, match_type, paths, return_ty, span_lint}; use itertools::Itertools; use rustc::lint::in_external_macro; use rustc::ty::TyKind; @@ -223,19 +223,24 @@ fn lint_for_missing_headers<'a, 'tcx>( "docs for function returning `Result` missing `# Errors` section", ); } else { - use TyKind::*; let def_id = cx.tcx.hir().local_def_id(hir_id); let mir = cx.tcx.optimized_mir(def_id); - if let Opaque(_, subs) = mir.return_ty().kind { - if let Some(ty) = subs.types().next() { - if let Generator(_, subs, _) = ty.kind { - if match_type(cx, subs.as_generator().return_ty(def_id, cx.tcx), &paths::RESULT) { - span_lint( - cx, - MISSING_ERRORS_DOC, - span, - "docs for function returning `Result` missing `# Errors` section", - ); + if let Some(future) = get_trait_def_id(cx, &paths::FUTURE) { + if implements_trait(cx, mir.return_ty(), future, &[]) { + use TyKind::*; + + if let Opaque(_, subs) = mir.return_ty().kind { + if let Some(ty) = subs.types().next() { + if let Generator(_, subs, _) = ty.kind { + if match_type(cx, subs.as_generator().return_ty(def_id, cx.tcx), &paths::RESULT) { + span_lint( + cx, + MISSING_ERRORS_DOC, + span, + "docs for function returning `Result` missing `# Errors` section", + ); + } + } } } } diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 0af7f946fa9..96337e42b54 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -36,6 +36,7 @@ pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"]; pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"]; pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"]; +pub const FUTURE: [&str; 3] = ["std", "future", "Future"]; pub const HASH: [&str; 2] = ["hash", "Hash"]; pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"]; pub const HASHMAP_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"]; diff --git a/tests/ui/doc_errors.rs b/tests/ui/doc_errors.rs index 776a65275e9..1401a658e03 100644 --- a/tests/ui/doc_errors.rs +++ b/tests/ui/doc_errors.rs @@ -1,3 +1,4 @@ +// compile-flags: --edition 2018 #![warn(clippy::missing_errors_doc)] use std::io; @@ -6,22 +7,42 @@ pub fn pub_fn_missing_errors_header() -> Result<(), ()> { unimplemented!(); } +pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> { + unimplemented!(); +} + /// This is not sufficiently documented. pub fn pub_fn_returning_io_result() -> io::Result<()> { unimplemented!(); } +/// This is not sufficiently documented. +pub async fn async_pub_fn_returning_io_result() -> io::Result<()> { + unimplemented!(); +} + /// # Errors /// A description of the errors goes here. pub fn pub_fn_with_errors_header() -> Result<(), ()> { unimplemented!(); } +/// # Errors +/// A description of the errors goes here. +pub async fn async_pub_fn_with_errors_header() -> Result<(), ()> { + unimplemented!(); +} + /// This function doesn't require the documentation because it is private fn priv_fn_missing_errors_header() -> Result<(), ()> { unimplemented!(); } +/// This function doesn't require the documentation because it is private +async fn async_priv_fn_missing_errors_header() -> Result<(), ()> { + unimplemented!(); +} + pub struct Struct1; impl Struct1 { @@ -30,16 +51,32 @@ pub fn pub_method_missing_errors_header() -> Result<(), ()> { unimplemented!(); } + /// This is not sufficiently documented. + pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> { + unimplemented!(); + } + /// # Errors /// A description of the errors goes here. pub fn pub_method_with_errors_header() -> Result<(), ()> { unimplemented!(); } + /// # Errors + /// A description of the errors goes here. + pub async fn async_pub_method_with_errors_header() -> Result<(), ()> { + unimplemented!(); + } + /// This function doesn't require the documentation because it is private. fn priv_method_missing_errors_header() -> Result<(), ()> { unimplemented!(); } + + /// This function doesn't require the documentation because it is private. + async fn async_priv_method_missing_errors_header() -> Result<(), ()> { + unimplemented!(); + } } pub trait Trait1 { diff --git a/tests/ui/doc_errors.stderr b/tests/ui/doc_errors.stderr index f1d321cf909..f44d6693d30 100644 --- a/tests/ui/doc_errors.stderr +++ b/tests/ui/doc_errors.stderr @@ -1,5 +1,5 @@ error: docs for function returning `Result` missing `# Errors` section - --> $DIR/doc_errors.rs:5:1 + --> $DIR/doc_errors.rs:6:1 | LL | / pub fn pub_fn_missing_errors_header() -> Result<(), ()> { LL | | unimplemented!(); @@ -11,13 +11,29 @@ LL | | } error: docs for function returning `Result` missing `# Errors` section --> $DIR/doc_errors.rs:10:1 | +LL | / pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> { +LL | | unimplemented!(); +LL | | } + | |_^ + +error: docs for function returning `Result` missing `# Errors` section + --> $DIR/doc_errors.rs:15:1 + | LL | / pub fn pub_fn_returning_io_result() -> io::Result<()> { LL | | unimplemented!(); LL | | } | |_^ error: docs for function returning `Result` missing `# Errors` section - --> $DIR/doc_errors.rs:29:5 + --> $DIR/doc_errors.rs:20:1 + | +LL | / pub async fn async_pub_fn_returning_io_result() -> io::Result<()> { +LL | | unimplemented!(); +LL | | } + | |_^ + +error: docs for function returning `Result` missing `# Errors` section + --> $DIR/doc_errors.rs:50:5 | LL | / pub fn pub_method_missing_errors_header() -> Result<(), ()> { LL | | unimplemented!(); @@ -25,10 +41,18 @@ LL | | } | |_____^ error: docs for function returning `Result` missing `# Errors` section - --> $DIR/doc_errors.rs:47:5 + --> $DIR/doc_errors.rs:55:5 + | +LL | / pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> { +LL | | unimplemented!(); +LL | | } + | |_____^ + +error: docs for function returning `Result` missing `# Errors` section + --> $DIR/doc_errors.rs:84:5 | LL | fn trait_method_missing_errors_header() -> Result<(), ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 7 previous errors