Skip to content

Commit

Permalink
Use the correct bound vars in return type suggestion.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Mar 5, 2023
1 parent 0fbfc3e commit 1e9b58b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 24 deletions.
45 changes: 21 additions & 24 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// This routine checks if the return type is left as default, the method is not part of an
/// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
/// type.
#[instrument(level = "trace", skip(self, err))]
pub(in super::super) fn suggest_missing_return_type(
&self,
err: &mut Diagnostic,
Expand Down Expand Up @@ -705,28 +706,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return true
}
}
hir::FnRetTy::Return(ty) => {
let span = ty.span;

if let hir::TyKind::OpaqueDef(item_id, ..) = ty.kind
&& let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(op_ty),
..
}) = self.tcx.hir().get(item_id.hir_id())
&& let hir::OpaqueTy {
bounds: [bound], ..
} = op_ty
&& let hir::GenericBound::LangItemTrait(
hir::LangItem::Future, _, _, generic_args) = bound
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
&& let hir::TypeBinding { kind, .. } = ty_binding
&& let hir::TypeBindingKind::Equality { term } = kind
&& let hir::Term::Ty(term_ty) = term {
hir::FnRetTy::Return(hir_ty) => {
let span = hir_ty.span;

if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
&& let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(op_ty),
..
}) = self.tcx.hir().get(item_id.hir_id())
&& let [hir::GenericBound::LangItemTrait(
hir::LangItem::Future, _, _, generic_args)] = op_ty.bounds
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = ty_binding.kind
{
// Check if async function's return type was omitted.
// Don't emit suggestions if the found type is `impl Future<...>`.
debug!("suggest_missing_return_type: found = {:?}", found);
debug!(?found);
if found.is_suggestable(self.tcx, false) {
if term_ty.span.is_empty() {
if term.span.is_empty() {
err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() });
return true;
} else {
Expand All @@ -737,11 +734,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Only point to return type if the expected type is the return type, as if they
// are not, the expectation must have been caused by something else.
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
let ty = self.astconv().ast_ty_to_ty(ty);
debug!("suggest_missing_return_type: return type {:?}", ty);
debug!("suggest_missing_return_type: expected type {:?}", ty);
let bound_vars = self.tcx.late_bound_vars(fn_id);
debug!("return type {:?}", hir_ty);
let ty = self.astconv().ast_ty_to_ty(hir_ty);
debug!("return type {:?}", ty);
debug!("expected type {:?}", expected);
let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into());
let ty = Binder::bind_with_vars(ty, bound_vars);
let ty = self.normalize(span, ty);
let ty = self.tcx.erase_late_bound_regions(ty);
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/suggestions/issue-107860.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// edition: 2021

async fn str<T>(T: &str) -> &str { &str }
//~^ ERROR mismatched types

fn main() {}
12 changes: 12 additions & 0 deletions tests/ui/suggestions/issue-107860.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0308]: mismatched types
--> $DIR/issue-107860.rs:3:36
|
LL | async fn str<T>(T: &str) -> &str { &str }
| ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<...>}`
|
= note: expected reference `&str`
found reference `&for<'a> fn(&'a str) -> impl Future<Output = &'a str> {str::<_>}`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

0 comments on commit 1e9b58b

Please sign in to comment.