Skip to content

Commit

Permalink
update error message for anyhow
Browse files Browse the repository at this point in the history
Signed-off-by: Bugen Zhao <[email protected]>
  • Loading branch information
BugenZhao committed Feb 20, 2024
1 parent e3d158f commit 44ebaed
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 24 deletions.
73 changes: 53 additions & 20 deletions lints/src/format_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,20 +144,27 @@ fn check_fmt_arg_in_anyhow_error(cx: &LateContext<'_>, arg_expr: &Expr<'_>) {
check_fmt_arg_with_help(
cx,
arg_expr,
"consider directly wrapping the error with `anyhow::anyhow!(..)` instead of formatting it",
(
"consider directly wrapping the error with `anyhow::anyhow!(..)` instead of formatting it",
"consider removing the redundant wrapping of `anyhow::anyhow!(..)`",
),
);
}

fn check_fmt_arg_in_anyhow_context(cx: &LateContext<'_>, arg_expr: &Expr<'_>) {
check_fmt_arg_with_help(
cx,
arg_expr,
"consider using `anyhow::Error::context`, `anyhow::Context::(with_)context` to \
(
"consider using `anyhow::Context::(with_)context` to \
attach additional message to the error and make it an error source instead",
"consider using `.context(..)` to \
attach additional message to the error and make it an error source instead",
),
);
}

fn check_fmt_arg_with_help(cx: &LateContext<'_>, arg_expr: &Expr<'_>, help: &str) {
fn check_fmt_arg_with_help(cx: &LateContext<'_>, arg_expr: &Expr<'_>, help: impl Help) {
check_arg(cx, arg_expr, arg_expr.span, help);
}

Expand All @@ -170,30 +177,56 @@ fn check_to_string_call(cx: &LateContext<'_>, receiver: &Expr<'_>, to_string_spa
);
}

fn check_arg(cx: &LateContext<'_>, arg_expr: &Expr<'_>, span: Span, help: &str) {
fn check_arg(cx: &LateContext<'_>, arg_expr: &Expr<'_>, span: Span, help: impl Help) {
let Some(error_trait_id) = cx.tcx.get_diagnostic_item(sym::Error) else {
return;
};

let ty = cx.typeck_results().expr_ty(arg_expr).peel_refs();

let is_error = || implements_trait(cx, ty, error_trait_id, &[]);
let is_anyhow = || match_type(cx, ty, &ANYHOW_ERROR);
let help = if implements_trait(cx, ty, error_trait_id, &[]) {
help.normal_help()
} else if match_type(cx, ty, &ANYHOW_ERROR) {
help.anyhow_help()
} else {
return;
};

if is_error() || is_anyhow() {
if let Some(span) = core::iter::successors(Some(span), |s| s.parent_callsite())
.find(|s| s.can_be_used_for_suggestions())
{
// TODO: applicable suggestions
span_lint_and_help(
cx,
FORMAT_ERROR,
span,
"should not format error directly",
None,
help,
);
}
if let Some(span) = core::iter::successors(Some(span), |s| s.parent_callsite())
.find(|s| s.can_be_used_for_suggestions())
{
// TODO: applicable suggestions
span_lint_and_help(
cx,
FORMAT_ERROR,
span,
"should not format error directly",
None,
help,
);
}
}

trait Help {
fn normal_help(&self) -> &str;
fn anyhow_help(&self) -> &str {
self.normal_help()
}
}

impl Help for &str {
fn normal_help(&self) -> &str {
self
}
}

impl Help for (&str, &str) {
fn normal_help(&self) -> &str {
self.0
}

fn anyhow_help(&self) -> &str {
self.1
}
}

Expand Down
1 change: 1 addition & 0 deletions lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#![feature(rustc_private)]
#![feature(let_chains)]
#![feature(lazy_cell)]
#![warn(unused_extern_crates)]

extern crate rustc_ast;
Expand Down
8 changes: 4 additions & 4 deletions lints/ui/format_error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,15 @@ error: should not format error directly
LL | let _ = anyhow!("some error occurred: {}", err);
| ^^^
|
= help: consider using `anyhow::Error::context`, `anyhow::Context::(with_)context` to attach additional message to the error and make it an error source instead
= help: consider using `anyhow::Context::(with_)context` to attach additional message to the error and make it an error source instead

error: should not format error directly
--> $DIR/format_error.rs:57:50
|
LL | let _ = anyhow!("some error occurred: {:?}", err);
| ^^^
|
= help: consider using `anyhow::Error::context`, `anyhow::Context::(with_)context` to attach additional message to the error and make it an error source instead
= help: consider using `anyhow::Context::(with_)context` to attach additional message to the error and make it an error source instead

error: should not format error directly
--> $DIR/format_error.rs:63:27
Expand Down Expand Up @@ -334,15 +334,15 @@ error: should not format error directly
LL | let _ = anyhow!("{}", anyhow_err);
| ^^^^^^^^^^
|
= help: consider directly wrapping the error with `anyhow::anyhow!(..)` instead of formatting it
= help: consider removing the redundant wrapping of `anyhow::anyhow!(..)`

error: should not format error directly
--> $DIR/format_error.rs:75:50
|
LL | let _ = anyhow!("some error occurred: {:?}", anyhow_err);
| ^^^^^^^^^^
|
= help: consider using `anyhow::Error::context`, `anyhow::Context::(with_)context` to attach additional message to the error and make it an error source instead
= help: consider using `.context(..)` to attach additional message to the error and make it an error source instead

error: aborting due to 43 previous errors

0 comments on commit 44ebaed

Please sign in to comment.