Skip to content

Commit

Permalink
Print the first possible panic location in the lint message
Browse files Browse the repository at this point in the history
  • Loading branch information
flip1995 committed Jan 7, 2021
1 parent 3632212 commit c222abf
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 29 deletions.
46 changes: 18 additions & 28 deletions clippy_lints/src/doc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::utils::{
implements_trait, is_entrypoint_fn, is_type_diagnostic_item, match_panic_def_id, method_chain_args, return_ty,
span_lint,
span_lint, span_lint_and_note,
};
use if_chain::if_chain;
use itertools::Itertools;
Expand All @@ -13,7 +13,7 @@ use rustc_errors::Handler;
use rustc_hir as hir;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::{Expr, ExprKind, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::hir::map::Map;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
Expand Down Expand Up @@ -223,18 +223,10 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
let mut fpu = FindPanicUnwrap {
cx,
typeck_results: cx.tcx.typeck(impl_item_def_id),
found_panicking: false,
panic_span: None,
};
fpu.visit_expr(&body.value);
lint_for_missing_headers(
cx,
item.hir_id,
item.span,
sig,
headers,
Some(body_id),
fpu.found_panicking,
);
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, Some(body_id), fpu.panic_span);
}
},
hir::ItemKind::Impl {
Expand All @@ -257,7 +249,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
if !in_external_macro(cx.tcx.sess, item.span) {
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, None, false);
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, None, None);
}
}
}
Expand All @@ -272,19 +264,11 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
let impl_item_def_id = cx.tcx.hir().local_def_id(item.hir_id);
let mut fpu = FindPanicUnwrap {
cx,
found_panicking: false,
typeck_results: cx.tcx.typeck(impl_item_def_id),
panic_span: None,
};
fpu.visit_expr(&body.value);
lint_for_missing_headers(
cx,
item.hir_id,
item.span,
sig,
headers,
Some(body_id),
fpu.found_panicking,
);
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, Some(body_id), fpu.panic_span);
}
}
}
Expand All @@ -296,7 +280,7 @@ fn lint_for_missing_headers<'tcx>(
sig: &hir::FnSig<'_>,
headers: DocHeaders,
body_id: Option<hir::BodyId>,
found_panicking: bool,
panic_span: Option<Span>,
) {
if !cx.access_levels.is_exported(hir_id) {
return; // Private functions do not require doc comments
Expand All @@ -309,12 +293,14 @@ fn lint_for_missing_headers<'tcx>(
"unsafe function's docs miss `# Safety` section",
);
}
if !headers.panics && found_panicking {
span_lint(
if !headers.panics && panic_span.is_some() {
span_lint_and_note(
cx,
MISSING_PANICS_DOC,
span,
"docs for function which may panic missing `# Panics` section",
panic_span,
"first possible panic found here",
);
}
if !headers.errors {
Expand Down Expand Up @@ -697,22 +683,26 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {

struct FindPanicUnwrap<'a, 'tcx> {
cx: &'a LateContext<'tcx>,
found_panicking: bool,
panic_span: Option<Span>,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
}

impl<'a, 'tcx> Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> {
type Map = Map<'tcx>;

fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
if self.panic_span.is_some() {
return;
}

// check for `begin_panic`
if_chain! {
if let ExprKind::Call(ref func_expr, _) = expr.kind;
if let ExprKind::Path(QPath::Resolved(_, ref path)) = func_expr.kind;
if let Some(path_def_id) = path.res.opt_def_id();
if match_panic_def_id(self.cx, path_def_id);
then {
self.found_panicking = true;
self.panic_span = Some(expr.span);
}
}

Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/utils/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub fn span_lint_and_help<'a, T: LintContext>(
pub fn span_lint_and_note<'a, T: LintContext>(
cx: &'a T,
lint: &'static Lint,
span: Span,
span: impl Into<MultiSpan>,
msg: &str,
note_span: Option<Span>,
note: &str,
Expand Down
26 changes: 26 additions & 0 deletions tests/ui/doc_panics.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ LL | | }
| |_^
|
= note: `-D clippy::missing-panics-doc` implied by `-D warnings`
note: first possible panic found here
--> $DIR/doc_panics.rs:9:5
|
LL | result.unwrap()
| ^^^^^^^^^^^^^^^

error: docs for function which may panic missing `# Panics` section
--> $DIR/doc_panics.rs:13:1
Expand All @@ -16,6 +21,13 @@ LL | / pub fn panic() {
LL | | panic!("This function panics")
LL | | }
| |_^
|
note: first possible panic found here
--> $DIR/doc_panics.rs:14:5
|
LL | panic!("This function panics")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: docs for function which may panic missing `# Panics` section
--> $DIR/doc_panics.rs:18:1
Expand All @@ -24,6 +36,13 @@ LL | / pub fn todo() {
LL | | todo!()
LL | | }
| |_^
|
note: first possible panic found here
--> $DIR/doc_panics.rs:19:5
|
LL | todo!()
| ^^^^^^^
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: docs for function which may panic missing `# Panics` section
--> $DIR/doc_panics.rs:23:1
Expand All @@ -36,6 +55,13 @@ LL | | }
LL | | });
LL | | }
| |_^
|
note: first possible panic found here
--> $DIR/doc_panics.rs:26:13
|
LL | panic!()
| ^^^^^^^^
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 4 previous errors

0 comments on commit c222abf

Please sign in to comment.