X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=clippy_lints%2Fsrc%2Fdoc.rs;h=133a20b669a17720faab96f0cb22031939e01f2a;hb=0ee393cf01b59d55a54e9e4299797bd0f7339d58;hp=cc662806e85f4396d80b17b9ad38aadcad3d8b64;hpb=c5178e82b4ed8fd9210e382dcd2735d438957434;p=rust.git diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index cc662806e85..133a20b669a 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -1,10 +1,11 @@ -use crate::utils::{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::hir; -use rustc::impl_lint_pass; -use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use rustc::lint::in_external_macro; +use rustc::ty::TyKind; use rustc_data_structures::fx::FxHashSet; -use rustc_session::declare_tool_lint; +use rustc_hir as hir; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::{BytePos, MultiSpan, Span}; use rustc_span::Pos; use std::ops::Range; @@ -153,9 +154,16 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) let headers = check_attrs(cx, &self.valid_idents, &item.attrs); match item.kind { hir::ItemKind::Fn(ref sig, ..) => { - lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers); + if !(is_entrypoint_fn(cx, cx.tcx.hir().local_def_id(item.hir_id)) + || in_external_macro(cx.tcx.sess, item.span)) + { + lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers); + } }, - hir::ItemKind::Impl(_, _, _, _, ref trait_ref, ..) => { + hir::ItemKind::Impl { + of_trait: ref trait_ref, + .. + } => { self.in_trait_impl = trait_ref.is_some(); }, _ => {}, @@ -163,7 +171,7 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) } fn check_item_post(&mut self, _cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) { - if let hir::ItemKind::Impl(..) = item.kind { + if let hir::ItemKind::Impl { .. } = item.kind { self.in_trait_impl = false; } } @@ -171,13 +179,15 @@ fn check_item_post(&mut self, _cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem<'_>) { let headers = check_attrs(cx, &self.valid_idents, &item.attrs); if let hir::TraitItemKind::Method(ref sig, ..) = item.kind { - lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers); + if !in_external_macro(cx.tcx.sess, item.span) { + lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers); + } } } fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem<'_>) { let headers = check_attrs(cx, &self.valid_idents, &item.attrs); - if self.in_trait_impl { + if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) { return; } if let hir::ImplItemKind::Method(ref sig, ..) = item.kind { @@ -204,13 +214,38 @@ fn lint_for_missing_headers<'a, 'tcx>( "unsafe function's docs miss `# Safety` section", ); } - if !headers.errors && match_type(cx, return_ty(cx, hir_id), &paths::RESULT) { - span_lint( - cx, - MISSING_ERRORS_DOC, - span, - "docs for function returning `Result` missing `# Errors` section", - ); + if !headers.errors { + if match_type(cx, return_ty(cx, hir_id), &paths::RESULT) { + span_lint( + cx, + MISSING_ERRORS_DOC, + span, + "docs for function returning `Result` missing `# Errors` section", + ); + } else { + let def_id = cx.tcx.hir().local_def_id(hir_id); + let mir = cx.tcx.optimized_mir(def_id); + 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", + ); + } + } + } + } + } + } + } } }