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 #39968.
This commit is contained in:
parent
d3d28a4920
commit
b0f258b2c4
6 changed files with 44 additions and 10 deletions
|
|
@ -1169,7 +1169,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
fn suggest_fn_call(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
|
||||
points_at_arg: bool,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -553,7 +553,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
pub fn check_for_cast(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
expr: &hir::Expr,
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected_ty: Ty<'tcx>,
|
||||
|
|
|
|||
|
|
@ -583,7 +583,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
} else {
|
||||
assert!(e_ty.is_unit());
|
||||
let ty = coerce.expected_ty();
|
||||
coerce.coerce_forced_unit(self, &cause, &mut |err| {
|
||||
coerce.coerce_forced_unit(self, &cause, &mut |mut err| {
|
||||
self.suggest_mismatched_types_on_tail(
|
||||
&mut err,
|
||||
expr,
|
||||
ty,
|
||||
e_ty,
|
||||
cause.span,
|
||||
target_id,
|
||||
);
|
||||
let val = match ty.kind {
|
||||
ty::Bool => "true",
|
||||
ty::Char => "'a'",
|
||||
|
|
|
|||
|
|
@ -4246,7 +4246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// - Possible missing return type if the return type is the default, and not `fn main()`.
|
||||
pub fn suggest_mismatched_types_on_tail(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
expr: &'tcx hir::Expr,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
|
|
@ -4273,7 +4273,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// ```
|
||||
fn suggest_fn_call(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
expr: &hir::Expr,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
|
|
@ -4386,7 +4386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
pub fn suggest_ref_or_into(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
expr: &hir::Expr,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
|
|
@ -4454,7 +4454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// in the heap by calling `Box::new()`.
|
||||
fn suggest_boxing_when_appropriate(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
expr: &hir::Expr,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
|
|
@ -4498,7 +4498,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// it suggests adding a semicolon.
|
||||
fn suggest_missing_semicolon(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
expression: &'tcx hir::Expr,
|
||||
expected: Ty<'tcx>,
|
||||
cause_span: Span,
|
||||
|
|
@ -4537,7 +4537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// type.
|
||||
fn suggest_missing_return_type(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
fn_decl: &hir::FnDecl,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
|
|
@ -4603,7 +4603,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// `.await` to the tail of the expression.
|
||||
fn suggest_missing_await(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
expr: &hir::Expr,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
|
|
|
|||
8
src/test/ui/type/type-error-break-tail.rs
Normal file
8
src/test/ui/type/type-error-break-tail.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fn loop_ending() -> i32 {
|
||||
loop {
|
||||
if false { break; } //~ ERROR mismatched types
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
18
src/test/ui/type/type-error-break-tail.stderr
Normal file
18
src/test/ui/type/type-error-break-tail.stderr
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/type-error-break-tail.rs:3:20
|
||||
|
|
||||
LL | fn loop_ending() -> i32 {
|
||||
| --- expected `i32` because of return type
|
||||
LL | loop {
|
||||
LL | if false { break; }
|
||||
| ^^^^^
|
||||
| |
|
||||
| expected i32, found ()
|
||||
| help: give it a value of the expected type: `break 42`
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `()`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue