Skip to content

Commit

Permalink
Rollup merge of rust-lang#86666 - ptrojahn:compare_kinds, r=petrochenkov
Browse files Browse the repository at this point in the history
Fix misleading "impl Trait" error

The kinds can't be compared directly, as types with references are treated as different because the lifetimes aren't bound in ty, but are in expected.
Closes rust-lang#84160
  • Loading branch information
GuillaumeGomez committed Jul 1, 2021
2 parents dfd30d7 + 61554bc commit 7e27209
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 3 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
16 changes: 13 additions & 3 deletions compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
Expand Down Expand Up @@ -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).
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/extern/extern-types-distinct-types.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`
|
Expand Down
3 changes: 3 additions & 0 deletions src/test/ui/retslot-cast.stderr
Original file line number Diff line number Diff line change
@@ -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`
|
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/typeck/issue-84160.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fn mismatched_types_with_reference(x: &u32) -> &u32 {
if false {
return x;
}
return "test";
//~^ERROR mismatched types
}

fn main() {}
15 changes: 15 additions & 0 deletions src/test/ui/typeck/issue-84160.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 7e27209

Please sign in to comment.