Rollup merge of #108775 - cjgillot:issue-107860, r=compiler-errors

Use the correct bound vars in return type suggestion.

Fixes https://github.com/rust-lang/rust/issues/107860
This commit is contained in:
Matthias Krüger 2023-03-05 20:57:23 +01:00 committed by GitHub
commit 5c49f0885e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 23 deletions

View File

@ -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 /// 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 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
/// type. /// type.
#[instrument(level = "trace", skip(self, err))]
pub(in super::super) fn suggest_missing_return_type( pub(in super::super) fn suggest_missing_return_type(
&self, &self,
err: &mut Diagnostic, err: &mut Diagnostic,
@ -705,28 +706,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return true return true
} }
} }
hir::FnRetTy::Return(ty) => { hir::FnRetTy::Return(hir_ty) => {
let span = ty.span; let span = hir_ty.span;
if let hir::TyKind::OpaqueDef(item_id, ..) = ty.kind if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
&& let hir::Node::Item(hir::Item { && let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(op_ty), kind: hir::ItemKind::OpaqueTy(op_ty),
.. ..
}) = self.tcx.hir().get(item_id.hir_id()) }) = self.tcx.hir().get(item_id.hir_id())
&& let hir::OpaqueTy { && let [hir::GenericBound::LangItemTrait(
bounds: [bound], .. hir::LangItem::Future, _, _, generic_args)] = op_ty.bounds
} = op_ty
&& let hir::GenericBound::LangItemTrait(
hir::LangItem::Future, _, _, generic_args) = bound
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args && let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
&& let hir::TypeBinding { kind, .. } = ty_binding && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = ty_binding.kind
&& let hir::TypeBindingKind::Equality { term } = kind {
&& let hir::Term::Ty(term_ty) = term {
// Check if async function's return type was omitted. // Check if async function's return type was omitted.
// Don't emit suggestions if the found type is `impl Future<...>`. // 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 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() }); err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() });
return true; return true;
} else { } else {
@ -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 // 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. // are not, the expectation must have been caused by something else.
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind); debug!("return type {:?}", hir_ty);
let ty = self.astconv().ast_ty_to_ty(ty); let ty = self.astconv().ast_ty_to_ty(hir_ty);
debug!("suggest_missing_return_type: return type {:?}", ty); debug!("return type {:?}", ty);
debug!("suggest_missing_return_type: expected type {:?}", ty); debug!("expected type {:?}", expected);
let bound_vars = self.tcx.late_bound_vars(fn_id); 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 = Binder::bind_with_vars(ty, bound_vars);
let ty = self.normalize(span, ty); let ty = self.normalize(span, ty);
let ty = self.tcx.erase_late_bound_regions(ty); let ty = self.tcx.erase_late_bound_regions(ty);

View File

@ -0,0 +1,6 @@
// edition: 2021
async fn str<T>(T: &str) -> &str { &str }
//~^ ERROR mismatched types
fn main() {}

View File

@ -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`.