NiceRegionError: Use written return type for async fn
This commit is contained in:
parent
6487845884
commit
5c15ad7fca
13 changed files with 181 additions and 165 deletions
|
@ -65,9 +65,9 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{Item, ItemKind, Node};
|
||||
use rustc_middle::dep_graph::DepContext;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::{
|
||||
self,
|
||||
error::TypeError,
|
||||
subst::{GenericArgKind, Subst, SubstsRef},
|
||||
Binder, Region, Ty, TyCtxt, TypeFoldable,
|
||||
};
|
||||
|
|
|
@ -171,6 +171,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
|
||||
self.suggest_adding_lifetime_params(sub, ty_sup, ty_sub, &mut err);
|
||||
|
||||
// TODO: This is only helpful if the lifetime more visible in the impl Future type than in the signature.
|
||||
if let Some(t) = future_return_type {
|
||||
let snip = self
|
||||
.tcx()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::Node;
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::middle::resolve_lifetime as rl;
|
||||
|
@ -25,25 +24,19 @@ pub(crate) fn find_anon_type<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
region: Region<'tcx>,
|
||||
br: &ty::BoundRegionKind,
|
||||
) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnDecl<'tcx>)> {
|
||||
) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> {
|
||||
if let Some(anon_reg) = tcx.is_suitable_region(region) {
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(anon_reg.def_id);
|
||||
let fndecl = match tcx.hir().get(hir_id) {
|
||||
Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. })
|
||||
| Node::TraitItem(&hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(ref m, ..), ..
|
||||
})
|
||||
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(ref m, ..), .. }) => {
|
||||
&m.decl
|
||||
}
|
||||
_ => return None,
|
||||
let Some(fn_sig) = tcx.hir().get(hir_id).fn_sig() else {
|
||||
return None
|
||||
};
|
||||
|
||||
fndecl
|
||||
fn_sig
|
||||
.decl
|
||||
.inputs
|
||||
.iter()
|
||||
.find_map(|arg| find_component_for_bound_region(tcx, arg, br))
|
||||
.map(|ty| (ty, &**fndecl))
|
||||
.map(|ty| (ty, fn_sig))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::ty::{self, DefIdTree, Region, Ty};
|
||||
use rustc_middle::ty::{self, Binder, DefIdTree, Region, Ty, TypeFoldable};
|
||||
use rustc_span::Span;
|
||||
|
||||
/// Information about the anonymous region we are searching for.
|
||||
|
@ -149,26 +149,41 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Here, we check for the case where the anonymous region
|
||||
// is in the return type.
|
||||
// is in the return type as written by the user.
|
||||
// FIXME(#42703) - Need to handle certain cases here.
|
||||
pub(super) fn is_return_type_anon(
|
||||
&self,
|
||||
scope_def_id: LocalDefId,
|
||||
br: ty::BoundRegionKind,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
hir_sig: &hir::FnSig<'_>,
|
||||
) -> Option<Span> {
|
||||
let ret_ty = self.tcx().type_of(scope_def_id);
|
||||
if let ty::FnDef(_, _) = ret_ty.kind() {
|
||||
let sig = ret_ty.fn_sig(self.tcx());
|
||||
let late_bound_regions =
|
||||
self.tcx().collect_referenced_late_bound_regions(&sig.output());
|
||||
if late_bound_regions.iter().any(|r| *r == br) {
|
||||
return Some(decl.output.span());
|
||||
}
|
||||
let fn_ty = self.tcx().type_of(scope_def_id);
|
||||
if let ty::FnDef(_, _) = fn_ty.kind() {
|
||||
let ret_ty = fn_ty.fn_sig(self.tcx()).output();
|
||||
let span = hir_sig.decl.output.span();
|
||||
let future_output = if hir_sig.header.is_async() {
|
||||
ret_ty.map_bound(|ty| self.infcx.get_impl_future_output_ty(ty)).transpose()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
return match future_output {
|
||||
Some(output) if self.includes_region(output, br) => Some(span),
|
||||
None if self.includes_region(ret_ty, br) => Some(span),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn includes_region(
|
||||
&self,
|
||||
ty: Binder<'tcx, impl TypeFoldable<'tcx>>,
|
||||
region: ty::BoundRegionKind,
|
||||
) -> bool {
|
||||
let late_bound_regions = self.tcx().collect_referenced_late_bound_regions(&ty);
|
||||
late_bound_regions.iter().any(|r| *r == region)
|
||||
}
|
||||
|
||||
// Here we check for the case where anonymous region
|
||||
// corresponds to self and if yes, we display E0312.
|
||||
// FIXME(#42700) - Need to format self properly to
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue