mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-03 18:43:38 +00:00
Auto merge of #4884 - RobbieClarken:warn-missing-errors, r=llogiq
Add lint for pub fns returning a `Result` without documenting errors The Rust Book recommends that functions that return a `Result` type have [a doc comment with an `# Errors` section](https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#commonly-used-sections) describing the kind of errors that can be returned. This change adds a lint to enforce this. The lint is allow by default; it can be enabled with `#![warn(clippy::missing_errors_doc)]`. Closes #4854. changelog: adds lint for `missing_errors_doc`
This commit is contained in:
commit
61b19a1a28
@ -1092,6 +1092,7 @@ Released 2018-09-13
|
|||||||
[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op
|
[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op
|
||||||
[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn
|
[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn
|
||||||
[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items
|
[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items
|
||||||
|
[`missing_errors_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc
|
||||||
[`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items
|
[`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items
|
||||||
[`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
|
[`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
|
||||||
[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
|
[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
|
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
|
||||||
|
|
||||||
[There are 338 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
|
[There are 339 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
|
||||||
|
|
||||||
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
|
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::utils::span_lint;
|
use crate::utils::{match_type, paths, return_ty, span_lint};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use pulldown_cmark;
|
use pulldown_cmark;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_session::declare_tool_lint;
|
use rustc_session::declare_tool_lint;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use syntax::ast::{AttrKind, Attribute};
|
use syntax::ast::{AttrKind, Attribute};
|
||||||
use syntax::source_map::{BytePos, Span};
|
use syntax::source_map::{BytePos, MultiSpan, Span};
|
||||||
use syntax_pos::Pos;
|
use syntax_pos::Pos;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ declare_clippy_lint! {
|
|||||||
///
|
///
|
||||||
/// **Known problems:** None.
|
/// **Known problems:** None.
|
||||||
///
|
///
|
||||||
/// **Examples**:
|
/// **Examples:**
|
||||||
/// ```rust
|
/// ```rust
|
||||||
///# type Universe = ();
|
///# type Universe = ();
|
||||||
/// /// This function should really be documented
|
/// /// This function should really be documented
|
||||||
@ -70,6 +70,35 @@ declare_clippy_lint! {
|
|||||||
"`pub unsafe fn` without `# Safety` docs"
|
"`pub unsafe fn` without `# Safety` docs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// **What it does:** Checks the doc comments of publicly visible functions that
|
||||||
|
/// return a `Result` type and warns if there is no `# Errors` section.
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** Documenting the type of errors that can be returned from a
|
||||||
|
/// function can help callers write code to handle the errors appropriately.
|
||||||
|
///
|
||||||
|
/// **Known problems:** None.
|
||||||
|
///
|
||||||
|
/// **Examples:**
|
||||||
|
///
|
||||||
|
/// Since the following function returns a `Result` it has an `# Errors` section in
|
||||||
|
/// its doc comment:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
///# use std::io;
|
||||||
|
/// /// # Errors
|
||||||
|
/// ///
|
||||||
|
/// /// Will return `Err` if `filename` does not exist or the user does not have
|
||||||
|
/// /// permission to read it.
|
||||||
|
/// pub fn read(filename: String) -> io::Result<String> {
|
||||||
|
/// unimplemented!();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub MISSING_ERRORS_DOC,
|
||||||
|
pedantic,
|
||||||
|
"`pub fn` returns `Result` without `# Errors` in doc comment"
|
||||||
|
}
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// **What it does:** Checks for `fn main() { .. }` in doctests
|
/// **What it does:** Checks for `fn main() { .. }` in doctests
|
||||||
///
|
///
|
||||||
@ -114,7 +143,7 @@ impl DocMarkdown {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN, MISSING_SAFETY_DOC, NEEDLESS_DOCTEST_MAIN]);
|
impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN, MISSING_SAFETY_DOC, MISSING_ERRORS_DOC, NEEDLESS_DOCTEST_MAIN]);
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
|
||||||
fn check_crate(&mut self, cx: &LateContext<'a, 'tcx>, krate: &'tcx hir::Crate) {
|
fn check_crate(&mut self, cx: &LateContext<'a, 'tcx>, krate: &'tcx hir::Crate) {
|
||||||
@ -122,20 +151,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
|
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
|
||||||
if check_attrs(cx, &self.valid_idents, &item.attrs) {
|
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
|
||||||
return;
|
|
||||||
}
|
|
||||||
// no safety header
|
|
||||||
match item.kind {
|
match item.kind {
|
||||||
hir::ItemKind::Fn(ref sig, ..) => {
|
hir::ItemKind::Fn(ref sig, ..) => {
|
||||||
if cx.access_levels.is_exported(item.hir_id) && sig.header.unsafety == hir::Unsafety::Unsafe {
|
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers);
|
||||||
span_lint(
|
|
||||||
cx,
|
|
||||||
MISSING_SAFETY_DOC,
|
|
||||||
item.span,
|
|
||||||
"unsafe function's docs miss `# Safety` section",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
hir::ItemKind::Impl(_, _, _, _, ref trait_ref, ..) => {
|
hir::ItemKind::Impl(_, _, _, _, ref trait_ref, ..) => {
|
||||||
self.in_trait_impl = trait_ref.is_some();
|
self.in_trait_impl = trait_ref.is_some();
|
||||||
@ -151,37 +170,48 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) {
|
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) {
|
||||||
if check_attrs(cx, &self.valid_idents, &item.attrs) {
|
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
|
||||||
return;
|
|
||||||
}
|
|
||||||
// no safety header
|
|
||||||
if let hir::TraitItemKind::Method(ref sig, ..) = item.kind {
|
if let hir::TraitItemKind::Method(ref sig, ..) = item.kind {
|
||||||
if cx.access_levels.is_exported(item.hir_id) && sig.header.unsafety == hir::Unsafety::Unsafe {
|
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers);
|
||||||
span_lint(
|
|
||||||
cx,
|
|
||||||
MISSING_SAFETY_DOC,
|
|
||||||
item.span,
|
|
||||||
"unsafe function's docs miss `# Safety` section",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem) {
|
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem) {
|
||||||
if check_attrs(cx, &self.valid_idents, &item.attrs) || self.in_trait_impl {
|
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
|
||||||
|
if self.in_trait_impl {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// no safety header
|
|
||||||
if let hir::ImplItemKind::Method(ref sig, ..) = item.kind {
|
if let hir::ImplItemKind::Method(ref sig, ..) = item.kind {
|
||||||
if cx.access_levels.is_exported(item.hir_id) && sig.header.unsafety == hir::Unsafety::Unsafe {
|
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lint_for_missing_headers<'a, 'tcx>(
|
||||||
|
cx: &LateContext<'a, 'tcx>,
|
||||||
|
hir_id: hir::HirId,
|
||||||
|
span: impl Into<MultiSpan> + Copy,
|
||||||
|
sig: &hir::FnSig,
|
||||||
|
headers: DocHeaders,
|
||||||
|
) {
|
||||||
|
if !cx.access_levels.is_exported(hir_id) {
|
||||||
|
return; // Private functions do not require doc comments
|
||||||
|
}
|
||||||
|
if !headers.safety && sig.header.unsafety == hir::Unsafety::Unsafe {
|
||||||
span_lint(
|
span_lint(
|
||||||
cx,
|
cx,
|
||||||
MISSING_SAFETY_DOC,
|
MISSING_SAFETY_DOC,
|
||||||
item.span,
|
span,
|
||||||
"unsafe function's docs miss `# Safety` section",
|
"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",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +273,13 @@ pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<(
|
|||||||
panic!("not a doc-comment: {}", comment);
|
panic!("not a doc-comment: {}", comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String>, attrs: &'a [Attribute]) -> bool {
|
#[derive(Copy, Clone)]
|
||||||
|
struct DocHeaders {
|
||||||
|
safety: bool,
|
||||||
|
errors: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String>, attrs: &'a [Attribute]) -> DocHeaders {
|
||||||
let mut doc = String::new();
|
let mut doc = String::new();
|
||||||
let mut spans = vec![];
|
let mut spans = vec![];
|
||||||
|
|
||||||
@ -255,7 +291,11 @@ pub fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String
|
|||||||
doc.push_str(&comment);
|
doc.push_str(&comment);
|
||||||
} else if attr.check_name(sym!(doc)) {
|
} else if attr.check_name(sym!(doc)) {
|
||||||
// ignore mix of sugared and non-sugared doc
|
// ignore mix of sugared and non-sugared doc
|
||||||
return true; // don't trigger the safety check
|
// don't trigger the safety or errors check
|
||||||
|
return DocHeaders {
|
||||||
|
safety: true,
|
||||||
|
errors: true,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +307,10 @@ pub fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String
|
|||||||
}
|
}
|
||||||
|
|
||||||
if doc.is_empty() {
|
if doc.is_empty() {
|
||||||
return false;
|
return DocHeaders {
|
||||||
|
safety: false,
|
||||||
|
errors: false,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let parser = pulldown_cmark::Parser::new(&doc).into_offset_iter();
|
let parser = pulldown_cmark::Parser::new(&doc).into_offset_iter();
|
||||||
@ -295,12 +338,15 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||||||
valid_idents: &FxHashSet<String>,
|
valid_idents: &FxHashSet<String>,
|
||||||
events: Events,
|
events: Events,
|
||||||
spans: &[(usize, Span)],
|
spans: &[(usize, Span)],
|
||||||
) -> bool {
|
) -> DocHeaders {
|
||||||
// true if a safety header was found
|
// true if a safety header was found
|
||||||
use pulldown_cmark::Event::*;
|
use pulldown_cmark::Event::*;
|
||||||
use pulldown_cmark::Tag::*;
|
use pulldown_cmark::Tag::*;
|
||||||
|
|
||||||
let mut safety_header = false;
|
let mut headers = DocHeaders {
|
||||||
|
safety: false,
|
||||||
|
errors: false,
|
||||||
|
};
|
||||||
let mut in_code = false;
|
let mut in_code = false;
|
||||||
let mut in_link = None;
|
let mut in_link = None;
|
||||||
let mut in_heading = false;
|
let mut in_heading = false;
|
||||||
@ -323,7 +369,8 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||||||
// text "http://example.com" by pulldown-cmark
|
// text "http://example.com" by pulldown-cmark
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
safety_header |= in_heading && text.trim() == "Safety";
|
headers.safety |= in_heading && text.trim() == "Safety";
|
||||||
|
headers.errors |= in_heading && text.trim() == "Errors";
|
||||||
let index = match spans.binary_search_by(|c| c.0.cmp(&range.start)) {
|
let index = match spans.binary_search_by(|c| c.0.cmp(&range.start)) {
|
||||||
Ok(o) => o,
|
Ok(o) => o,
|
||||||
Err(e) => e - 1,
|
Err(e) => e - 1,
|
||||||
@ -340,7 +387,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
safety_header
|
headers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_code(cx: &LateContext<'_, '_>, text: &str, span: Span) {
|
fn check_code(cx: &LateContext<'_, '_>, text: &str, span: Span) {
|
||||||
|
@ -488,6 +488,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
|||||||
&derive::DERIVE_HASH_XOR_EQ,
|
&derive::DERIVE_HASH_XOR_EQ,
|
||||||
&derive::EXPL_IMPL_CLONE_ON_COPY,
|
&derive::EXPL_IMPL_CLONE_ON_COPY,
|
||||||
&doc::DOC_MARKDOWN,
|
&doc::DOC_MARKDOWN,
|
||||||
|
&doc::MISSING_ERRORS_DOC,
|
||||||
&doc::MISSING_SAFETY_DOC,
|
&doc::MISSING_SAFETY_DOC,
|
||||||
&doc::NEEDLESS_DOCTEST_MAIN,
|
&doc::NEEDLESS_DOCTEST_MAIN,
|
||||||
&double_comparison::DOUBLE_COMPARISONS,
|
&double_comparison::DOUBLE_COMPARISONS,
|
||||||
@ -1013,6 +1014,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
|||||||
LintId::of(&default_trait_access::DEFAULT_TRAIT_ACCESS),
|
LintId::of(&default_trait_access::DEFAULT_TRAIT_ACCESS),
|
||||||
LintId::of(&derive::EXPL_IMPL_CLONE_ON_COPY),
|
LintId::of(&derive::EXPL_IMPL_CLONE_ON_COPY),
|
||||||
LintId::of(&doc::DOC_MARKDOWN),
|
LintId::of(&doc::DOC_MARKDOWN),
|
||||||
|
LintId::of(&doc::MISSING_ERRORS_DOC),
|
||||||
LintId::of(&empty_enum::EMPTY_ENUM),
|
LintId::of(&empty_enum::EMPTY_ENUM),
|
||||||
LintId::of(&enum_glob_use::ENUM_GLOB_USE),
|
LintId::of(&enum_glob_use::ENUM_GLOB_USE),
|
||||||
LintId::of(&enum_variants::MODULE_NAME_REPETITIONS),
|
LintId::of(&enum_variants::MODULE_NAME_REPETITIONS),
|
||||||
|
@ -6,7 +6,7 @@ pub use lint::Lint;
|
|||||||
pub use lint::LINT_LEVELS;
|
pub use lint::LINT_LEVELS;
|
||||||
|
|
||||||
// begin lint list, do not remove this comment, it’s used in `update_lints`
|
// begin lint list, do not remove this comment, it’s used in `update_lints`
|
||||||
pub const ALL_LINTS: [Lint; 338] = [
|
pub const ALL_LINTS: [Lint; 339] = [
|
||||||
Lint {
|
Lint {
|
||||||
name: "absurd_extreme_comparisons",
|
name: "absurd_extreme_comparisons",
|
||||||
group: "correctness",
|
group: "correctness",
|
||||||
@ -1127,6 +1127,13 @@ pub const ALL_LINTS: [Lint; 338] = [
|
|||||||
deprecation: None,
|
deprecation: None,
|
||||||
module: "missing_doc",
|
module: "missing_doc",
|
||||||
},
|
},
|
||||||
|
Lint {
|
||||||
|
name: "missing_errors_doc",
|
||||||
|
group: "pedantic",
|
||||||
|
desc: "`pub fn` returns `Result` without `# Errors` in doc comment",
|
||||||
|
deprecation: None,
|
||||||
|
module: "doc",
|
||||||
|
},
|
||||||
Lint {
|
Lint {
|
||||||
name: "missing_inline_in_public_items",
|
name: "missing_inline_in_public_items",
|
||||||
group: "restriction",
|
group: "restriction",
|
||||||
|
64
tests/ui/doc_errors.rs
Normal file
64
tests/ui/doc_errors.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#![warn(clippy::missing_errors_doc)]
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
pub fn pub_fn_missing_errors_header() -> Result<(), ()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is not sufficiently documented.
|
||||||
|
pub fn 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!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function doesn't require the documentation because it is private
|
||||||
|
fn priv_fn_missing_errors_header() -> Result<(), ()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Struct1;
|
||||||
|
|
||||||
|
impl Struct1 {
|
||||||
|
/// This is not sufficiently documented.
|
||||||
|
pub fn pub_method_missing_errors_header() -> Result<(), ()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # Errors
|
||||||
|
/// A description of the errors goes here.
|
||||||
|
pub fn 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!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Trait1 {
|
||||||
|
/// This is not sufficiently documented.
|
||||||
|
fn trait_method_missing_errors_header() -> Result<(), ()>;
|
||||||
|
|
||||||
|
/// # Errors
|
||||||
|
/// A description of the errors goes here.
|
||||||
|
fn trait_method_with_errors_header() -> Result<(), ()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait1 for Struct1 {
|
||||||
|
fn trait_method_missing_errors_header() -> Result<(), ()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trait_method_with_errors_header() -> Result<(), ()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
34
tests/ui/doc_errors.stderr
Normal file
34
tests/ui/doc_errors.stderr
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
error: docs for function returning `Result` missing `# Errors` section
|
||||||
|
--> $DIR/doc_errors.rs:5:1
|
||||||
|
|
|
||||||
|
LL | / pub fn pub_fn_missing_errors_header() -> Result<(), ()> {
|
||||||
|
LL | | unimplemented!();
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::missing-errors-doc` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: docs for function returning `Result` missing `# Errors` section
|
||||||
|
--> $DIR/doc_errors.rs:10: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
|
||||||
|
|
|
||||||
|
LL | / pub fn pub_method_missing_errors_header() -> Result<(), ()> {
|
||||||
|
LL | | unimplemented!();
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: docs for function returning `Result` missing `# Errors` section
|
||||||
|
--> $DIR/doc_errors.rs:47:5
|
||||||
|
|
|
||||||
|
LL | fn trait_method_missing_errors_header() -> Result<(), ()>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user