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:
commit
5c49f0885e
@ -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);
|
||||||
|
6
tests/ui/suggestions/issue-107860.rs
Normal file
6
tests/ui/suggestions/issue-107860.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// edition: 2021
|
||||||
|
|
||||||
|
async fn str<T>(T: &str) -> &str { &str }
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
|
||||||
|
fn main() {}
|
12
tests/ui/suggestions/issue-107860.stderr
Normal file
12
tests/ui/suggestions/issue-107860.stderr
Normal 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`.
|
Loading…
x
Reference in New Issue
Block a user