Skip to content

Commit 8fc1d68

Browse files
committed
Account for variance in outlives verification.
1 parent 8889c6f commit 8fc1d68

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

compiler/rustc_infer/src/infer/outlives/components.rs

+38-2
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ fn compute_components<'tcx>(
143143
// through and constrain Pi.
144144
let mut subcomponents = smallvec![];
145145
let mut subvisited = SsoHashSet::new();
146-
compute_components_recursive(tcx, ty.into(), &mut subcomponents, &mut subvisited);
146+
compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited);
147147
out.push(Component::EscapingAlias(subcomponents.into_iter().collect()));
148148
}
149149
}
@@ -193,7 +193,43 @@ fn compute_components<'tcx>(
193193
///
194194
/// This should not be used to get the components of `parent` itself.
195195
/// Use [push_outlives_components] instead.
196-
pub(super) fn compute_components_recursive<'tcx>(
196+
pub(super) fn compute_alias_components_recursive<'tcx>(
197+
tcx: TyCtxt<'tcx>,
198+
alias_ty: Ty<'tcx>,
199+
out: &mut SmallVec<[Component<'tcx>; 4]>,
200+
visited: &mut SsoHashSet<GenericArg<'tcx>>,
201+
) {
202+
let ty::Alias(kind, alias_ty) = alias_ty.kind() else { bug!() };
203+
let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] };
204+
for (index, child) in alias_ty.substs.iter().enumerate() {
205+
if opt_variances.get(index) == Some(&ty::Bivariant) {
206+
continue;
207+
}
208+
if !visited.insert(child) {
209+
continue;
210+
}
211+
match child.unpack() {
212+
GenericArgKind::Type(ty) => {
213+
compute_components(tcx, ty, out, visited);
214+
}
215+
GenericArgKind::Lifetime(lt) => {
216+
// Ignore late-bound regions.
217+
if !lt.is_late_bound() {
218+
out.push(Component::Region(lt));
219+
}
220+
}
221+
GenericArgKind::Const(_) => {
222+
compute_components_recursive(tcx, child, out, visited);
223+
}
224+
}
225+
}
226+
}
227+
228+
/// Collect [Component]s for *all* the substs of `parent`.
229+
///
230+
/// This should not be used to get the components of `parent` itself.
231+
/// Use [push_outlives_components] instead.
232+
fn compute_components_recursive<'tcx>(
197233
tcx: TyCtxt<'tcx>,
198234
parent: GenericArg<'tcx>,
199235
out: &mut SmallVec<[Component<'tcx>; 4]>,

compiler/rustc_infer/src/infer/outlives/verify.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::infer::outlives::components::{compute_components_recursive, Component};
1+
use crate::infer::outlives::components::{compute_alias_components_recursive, Component};
22
use crate::infer::outlives::env::RegionBoundPairs;
33
use crate::infer::region_constraints::VerifyIfEq;
44
use crate::infer::VerifyBound;
@@ -130,7 +130,12 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
130130
// see the extensive comment in projection_must_outlive
131131
let recursive_bound = {
132132
let mut components = smallvec![];
133-
compute_components_recursive(self.tcx, alias_ty_as_ty.into(), &mut components, visited);
133+
compute_alias_components_recursive(
134+
self.tcx,
135+
alias_ty_as_ty.into(),
136+
&mut components,
137+
visited,
138+
);
134139
self.bound_from_components(&components, visited)
135140
};
136141

tests/ui/impl-trait/issue-108592.stderr

-21
This file was deleted.

0 commit comments

Comments
 (0)