Point at coercion source on type errors for fn returning impl Trait
This commit is contained in:
parent
59f643fc5f
commit
cdbccf50a7
4 changed files with 29 additions and 0 deletions
|
@ -1183,6 +1183,11 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
||||||
(self.final_ty.unwrap_or(self.expected_ty), expression_ty)
|
(self.final_ty.unwrap_or(self.expected_ty), expression_ty)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let reason_label = if label_expression_as_expected {
|
||||||
|
"found because of this statement"
|
||||||
|
} else {
|
||||||
|
"expected because of this statement"
|
||||||
|
};
|
||||||
let mut db;
|
let mut db;
|
||||||
match cause.code {
|
match cause.code {
|
||||||
ObligationCauseCode::ReturnNoExpression => {
|
ObligationCauseCode::ReturnNoExpression => {
|
||||||
|
@ -1207,9 +1212,19 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
||||||
cause.span,
|
cause.span,
|
||||||
blk_id,
|
blk_id,
|
||||||
);
|
);
|
||||||
|
if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
|
||||||
|
if !sp.overlaps(cause.span) {
|
||||||
|
db.span_label(*sp, reason_label);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
db = fcx.report_mismatched_types(cause, expected, found, err);
|
db = fcx.report_mismatched_types(cause, expected, found, err);
|
||||||
|
if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
|
||||||
|
if !sp.overlaps(cause.span) {
|
||||||
|
db.span_label(*sp, reason_label);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -535,6 +535,7 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||||
err_count_on_creation: usize,
|
err_count_on_creation: usize,
|
||||||
|
|
||||||
ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
|
ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
|
||||||
|
ret_coercion_span: RefCell<Option<Span>>,
|
||||||
|
|
||||||
yield_ty: Option<Ty<'tcx>>,
|
yield_ty: Option<Ty<'tcx>>,
|
||||||
|
|
||||||
|
@ -1984,6 +1985,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
param_env,
|
param_env,
|
||||||
err_count_on_creation: inh.tcx.sess.err_count(),
|
err_count_on_creation: inh.tcx.sess.err_count(),
|
||||||
ret_coercion: None,
|
ret_coercion: None,
|
||||||
|
ret_coercion_span: RefCell::new(None),
|
||||||
yield_ty: None,
|
yield_ty: None,
|
||||||
ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
|
ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
|
||||||
ast::CRATE_NODE_ID)),
|
ast::CRATE_NODE_ID)),
|
||||||
|
@ -4099,9 +4101,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
struct_span_err!(self.tcx.sess, expr.span, E0572,
|
struct_span_err!(self.tcx.sess, expr.span, E0572,
|
||||||
"return statement outside of function body").emit();
|
"return statement outside of function body").emit();
|
||||||
} else if let Some(ref e) = *expr_opt {
|
} else if let Some(ref e) = *expr_opt {
|
||||||
|
*self.ret_coercion_span.borrow_mut() = Some(e.span);
|
||||||
self.check_return_expr(e);
|
self.check_return_expr(e);
|
||||||
} else {
|
} else {
|
||||||
let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
|
let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
|
||||||
|
*self.ret_coercion_span.borrow_mut() = Some(expr.span);
|
||||||
let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
|
let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
|
||||||
if let Some((fn_decl, _)) = self.get_fn_decl(expr.id) {
|
if let Some((fn_decl, _)) = self.get_fn_decl(expr.id) {
|
||||||
coercion.coerce_forced_unit(
|
coercion.coerce_forced_unit(
|
||||||
|
|
|
@ -331,6 +331,13 @@ impl Span {
|
||||||
span.lo <= other.lo && other.hi <= span.hi
|
span.lo <= other.lo && other.hi <= span.hi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return `true` if `self` touches `other`.
|
||||||
|
pub fn overlaps(self, other: Span) -> bool {
|
||||||
|
let span = self.data();
|
||||||
|
let other = other.data();
|
||||||
|
span.lo < other.hi && other.lo < span.hi
|
||||||
|
}
|
||||||
|
|
||||||
/// Return true if the spans are equal with regards to the source text.
|
/// Return true if the spans are equal with regards to the source text.
|
||||||
///
|
///
|
||||||
/// Use this instead of `==` when either span could be generated code,
|
/// Use this instead of `==` when either span could be generated code,
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/equality.rs:25:5
|
--> $DIR/equality.rs:25:5
|
||||||
|
|
|
|
||||||
|
LL | return 1_i32;
|
||||||
|
| ----- expected because of this statement
|
||||||
|
LL | }
|
||||||
LL | 0_u32
|
LL | 0_u32
|
||||||
| ^^^^^ expected i32, found u32
|
| ^^^^^ expected i32, found u32
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue