1
Fork 0

Add hint for missing lifetime bound on trait object when type alias is used

This commit is contained in:
yanchen4791 2022-12-05 16:51:49 -08:00
parent c8e6a9e8b6
commit 62a1e76d2b
6 changed files with 176 additions and 19 deletions

View file

@ -813,17 +813,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if *outlived_f != ty::ReStatic {
return;
}
let suitable_region = self.infcx.tcx.is_suitable_region(f);
let Some(suitable_region) = suitable_region else { return; };
let fn_returns = self
.infcx
.tcx
.is_suitable_region(f)
.map(|r| self.infcx.tcx.return_type_impl_or_dyn_traits(r.def_id))
.unwrap_or_default();
if fn_returns.is_empty() {
return;
}
let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.def_id);
let param = if let Some(param) = find_param_with_region(self.infcx.tcx, f, outlived_f) {
param
@ -839,15 +832,43 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
let captures = format!("captures data from {arg}");
return nice_region_error::suggest_new_region_bound(
self.infcx.tcx,
diag,
fn_returns,
lifetime.to_string(),
Some(arg),
captures,
Some((param.param_ty_span, param.param_ty.to_string())),
self.infcx.tcx.is_suitable_region(f).map(|r| r.def_id),
if !fn_returns.is_empty() {
nice_region_error::suggest_new_region_bound(
self.infcx.tcx,
diag,
fn_returns,
lifetime.to_string(),
Some(arg),
captures,
Some((param.param_ty_span, param.param_ty.to_string())),
Some(suitable_region.def_id),
);
return;
}
let Some((alias_tys, alias_span)) = self
.infcx
.tcx
.return_type_impl_or_dyn_traits_with_type_alias(suitable_region.def_id) else { return; };
// in case the return type of the method is a type alias
let mut spans_suggs: Vec<_> = Vec::new();
for alias_ty in alias_tys {
if alias_ty.span.desugaring_kind().is_some() {
// Skip `async` desugaring `impl Future`.
()
}
if let TyKind::TraitObject(_, lt, _) = alias_ty.kind {
spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
}
}
spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string()));
diag.multipart_suggestion_verbose(
&format!(
"to declare that the trait object {captures}, you can add a lifetime parameter `'a` in the type alias"
),
spans_suggs,
Applicability::MaybeIncorrect,
);
}
}