Skip to content

Commit d43b667

Browse files
authored
Rollup merge of #151457 - enthropy7:fix-assert-macro-only, r=enthropy7
Improve error message for assert!() macro in functions returning bool Detect `assert!()` macro in error messages and provide clearer diagnostics When `assert!()` is used in a function returning a value, show a message explaining that `assert!()` doesn't return a value, instead of the generic "if may be missing an else clause" error. Fixes #151446
2 parents 512cc8d + 95b58ac commit d43b667

5 files changed

Lines changed: 106 additions & 8 deletions

File tree

compiler/rustc_hir_typeck/src/_match.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
use rustc_errors::codes::*;
12
use rustc_errors::{Applicability, Diag};
23
use rustc_hir::def::{CtorOf, DefKind, Res};
34
use rustc_hir::def_id::LocalDefId;
45
use rustc_hir::{self as hir, ExprKind, HirId, PatKind};
56
use rustc_hir_pretty::ty_to_string;
67
use rustc_middle::ty::{self, Ty};
7-
use rustc_span::Span;
8+
use rustc_span::{Span, sym};
89
use rustc_trait_selection::traits::{
910
MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
1011
};
@@ -291,6 +292,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
291292
error
292293
}
293294

295+
/// Check if the span comes from an assert-like macro expansion.
296+
fn is_from_assert_macro(&self, span: Span) -> bool {
297+
span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| {
298+
matches!(
299+
self.tcx.get_diagnostic_name(def_id),
300+
Some(
301+
sym::assert_macro
302+
| sym::debug_assert_macro
303+
| sym::assert_eq_macro
304+
| sym::assert_ne_macro
305+
| sym::debug_assert_eq_macro
306+
| sym::debug_assert_ne_macro
307+
)
308+
)
309+
})
310+
}
311+
294312
/// Explain why `if` expressions without `else` evaluate to `()` and detect likely irrefutable
295313
/// `if let PAT = EXPR {}` expressions that could be turned into `let PAT = EXPR;`.
296314
fn explain_if_expr(
@@ -302,15 +320,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
302320
then_expr: &'tcx hir::Expr<'tcx>,
303321
error: &mut bool,
304322
) {
323+
let is_assert_macro = self.is_from_assert_macro(if_span);
324+
305325
if let Some((if_span, msg)) = ret_reason {
306326
err.span_label(if_span, msg);
307327
} else if let ExprKind::Block(block, _) = then_expr.kind
308328
&& let Some(expr) = block.expr
309329
{
310330
err.span_label(expr.span, "found here");
311331
}
312-
err.note("`if` expressions without `else` evaluate to `()`");
313-
err.help("consider adding an `else` block that evaluates to the expected type");
332+
333+
if is_assert_macro {
334+
err.code(E0308);
335+
err.primary_message("mismatched types");
336+
} else {
337+
err.note("`if` expressions without `else` evaluate to `()`");
338+
err.help("consider adding an `else` block that evaluates to the expected type");
339+
}
314340
*error = true;
315341
if let ExprKind::Let(hir::LetExpr { span, pat, init, .. }) = cond_expr.kind
316342
&& let ExprKind::Block(block, _) = then_expr.kind
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fn main() {
22
enum Foo {
33
Drop = assert_eq!(1, 1),
4-
//~^ ERROR `if` may be missing an `else` clause
4+
//~^ ERROR mismatched types [E0308]
55
}
66
}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
error[E0317]: `if` may be missing an `else` clause
1+
error[E0308]: mismatched types
22
--> $DIR/issue-50577.rs:3:16
33
|
44
LL | Drop = assert_eq!(1, 1),
55
| ^^^^^^^^^^^^^^^^ expected `isize`, found `()`
66
|
7-
= note: `if` expressions without `else` evaluate to `()`
8-
= help: consider adding an `else` block that evaluates to the expected type
97
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
108

119
error: aborting due to 1 previous error
1210

13-
For more information about this error, try `rustc --explain E0317`.
11+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//@ dont-require-annotations: NOTE
2+
3+
fn f() -> bool {
4+
assert!(1 < 2)
5+
//~^ ERROR mismatched types [E0308]
6+
}
7+
8+
fn g() -> i32 {
9+
assert_eq!(1, 1)
10+
//~^ ERROR mismatched types [E0308]
11+
}
12+
13+
fn h() -> bool {
14+
assert_ne!(1, 2)
15+
//~^ ERROR mismatched types [E0308]
16+
}
17+
18+
// Test nested macros
19+
macro_rules! g {
20+
() => {
21+
f!()
22+
};
23+
}
24+
macro_rules! f {
25+
() => {
26+
assert!(1 < 2)
27+
//~^ ERROR mismatched types [E0308]
28+
};
29+
}
30+
fn nested() -> bool {
31+
g!()
32+
}
33+
34+
fn main() {}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/assert-macro-without-else.rs:4:5
3+
|
4+
LL | fn f() -> bool {
5+
| ---- expected `bool` because of this return type
6+
LL | assert!(1 < 2)
7+
| ^^^^^^^^^^^^^^ expected `bool`, found `()`
8+
9+
error[E0308]: mismatched types
10+
--> $DIR/assert-macro-without-else.rs:9:5
11+
|
12+
LL | assert_eq!(1, 1)
13+
| ^^^^^^^^^^^^^^^^ expected `i32`, found `()`
14+
|
15+
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
16+
17+
error[E0308]: mismatched types
18+
--> $DIR/assert-macro-without-else.rs:14:5
19+
|
20+
LL | assert_ne!(1, 2)
21+
| ^^^^^^^^^^^^^^^^ expected `bool`, found `()`
22+
|
23+
= note: this error originates in the macro `assert_ne` (in Nightly builds, run with -Z macro-backtrace for more info)
24+
25+
error[E0308]: mismatched types
26+
--> $DIR/assert-macro-without-else.rs:26:9
27+
|
28+
LL | assert!(1 < 2)
29+
| ^^^^^^^^^^^^^^ expected `bool`, found `()`
30+
...
31+
LL | fn nested() -> bool {
32+
| ---- expected `bool` because of this return type
33+
LL | g!()
34+
| ---- in this macro invocation
35+
|
36+
= 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)
37+
38+
error: aborting due to 4 previous errors
39+
40+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)