Account for variance in outlives obligations.

This commit is contained in:
Camille GILLOT 2023-04-16 10:01:15 +00:00
parent 4e7edf3684
commit 8889c6fa0e

View File

@ -344,12 +344,14 @@ where
// the problem is to add `T: 'r`, which isn't true. So, if there are no
// inference variables, we use a verify constraint instead of adding
// edges, which winds up enforcing the same condition.
let is_opaque = alias_ty.kind(self.tcx) == ty::Opaque;
if approx_env_bounds.is_empty()
&& trait_bounds.is_empty()
&& (alias_ty.needs_infer() || alias_ty.kind(self.tcx) == ty::Opaque)
&& (alias_ty.needs_infer() || is_opaque)
{
debug!("no declared bounds");
self.substs_must_outlive(alias_ty.substs, origin, region);
let opt_variances = is_opaque.then(|| self.tcx.variances_of(alias_ty.def_id));
self.substs_must_outlive(alias_ty.substs, origin, region, opt_variances);
return;
}
@ -395,22 +397,31 @@ where
self.delegate.push_verify(origin, GenericKind::Alias(alias_ty), region, verify_bound);
}
#[instrument(level = "debug", skip(self))]
fn substs_must_outlive(
&mut self,
substs: SubstsRef<'tcx>,
origin: infer::SubregionOrigin<'tcx>,
region: ty::Region<'tcx>,
opt_variances: Option<&[ty::Variance]>,
) {
let constraint = origin.to_constraint_category();
for k in substs {
for (index, k) in substs.iter().enumerate() {
match k.unpack() {
GenericArgKind::Lifetime(lt) => {
self.delegate.push_sub_region_constraint(
origin.clone(),
region,
lt,
constraint,
);
let variance = if let Some(variances) = opt_variances {
variances[index]
} else {
ty::Invariant
};
if variance == ty::Invariant {
self.delegate.push_sub_region_constraint(
origin.clone(),
region,
lt,
constraint,
);
}
}
GenericArgKind::Type(ty) => {
self.type_must_outlive(origin.clone(), ty, region, constraint);