1
Fork 0

Apply suggestions from review

This commit is contained in:
Michael Goulet 2024-01-26 19:18:14 +00:00
parent dc050f6d5b
commit 720d7a7a03
11 changed files with 77 additions and 50 deletions

View file

@ -33,7 +33,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
/// our special inference variable there, we would mess that up. /// our special inference variable there, we would mess that up.
region_bound_pairs: &'a RegionBoundPairs<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
param_env: ty::ParamEnv<'tcx>, known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
locations: Locations, locations: Locations,
span: Span, span: Span,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
@ -47,7 +47,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
universal_regions: &'a UniversalRegions<'tcx>, universal_regions: &'a UniversalRegions<'tcx>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
param_env: ty::ParamEnv<'tcx>, known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
locations: Locations, locations: Locations,
span: Span, span: Span,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
@ -59,7 +59,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
universal_regions, universal_regions,
region_bound_pairs, region_bound_pairs,
implicit_region_bound, implicit_region_bound,
param_env, known_type_outlives_obligations,
locations, locations,
span, span,
category, category,
@ -136,7 +136,11 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
// Extract out various useful fields we'll need below. // Extract out various useful fields we'll need below.
let ConstraintConversion { let ConstraintConversion {
tcx, region_bound_pairs, implicit_region_bound, param_env, .. tcx,
region_bound_pairs,
implicit_region_bound,
known_type_outlives_obligations,
..
} = *self; } = *self;
let ty::OutlivesPredicate(k1, r2) = predicate; let ty::OutlivesPredicate(k1, r2) = predicate;
@ -157,8 +161,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
tcx, tcx,
region_bound_pairs, region_bound_pairs,
Some(implicit_region_bound), Some(implicit_region_bound),
// FIXME(-Znext-solver): These bounds are not normalized! known_type_outlives_obligations,
param_env.caller_bounds(),
) )
.type_must_outlive(origin, t1, r2, constraint_category); .type_must_outlive(origin, t1, r2, constraint_category);
} }

View file

@ -45,12 +45,14 @@ type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
pub(crate) struct CreateResult<'tcx> { pub(crate) struct CreateResult<'tcx> {
pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>, pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>,
pub(crate) known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>, pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
} }
pub(crate) fn create<'tcx>( pub(crate) fn create<'tcx>(
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
universal_regions: &Rc<UniversalRegions<'tcx>>, universal_regions: &Rc<UniversalRegions<'tcx>>,
constraints: &mut MirTypeckRegionConstraints<'tcx>, constraints: &mut MirTypeckRegionConstraints<'tcx>,
@ -58,6 +60,7 @@ pub(crate) fn create<'tcx>(
UniversalRegionRelationsBuilder { UniversalRegionRelationsBuilder {
infcx, infcx,
param_env, param_env,
known_type_outlives_obligations,
implicit_region_bound, implicit_region_bound,
constraints, constraints,
universal_regions: universal_regions.clone(), universal_regions: universal_regions.clone(),
@ -175,6 +178,7 @@ impl UniversalRegionRelations<'_> {
struct UniversalRegionRelationsBuilder<'this, 'tcx> { struct UniversalRegionRelationsBuilder<'this, 'tcx> {
infcx: &'this InferCtxt<'tcx>, infcx: &'this InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
universal_regions: Rc<UniversalRegions<'tcx>>, universal_regions: Rc<UniversalRegions<'tcx>>,
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
constraints: &'this mut MirTypeckRegionConstraints<'tcx>, constraints: &'this mut MirTypeckRegionConstraints<'tcx>,
@ -200,7 +204,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
let defining_ty_def_id = self.universal_regions.defining_ty.def_id().expect_local(); let defining_ty_def_id = self.universal_regions.defining_ty.def_id().expect_local();
let span = tcx.def_span(defining_ty_def_id); let span = tcx.def_span(defining_ty_def_id);
// Insert the facts we know from the predicates. Why? Why not. // Insert the `'a: 'b` we know from the predicates.
// This does not consider the type-outlives.
let param_env = self.param_env; let param_env = self.param_env;
self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env)); self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env));
@ -308,6 +313,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
outlives: self.outlives.freeze(), outlives: self.outlives.freeze(),
inverse_outlives: self.inverse_outlives.freeze(), inverse_outlives: self.inverse_outlives.freeze(),
}), }),
known_type_outlives_obligations: self.known_type_outlives_obligations,
region_bound_pairs: self.region_bound_pairs, region_bound_pairs: self.region_bound_pairs,
normalized_inputs_and_output, normalized_inputs_and_output,
} }
@ -322,7 +328,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
&self.universal_regions, &self.universal_regions,
&self.region_bound_pairs, &self.region_bound_pairs,
self.implicit_region_bound, self.implicit_region_bound,
self.param_env, self.known_type_outlives_obligations,
Locations::All(span), Locations::All(span),
span, span,
ConstraintCategory::Internal, ConstraintCategory::Internal,

