parent
117799b73c
commit
61554bc9d7
6 changed files with 43 additions and 3 deletions
|
@ -1481,6 +1481,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
|||
expected,
|
||||
found,
|
||||
can_suggest,
|
||||
fcx.tcx.hir().get_parent_item(id),
|
||||
);
|
||||
}
|
||||
if !pointing_at_return_type {
|
||||
|
|
|
@ -52,9 +52,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
let mut pointing_at_return_type = false;
|
||||
if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
|
||||
pointing_at_return_type =
|
||||
self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
|
||||
let fn_id = self.tcx.hir().get_return_block(blk_id).unwrap();
|
||||
pointing_at_return_type = self.suggest_missing_return_type(
|
||||
err,
|
||||
&fn_decl,
|
||||
expected,
|
||||
found,
|
||||
can_suggest,
|
||||
fn_id,
|
||||
);
|
||||
self.suggest_missing_break_or_return_expr(
|
||||
err, expr, &fn_decl, expected, found, blk_id, fn_id,
|
||||
);
|
||||
|
@ -433,6 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
can_suggest: bool,
|
||||
fn_id: hir::HirId,
|
||||
) -> bool {
|
||||
// Only suggest changing the return type for methods that
|
||||
// haven't set a return type at all (and aren't `fn main()` or an impl).
|
||||
|
@ -465,7 +472,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty);
|
||||
debug!("suggest_missing_return_type: return type {:?}", ty);
|
||||
debug!("suggest_missing_return_type: expected type {:?}", ty);
|
||||
if ty.kind() == expected.kind() {
|
||||
let bound_vars = self.tcx.late_bound_vars(fn_id);
|
||||
let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
|
||||
let ty = self.normalize_associated_types_in(sp, ty);
|
||||
if self.can_coerce(expected, ty) {
|
||||
err.span_label(sp, format!("expected `{}` because of return type", expected));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ LL | type A;
|
|||
LL | type B;
|
||||
| ------- the expected foreign type
|
||||
...
|
||||
LL | fn foo(r: &A) -> &B {
|
||||
| -- expected `&B` because of return type
|
||||
LL | r
|
||||
| ^ expected extern type `B`, found extern type `A`
|
||||
|
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/retslot-cast.rs:13:5
|
||||
|
|
||||
LL | -> Option<&Iterator<Item=()>> {
|
||||
| -------------------------- expected `Option<&dyn Iterator<Item = ()>>` because of return type
|
||||
...
|
||||
LL | inner(x)
|
||||
| ^^^^^^^^ expected trait `Iterator<Item = ()>`, found trait `Iterator<Item = ()> + Send`
|
||||
|
|
||||
|
|
9
src/test/ui/typeck/issue-84160.rs
Normal file
9
src/test/ui/typeck/issue-84160.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
fn mismatched_types_with_reference(x: &u32) -> &u32 {
|
||||
if false {
|
||||
return x;
|
||||
}
|
||||
return "test";
|
||||
//~^ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
15
src/test/ui/typeck/issue-84160.stderr
Normal file
15
src/test/ui/typeck/issue-84160.stderr
Normal file
|
@ -0,0 +1,15 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-84160.rs:5:12
|
||||
|
|
||||
LL | fn mismatched_types_with_reference(x: &u32) -> &u32 {
|
||||
| ---- expected `&u32` because of return type
|
||||
...
|
||||
LL | return "test";
|
||||
| ^^^^^^ expected `u32`, found `str`
|
||||
|
|
||||
= note: expected reference `&u32`
|
||||
found reference `&'static str`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in a new issue