Skip to content

Commit b0f258b

Browse files
committed
Tweak type mismatch caused by break on tail expr
When `break;` has a type mismatch because the `Destination` points at a tail expression with an obligation flowing from a return type, point at the return type. Fix rust-lang#39968.
1 parent d3d28a4 commit b0f258b

File tree

6 files changed

+44
-10
lines changed

6 files changed

+44
-10
lines changed

src/librustc/traits/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11691169
fn suggest_fn_call(
11701170
&self,
11711171
obligation: &PredicateObligation<'tcx>,
1172-
err: &mut DiagnosticBuilder<'tcx>,
1172+
err: &mut DiagnosticBuilder<'_>,
11731173
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
11741174
points_at_arg: bool,
11751175
) {

src/librustc_typeck/check/demand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
553553

554554
pub fn check_for_cast(
555555
&self,
556-
err: &mut DiagnosticBuilder<'tcx>,
556+
err: &mut DiagnosticBuilder<'_>,
557557
expr: &hir::Expr,
558558
checked_ty: Ty<'tcx>,
559559
expected_ty: Ty<'tcx>,

src/librustc_typeck/check/expr.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
583583
} else {
584584
assert!(e_ty.is_unit());
585585
let ty = coerce.expected_ty();
586-
coerce.coerce_forced_unit(self, &cause, &mut |err| {
586+
coerce.coerce_forced_unit(self, &cause, &mut |mut err| {
587+
self.suggest_mismatched_types_on_tail(
588+
&mut err,
589+
expr,
590+
ty,
591+
e_ty,
592+
cause.span,
593+
target_id,
594+
);
587595
let val = match ty.kind {
588596
ty::Bool => "true",
589597
ty::Char => "'a'",

src/librustc_typeck/check/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -4246,7 +4246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
42464246
/// - Possible missing return type if the return type is the default, and not `fn main()`.
42474247
pub fn suggest_mismatched_types_on_tail(
42484248
&self,
4249-
err: &mut DiagnosticBuilder<'tcx>,
4249+
err: &mut DiagnosticBuilder<'_>,
42504250
expr: &'tcx hir::Expr,
42514251
expected: Ty<'tcx>,
42524252
found: Ty<'tcx>,
@@ -4273,7 +4273,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
42734273
/// ```
42744274
fn suggest_fn_call(
42754275
&self,
4276-
err: &mut DiagnosticBuilder<'tcx>,
4276+
err: &mut DiagnosticBuilder<'_>,
42774277
expr: &hir::Expr,
42784278
expected: Ty<'tcx>,
42794279
found: Ty<'tcx>,
@@ -4386,7 +4386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
43864386

43874387
pub fn suggest_ref_or_into(
43884388
&self,
4389-
err: &mut DiagnosticBuilder<'tcx>,
4389+
err: &mut DiagnosticBuilder<'_>,
43904390
expr: &hir::Expr,
43914391
expected: Ty<'tcx>,
43924392
found: Ty<'tcx>,
@@ -4454,7 +4454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
44544454
/// in the heap by calling `Box::new()`.
44554455
fn suggest_boxing_when_appropriate(
44564456
&self,
4457-
err: &mut DiagnosticBuilder<'tcx>,
4457+
err: &mut DiagnosticBuilder<'_>,
44584458
expr: &hir::Expr,
44594459
expected: Ty<'tcx>,
44604460
found: Ty<'tcx>,
@@ -4498,7 +4498,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
44984498
/// it suggests adding a semicolon.
44994499
fn suggest_missing_semicolon(
45004500
&self,
4501-
err: &mut DiagnosticBuilder<'tcx>,
4501+
err: &mut DiagnosticBuilder<'_>,
45024502
expression: &'tcx hir::Expr,
45034503
expected: Ty<'tcx>,
45044504
cause_span: Span,
@@ -4537,7 +4537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
45374537
/// type.
45384538
fn suggest_missing_return_type(
45394539
&self,
4540-
err: &mut DiagnosticBuilder<'tcx>,
4540+
err: &mut DiagnosticBuilder<'_>,
45414541
fn_decl: &hir::FnDecl,
45424542
expected: Ty<'tcx>,
45434543
found: Ty<'tcx>,
@@ -4603,7 +4603,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
46034603
/// `.await` to the tail of the expression.
46044604
fn suggest_missing_await(
46054605
&self,
4606-
err: &mut DiagnosticBuilder<'tcx>,
4606+
err: &mut DiagnosticBuilder<'_>,
46074607
expr: &hir::Expr,
46084608
expected: Ty<'tcx>,
46094609
found: Ty<'tcx>,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn loop_ending() -> i32 {
2+
loop {
3+
if false { break; } //~ ERROR mismatched types
4+
return 42;
5+
}
6+
}
7+
8+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/type-error-break-tail.rs:3:20
3+
|
4+
LL | fn loop_ending() -> i32 {
5+
| --- expected `i32` because of return type
6+
LL | loop {
7+
LL | if false { break; }
8+
| ^^^^^
9+
| |
10+
| expected i32, found ()
11+
| help: give it a value of the expected type: `break 42`
12+
|
13+
= note: expected type `i32`
14+
found type `()`
15+
16+
error: aborting due to previous error
17+
18+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)