View file

@ -152,9 +152,14 @@ pub(crate) fn type_check<'mir, 'tcx>(
universal_region_relations, universal_region_relations,
region_bound_pairs, region_bound_pairs,
normalized_inputs_and_output, normalized_inputs_and_output,
known_type_outlives_obligations,
} = free_region_relations::create( } = free_region_relations::create(
infcx, infcx,
param_env, param_env,
// FIXME(-Znext-solver): These are unnormalized. Normalize them.
infcx.tcx.arena.alloc_from_iter(
param_env.caller_bounds().iter().filter_map(|clause| clause.as_type_outlives_clause()),
),
implicit_region_bound, implicit_region_bound,
universal_regions, universal_regions,
&mut constraints, &mut constraints,
@ -176,6 +181,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
body, body,
param_env, param_env,
&region_bound_pairs, &region_bound_pairs,
known_type_outlives_obligations,
implicit_region_bound, implicit_region_bound,
&mut borrowck_context, &mut borrowck_context,
); );
@ -850,6 +856,7 @@ struct TypeChecker<'a, 'tcx> {
/// all of the promoted items. /// all of the promoted items.
user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>,
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
reported_errors: FxIndexSet<(Ty<'tcx>, Span)>, reported_errors: FxIndexSet<(Ty<'tcx>, Span)>,
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
@ -1000,6 +1007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>,
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
) -> Self { ) -> Self {
@ -1010,6 +1018,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
user_type_annotations: &body.user_type_annotations, user_type_annotations: &body.user_type_annotations,
param_env, param_env,
region_bound_pairs, region_bound_pairs,
known_type_outlives_obligations,
implicit_region_bound, implicit_region_bound,
borrowck_context, borrowck_context,
reported_errors: Default::default(), reported_errors: Default::default(),
@ -1127,7 +1136,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.borrowck_context.universal_regions, self.borrowck_context.universal_regions,
self.region_bound_pairs, self.region_bound_pairs,
self.implicit_region_bound, self.implicit_region_bound,
self.param_env, self.known_type_outlives_obligations,
locations, locations,
locations.span(self.body), locations.span(self.body),
category, category,
@ -2731,7 +2740,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.borrowck_context.universal_regions, self.borrowck_context.universal_regions,
self.region_bound_pairs, self.region_bound_pairs,
self.implicit_region_bound, self.implicit_region_bound,
self.param_env, self.known_type_outlives_obligations,
locations, locations,
DUMMY_SP, // irrelevant; will be overridden. DUMMY_SP, // irrelevant; will be overridden.
ConstraintCategory::Boring, // same as above. ConstraintCategory::Boring, // same as above.

View file

@ -189,7 +189,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
RegionResolutionError::UpperBoundUniverseConflict(a, _, _, _, b) => { RegionResolutionError::UpperBoundUniverseConflict(a, _, _, _, b) => {
format!("{b}: {a}", a = ty::Region::new_var(tcx, a)) format!("{b}: {a}", a = ty::Region::new_var(tcx, a))
} }
RegionResolutionError::CannotNormalize(..) => todo!(), RegionResolutionError::CannotNormalize(..) => unreachable!(),
}; };
guar = Some( guar = Some(
struct_span_code_err!( struct_span_code_err!(

View file

@ -1,7 +1,7 @@
//! Various code related to computing outlives relations. //! Various code related to computing outlives relations.
use self::env::OutlivesEnvironment; use self::env::OutlivesEnvironment;
use super::region_constraints::RegionConstraintData; use super::region_constraints::RegionConstraintData;
use super::{InferCtxt, RegionResolutionError}; use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
use crate::infer::free_regions::RegionRelations; use crate::infer::free_regions::RegionRelations;
use crate::infer::lexical_region_resolve; use crate::infer::lexical_region_resolve;
use rustc_middle::traits::query::OutlivesBound; use rustc_middle::traits::query::OutlivesBound;
@ -42,14 +42,14 @@ impl<'tcx> InferCtxt<'tcx> {
/// done -- or the compiler will panic -- but it is legal to use /// done -- or the compiler will panic -- but it is legal to use
/// `resolve_vars_if_possible` as well as `fully_resolve`. /// `resolve_vars_if_possible` as well as `fully_resolve`.
/// ///
/// If you are in a crate that has access to `rustc_trai_selection`, /// If you are in a crate that has access to `rustc_trait_selection`,
/// then it's probably better to use `resolve_regions_normalizing_outlives_obligations`, /// then it's probably better to use `resolve_regions`,
/// which knows how to normalize registered region obligations. /// which knows how to normalize registered region obligations.
#[must_use] #[must_use]
pub fn resolve_regions_with_normalize( pub fn resolve_regions_with_normalize(
&self, &self,
outlives_env: &OutlivesEnvironment<'tcx>, outlives_env: &OutlivesEnvironment<'tcx>,
deeply_normalize_ty: impl Fn(Ty<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>, deeply_normalize_ty: impl Fn(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>,
) -> Vec<RegionResolutionError<'tcx>> { ) -> Vec<RegionResolutionError<'tcx>> {
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) { match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
Ok(()) => {} Ok(()) => {}

View file

@ -68,8 +68,8 @@ use crate::infer::{
use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::traits::{ObligationCause, ObligationCauseCode};
use rustc_data_structures::undo_log::UndoLogs; use rustc_data_structures::undo_log::UndoLogs;
use rustc_middle::mir::ConstraintCategory; use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{GenericArgKind, ToPredicate};
use rustc_span::DUMMY_SP; use rustc_span::DUMMY_SP;
use smallvec::smallvec; use smallvec::smallvec;
@ -128,7 +128,7 @@ impl<'tcx> InferCtxt<'tcx> {
pub fn process_registered_region_obligations<E>( pub fn process_registered_region_obligations<E>(
&self, &self,
outlives_env: &OutlivesEnvironment<'tcx>, outlives_env: &OutlivesEnvironment<'tcx>,
mut deeply_normalize_ty: impl FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>, mut deeply_normalize_ty: impl FnMut(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, E>,
) -> Result<(), (E, SubregionOrigin<'tcx>)> { ) -> Result<(), (E, SubregionOrigin<'tcx>)> {
assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot"); assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
@ -141,20 +141,23 @@ impl<'tcx> InferCtxt<'tcx> {
let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else { let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else {
return None; return None;
}; };
Some(deeply_normalize_ty(outlives.0).map(|ty| { Some(
bound_clause deeply_normalize_ty(
.rebind(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, outlives.1))) outlives.0,
.to_predicate(self.tcx) SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP),
})) )
.map(|ty| bound_clause.rebind(ty::OutlivesPredicate(ty, outlives.1))),
)
}) })
// FIXME: How do we accurately report an error here :( // FIXME(-Znext-solver): How do we accurately report an error here :(
.try_collect() .try_collect()
.map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?; .map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?;
let my_region_obligations = self.take_registered_region_obligations(); let my_region_obligations = self.take_registered_region_obligations();
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations { for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
let sup_type = deeply_normalize_ty(sup_type).map_err(|e| (e, origin.clone()))?; let sup_type =
deeply_normalize_ty(sup_type, origin.clone()).map_err(|e| (e, origin.clone()))?;
debug!(?sup_type, ?sub_region, ?origin); debug!(?sup_type, ?sub_region, ?origin);
let outlives = &mut TypeOutlives::new( let outlives = &mut TypeOutlives::new(
@ -216,7 +219,7 @@ where
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
region_bound_pairs: &'cx RegionBoundPairs<'tcx>, region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
implicit_region_bound: Option<ty::Region<'tcx>>, implicit_region_bound: Option<ty::Region<'tcx>>,
caller_bounds: &'cx [ty::Clause<'tcx>], caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
) -> Self { ) -> Self {
Self { Self {
delegate, delegate,

View file

@ -23,7 +23,7 @@ pub struct VerifyBoundCx<'cx, 'tcx> {
/// Outside of borrowck the only way to prove `T: '?0` is by /// Outside of borrowck the only way to prove `T: '?0` is by
/// setting `'?0` to `'empty`. /// setting `'?0` to `'empty`.
implicit_region_bound: Option<ty::Region<'tcx>>, implicit_region_bound: Option<ty::Region<'tcx>>,
caller_bounds: &'cx [ty::Clause<'tcx>], caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
} }
impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
@ -31,7 +31,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
region_bound_pairs: &'cx RegionBoundPairs<'tcx>, region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
implicit_region_bound: Option<ty::Region<'tcx>>, implicit_region_bound: Option<ty::Region<'tcx>>,
caller_bounds: &'cx [ty::Clause<'tcx>], caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
) -> Self { ) -> Self {
Self { tcx, region_bound_pairs, implicit_region_bound, caller_bounds } Self { tcx, region_bound_pairs, implicit_region_bound, caller_bounds }
} }
@ -219,8 +219,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
// To start, collect bounds from user environment. Note that // To start, collect bounds from user environment. Note that
// parameter environments are already elaborated, so we don't // parameter environments are already elaborated, so we don't
// have to worry about that. // have to worry about that.
let param_bounds = let param_bounds = self.caller_bounds.iter().copied().filter(move |outlives_predicate| {
self.collect_outlives_from_clause_list(erased_ty, self.caller_bounds.iter().copied()); super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty)
});
// Next, collect regions we scraped from the well-formedness // Next, collect regions we scraped from the well-formedness
// constraints in the fn signature. To do that, we walk the list // constraints in the fn signature. To do that, we walk the list
@ -307,22 +308,4 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
.filter_map(|p| p.no_bound_vars()) .filter_map(|p| p.no_bound_vars())
.map(|OutlivesPredicate(_, r)| r) .map(|OutlivesPredicate(_, r)| r)
} }
/// Searches through a predicate list for a predicate `T: 'a`.
///
/// Careful: does not elaborate predicates, and just uses `==`
/// when comparing `ty` for equality, so `ty` must be something
/// that does not involve inference variables and where you
/// otherwise want a precise match.
fn collect_outlives_from_clause_list(
&self,
erased_ty: Ty<'tcx>,
clauses: impl Iterator<Item = ty::Clause<'tcx>>,
) -> impl Iterator<Item = ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>>
{
let tcx = self.tcx;
clauses.filter_map(|p| p.as_type_outlives_clause()).filter(move |outlives_predicate| {
super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty)
})
}
} }

View file

@ -20,12 +20,15 @@ impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
&self, &self,
outlives_env: &OutlivesEnvironment<'tcx>, outlives_env: &OutlivesEnvironment<'tcx>,
) -> Vec<RegionResolutionError<'tcx>> { ) -> Vec<RegionResolutionError<'tcx>> {
self.resolve_regions(outlives_env, |ty| { self.resolve_regions_with_normalize(outlives_env, |ty, origin| {
let ty = self.resolve_vars_if_possible(ty); let ty = self.resolve_vars_if_possible(ty);
if self.next_trait_solver() { if self.next_trait_solver() {
crate::solve::deeply_normalize( crate::solve::deeply_normalize(
self.at(&ObligationCause::dummy(), outlives_env.param_env), self.at(
&ObligationCause::dummy_with_span(origin.span()),
outlives_env.param_env,
),
ty, ty,
) )
.map_err(|_| ty) .map_err(|_| ty)

View file

@ -179,7 +179,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
} }
let outlives_env = OutlivesEnvironment::new(full_env); let outlives_env = OutlivesEnvironment::new(full_env);
let _ = infcx.process_registered_region_obligations::<!>(&outlives_env, |ty| Ok(ty)); let _ = infcx.process_registered_region_obligations::<!>(&outlives_env, |ty, _| Ok(ty));
let region_data = let region_data =
infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone(); infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone();

View file

@ -0,0 +1,13 @@
//~ ERROR the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime
// compile-flags: -Znext-solver
// Regression test for rust-lang/trait-system-refactor-initiative#59
trait StaticTy {
type Item<'a>: 'static;
}
impl StaticTy for () {
type Item<'a> = &'a ();
}
fn main() {}

View file

@ -0,0 +1,7 @@
error[E0477]: the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime
|
= note: type must satisfy the static lifetime
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0477`.