Improve error message for assert!() macro in functions returning bool
This commit is contained in:
parent
625b63f9e1
commit
95b58ac6ac
5 changed files with 106 additions and 8 deletions
|
|
@ -1,10 +1,11 @@
|
|||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::{self as hir, ExprKind, HirId, PatKind};
|
||||
use rustc_hir_pretty::ty_to_string;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{Span, sym};
|
||||
use rustc_trait_selection::traits::{
|
||||
MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
|
||||
};
|
||||
|
|
@ -291,6 +292,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
error
|
||||
}
|
||||
|
||||
/// Check if the span comes from an assert-like macro expansion.
|
||||
fn is_from_assert_macro(&self, span: Span) -> bool {
|
||||
span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| {
|
||||
matches!(
|
||||
self.tcx.get_diagnostic_name(def_id),
|
||||
Some(
|
||||
sym::assert_macro
|
||||
| sym::debug_assert_macro
|
||||
| sym::assert_eq_macro
|
||||
| sym::assert_ne_macro
|
||||
| sym::debug_assert_eq_macro
|
||||
| sym::debug_assert_ne_macro
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Explain why `if` expressions without `else` evaluate to `()` and detect likely irrefutable
|
||||
/// `if let PAT = EXPR {}` expressions that could be turned into `let PAT = EXPR;`.
|
||||
fn explain_if_expr(
|
||||
|
|
@ -302,6 +320,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
then_expr: &'tcx hir::Expr<'tcx>,
|
||||
error: &mut bool,
|
||||
) {
|
||||
let is_assert_macro = self.is_from_assert_macro(if_span);
|
||||
|
||||
if let Some((if_span, msg)) = ret_reason {
|
||||
err.span_label(if_span, msg);
|
||||
} else if let ExprKind::Block(block, _) = then_expr.kind
|
||||
|
|
@ -309,8 +329,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
{
|
||||
err.span_label(expr.span, "found here");
|
||||
}
|
||||
err.note("`if` expressions without `else` evaluate to `()`");
|
||||
err.help("consider adding an `else` block that evaluates to the expected type");
|
||||
|
||||
if is_assert_macro {
|
||||
err.code(E0308);
|
||||
err.primary_message("mismatched types");
|
||||
} else {
|
||||
err.note("`if` expressions without `else` evaluate to `()`");
|
||||
err.help("consider adding an `else` block that evaluates to the expected type");
|
||||
}
|
||||
*error = true;
|
||||
if let ExprKind::Let(hir::LetExpr { span, pat, init, .. }) = cond_expr.kind
|
||||
&& let ExprKind::Block(block, _) = then_expr.kind
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
fn main() {
|
||||
enum Foo {
|
||||
Drop = assert_eq!(1, 1),
|
||||
//~^ ERROR `if` may be missing an `else` clause
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
error[E0317]: `if` may be missing an `else` clause
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-50577.rs:3:16
|
||||
|
|
||||
LL | Drop = assert_eq!(1, 1),
|
||||
| ^^^^^^^^^^^^^^^^ expected `isize`, found `()`
|
||||
|
|
||||
= note: `if` expressions without `else` evaluate to `()`
|
||||
= help: consider adding an `else` block that evaluates to the expected type
|
||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0317`.
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
|
|||
34
tests/ui/expr/if/assert-macro-without-else.rs
Normal file
34
tests/ui/expr/if/assert-macro-without-else.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
//@ dont-require-annotations: NOTE
|
||||
|
||||
fn f() -> bool {
|
||||
assert!(1 < 2)
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
}
|
||||
|
||||
fn g() -> i32 {
|
||||
assert_eq!(1, 1)
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
}
|
||||
|
||||
fn h() -> bool {
|
||||
assert_ne!(1, 2)
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
}
|
||||
|
||||
// Test nested macros
|
||||
macro_rules! g {
|
||||
() => {
|
||||
f!()
|
||||
};
|
||||
}
|
||||
macro_rules! f {
|
||||
() => {
|
||||
assert!(1 < 2)
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
};
|
||||
}
|
||||
fn nested() -> bool {
|
||||
g!()
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
40
tests/ui/expr/if/assert-macro-without-else.stderr
Normal file
40
tests/ui/expr/if/assert-macro-without-else.stderr
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/assert-macro-without-else.rs:4:5
|
||||
|
|
||||
LL | fn f() -> bool {
|
||||
| ---- expected `bool` because of this return type
|
||||
LL | assert!(1 < 2)
|
||||
| ^^^^^^^^^^^^^^ expected `bool`, found `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/assert-macro-without-else.rs:9:5
|
||||
|
|
||||
LL | assert_eq!(1, 1)
|
||||
| ^^^^^^^^^^^^^^^^ expected `i32`, found `()`
|
||||
|
|
||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/assert-macro-without-else.rs:14:5
|
||||
|
|
||||
LL | assert_ne!(1, 2)
|
||||
| ^^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
||||
|
|
||||
= note: this error originates in the macro `assert_ne` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/assert-macro-without-else.rs:26:9
|
||||
|
|
||||
LL | assert!(1 < 2)
|
||||
| ^^^^^^^^^^^^^^ expected `bool`, found `()`
|
||||
...
|
||||
LL | fn nested() -> bool {
|
||||
| ---- expected `bool` because of this return type
|
||||
LL | g!()
|
||||
| ---- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `assert` which comes from the expansion of the macro `g` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue