Point to return span when writing return;
on non-() fn
This commit is contained in:
parent
f4a421ee3c
commit
59f643fc5f
6 changed files with 37 additions and 6 deletions
|
@ -1979,6 +1979,15 @@ pub enum FunctionRetTy {
|
|||
Return(P<Ty>),
|
||||
}
|
||||
|
||||
impl fmt::Display for FunctionRetTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Return(ref ty) => print::to_string(print::NO_ANN, |s| s.print_type(ty)).fmt(f),
|
||||
DefaultReturn(_) => "()".fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FunctionRetTy {
|
||||
pub fn span(&self) -> Span {
|
||||
match *self {
|
||||
|
|
|
@ -1143,7 +1143,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
|||
// `expression_ty` will be unit).
|
||||
//
|
||||
// Another example is `break` with no argument expression.
|
||||
assert!(expression_ty.is_unit());
|
||||
assert!(expression_ty.is_unit(), "if let hack without unit type");
|
||||
fcx.at(cause, fcx.param_env)
|
||||
.eq_exp(label_expression_as_expected, expression_ty, self.merged_ty())
|
||||
|
@ -1190,7 +1189,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
|||
db = struct_span_err!(
|
||||
fcx.tcx.sess, cause.span, E0069,
|
||||
"`return;` in a function whose return type is not `()`");
|
||||
db.span_label(cause.span, "return type is not ()");
|
||||
db.span_label(cause.span, "return type is not `()`");
|
||||
}
|
||||
ObligationCauseCode::BlockTailExpression(blk_id) => {
|
||||
db = fcx.report_mismatched_types(cause, expected, found, err);
|
||||
|
|
|
@ -4103,7 +4103,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
} else {
|
||||
let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
|
||||
let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
|
||||
coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
|
||||
if let Some((fn_decl, _)) = self.get_fn_decl(expr.id) {
|
||||
coercion.coerce_forced_unit(
|
||||
self,
|
||||
&cause,
|
||||
&mut |db| {
|
||||
db.span_label(
|
||||
fn_decl.output.span(),
|
||||
format!(
|
||||
"expected `{}` because of this return type",
|
||||
fn_decl.output,
|
||||
),
|
||||
);
|
||||
},
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
|
||||
}
|
||||
}
|
||||
tcx.types.never
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
error[E0069]: `return;` in a function whose return type is not `()`
|
||||
--> $DIR/E0069.rs:12:5
|
||||
|
|
||||
LL | fn foo() -> u8 {
|
||||
| -- expected `u8` because of this return type
|
||||
LL | return;
|
||||
| ^^^^^^ return type is not ()
|
||||
| ^^^^^^ return type is not `()`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@ error[E0069]: `return;` in a function whose return type is not `()`
|
|||
--> $DIR/ret-non-nil.rs:15:19
|
||||
|
|
||||
LL | fn g() -> isize { return; }
|
||||
| ^^^^^^ return type is not ()
|
||||
| ----- ^^^^^^ return type is not `()`
|
||||
| |
|
||||
| expected `isize` because of this return type
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
error[E0069]: `return;` in a function whose return type is not `()`
|
||||
--> $DIR/return-unit-from-diverging.rs:15:5
|
||||
|
|
||||
LL | fn fail() -> ! {
|
||||
| - expected `!` because of this return type
|
||||
LL | return; //~ ERROR in a function whose return type is not
|
||||
| ^^^^^^ return type is not ()
|
||||
| ^^^^^^ return type is not `()`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue