Skip to content

Commit 5c49f08

Browse files
authored
Rollup merge of #108775 - cjgillot:issue-107860, r=compiler-errors
Use the correct bound vars in return type suggestion. Fixes #107860
2 parents 7125df0 + 1e9b58b commit 5c49f08

File tree

3 files changed

+39
-24
lines changed

3 files changed

+39
-24
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+21-24
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
669669
/// This routine checks if the return type is left as default, the method is not part of an
670670
/// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
671671
/// type.
672+
#[instrument(level = "trace", skip(self, err))]
672673
pub(in super::super) fn suggest_missing_return_type(
673674
&self,
674675
err: &mut Diagnostic,
@@ -705,28 +706,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
705706
return true
706707
}
707708
}
708-
hir::FnRetTy::Return(ty) => {
709-
let span = ty.span;
710-
711-
if let hir::TyKind::OpaqueDef(item_id, ..) = ty.kind
712-
&& let hir::Node::Item(hir::Item {
713-
kind: hir::ItemKind::OpaqueTy(op_ty),
714-
..
715-
}) = self.tcx.hir().get(item_id.hir_id())
716-
&& let hir::OpaqueTy {
717-
bounds: [bound], ..
718-
} = op_ty
719-
&& let hir::GenericBound::LangItemTrait(
720-
hir::LangItem::Future, _, _, generic_args) = bound
721-
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
722-
&& let hir::TypeBinding { kind, .. } = ty_binding
723-
&& let hir::TypeBindingKind::Equality { term } = kind
724-
&& let hir::Term::Ty(term_ty) = term {
709+
hir::FnRetTy::Return(hir_ty) => {
710+
let span = hir_ty.span;
711+
712+
if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
713+
&& let hir::Node::Item(hir::Item {
714+
kind: hir::ItemKind::OpaqueTy(op_ty),
715+
..
716+
}) = self.tcx.hir().get(item_id.hir_id())
717+
&& let [hir::GenericBound::LangItemTrait(
718+
hir::LangItem::Future, _, _, generic_args)] = op_ty.bounds
719+
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
720+
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = ty_binding.kind
721+
{
725722
// Check if async function's return type was omitted.
726723
// Don't emit suggestions if the found type is `impl Future<...>`.
727-
debug!("suggest_missing_return_type: found = {:?}", found);
724+
debug!(?found);
728725
if found.is_suggestable(self.tcx, false) {
729-
if term_ty.span.is_empty() {
726+
if term.span.is_empty() {
730727
err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() });
731728
return true;
732729
} else {
@@ -737,11 +734,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
737734

738735
// Only point to return type if the expected type is the return type, as if they
739736
// are not, the expectation must have been caused by something else.
740-
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
741-
let ty = self.astconv().ast_ty_to_ty(ty);
742-
debug!("suggest_missing_return_type: return type {:?}", ty);
743-
debug!("suggest_missing_return_type: expected type {:?}", ty);
744-
let bound_vars = self.tcx.late_bound_vars(fn_id);
737+
debug!("return type {:?}", hir_ty);
738+
let ty = self.astconv().ast_ty_to_ty(hir_ty);
739+
debug!("return type {:?}", ty);
740+
debug!("expected type {:?}", expected);
741+
let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into());
745742
let ty = Binder::bind_with_vars(ty, bound_vars);
746743
let ty = self.normalize(span, ty);
747744
let ty = self.tcx.erase_late_bound_regions(ty);

tests/ui/suggestions/issue-107860.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// edition: 2021
2+
3+
async fn str<T>(T: &str) -> &str { &str }
4+
//~^ ERROR mismatched types
5+
6+
fn main() {}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-107860.rs:3:36
3+
|
4+
LL | async fn str<T>(T: &str) -> &str { &str }
5+
| ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<...>}`
6+
|
7+
= note: expected reference `&str`
8+
found reference `&for<'a> fn(&'a str) -> impl Future<Output = &'a str> {str::<_>}`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)