Point to return span when writing return; on non-() fn

This commit is contained in:
Esteban Küber 2018-12-20 14:00:30 -08:00
parent f4a421ee3c
commit 59f643fc5f
6 changed files with 37 additions and 6 deletions

View file

@ -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 {

View file

@ -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);

View file

@ -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
}

View file

@ -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

View file

@ -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

View file

@ -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