Skip to content

Commit 373293c

Browse files
committed
Extract compute_bidirectional_outlives_predicates fn
1 parent e69c730 commit 373293c

File tree

1 file changed

+51
-33
lines changed

1 file changed

+51
-33
lines changed

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
22
use crate::bounds::Bounds;
33
use crate::collect::ItemCtxt;
44
use crate::constrained_generic_params as cgp;
5-
use hir::{HirId, Node};
5+
use hir::{HirId, Lifetime, Node};
66
use rustc_data_structures::fx::FxIndexSet;
77
use rustc_hir as hir;
88
use rustc_hir::def::DefKind;
99
use rustc_hir::def_id::{DefId, LocalDefId};
1010
use rustc_hir::intravisit::{self, Visitor};
1111
use rustc_middle::ty::subst::InternalSubsts;
1212
use rustc_middle::ty::{self, Ty, TyCtxt};
13-
use rustc_middle::ty::{GenericPredicates, ToPredicate};
13+
use rustc_middle::ty::{GenericPredicates, Generics, ToPredicate};
1414
use rustc_span::symbol::{sym, Ident};
15-
use rustc_span::{Span, DUMMY_SP};
15+
use rustc_span::{Span, Symbol, DUMMY_SP};
1616

1717
/// Returns a list of all type predicates (explicit and implicit) for the definition with
1818
/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
@@ -289,38 +289,16 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
289289
bug!("unexpected {opaque_ty_node:?}")
290290
};
291291
debug!(?lifetimes);
292-
for (arg, duplicate) in std::iter::zip(lifetimes, ast_generics.params) {
293-
let hir::GenericArg::Lifetime(arg) = arg else { bug!() };
294-
let orig_region = icx.astconv().ast_region_to_region(&arg, None);
295-
if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) {
296-
// Only early-bound regions can point to the original generic parameter.
297-
continue;
298-
}
299-
300-
let hir::GenericParamKind::Lifetime { .. } = duplicate.kind else { continue };
301-
let dup_def = duplicate.def_id.to_def_id();
302292

303-
let Some(dup_index) = generics.param_def_id_to_index(tcx, dup_def) else { bug!() };
293+
let lifetime_mapping = std::iter::zip(lifetimes, ast_generics.params)
294+
.map(|(arg, dup)| {
295+
let hir::GenericArg::Lifetime(arg) = arg else { bug!() };
296+
(**arg, dup)
297+
})
298+
.filter(|(_, dup)| matches!(dup.kind, hir::GenericParamKind::Lifetime { .. }))
299+
.map(|(lifetime, dup)| (lifetime, (dup.def_id, dup.name.ident().name, dup.span)));
304300

305-
let dup_region = ty::Region::new_early_bound(
306-
tcx,
307-
ty::EarlyBoundRegion {
308-
def_id: dup_def,
309-
index: dup_index,
310-
name: duplicate.name.ident().name,
311-
},
312-
);
313-
predicates.push((
314-
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_region, dup_region))
315-
.to_predicate(icx.tcx),
316-
duplicate.span,
317-
));
318-
predicates.push((
319-
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_region, orig_region))
320-
.to_predicate(icx.tcx),
321-
duplicate.span,
322-
));
323-
}
301+
bidirectional_lifetime_predicates(tcx, def_id, lifetime_mapping, generics, &mut predicates);
324302
debug!(?predicates);
325303
}
326304

@@ -330,6 +308,46 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
330308
}
331309
}
332310

311+
/// Opaques have duplicated lifetimes and we need to compute bidirectional outlives predicates to
312+
/// enforce that these lifetimes stay in sync.
313+
fn compute_bidirectional_outlives_predicates<'tcx>(
314+
tcx: TyCtxt<'tcx>,
315+
item_def_id: LocalDefId,
316+
lifetime_mapping: impl Iterator<Item = (Lifetime, (LocalDefId, Symbol, Span))>,
317+
generics: &Generics,
318+
predicates: &mut Vec<(ty::Clause<'tcx>, Span)>,
319+
) {
320+
let icx = ItemCtxt::new(tcx, item_def_id);
321+
322+
for (arg, (dup_def, name, span)) in lifetime_mapping {
323+
let orig_region = icx.astconv().ast_region_to_region(&arg, None);
324+
if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) {
325+
// There is no late-bound lifetime to actually match up here, since the lifetime doesn't
326+
// show up in the opaque's parent's substs.
327+
continue;
328+
}
329+
330+
let Some(dup_index) = generics.param_def_id_to_index(icx.tcx, dup_def.to_def_id()) else { bug!() };
331+
332+
let dup_region = ty::Region::new_early_bound(
333+
tcx,
334+
ty::EarlyBoundRegion { def_id: dup_def.to_def_id(), index: dup_index, name },
335+
);
336+
337+
predicates.push((
338+
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_region, dup_region))
339+
.to_predicate(tcx),
340+
span,
341+
));
342+
343+
predicates.push((
344+
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_region, orig_region))
345+
.to_predicate(tcx),
346+
span,
347+
));
348+
}
349+
}
350+
333351
fn const_evaluatable_predicates_of(
334352
tcx: TyCtxt<'_>,
335353
def_id: LocalDefId,

0 commit comments

Comments
 (0)