@@ -276,7 +276,17 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
276
276
277
277
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
278
278
self.super_constant(constant, location);
279
- self.sanitize_type(constant, constant.literal.ty);
279
+ let ty = self.sanitize_type(constant, constant.literal.ty);
280
+
281
+ self.cx.infcx.tcx.for_each_free_region(&ty, |live_region| {
282
+ let live_region_vid =
283
+ self.cx.borrowck_context.universal_regions.to_region_vid(live_region);
284
+ self.cx
285
+ .borrowck_context
286
+ .constraints
287
+ .liveness_constraints
288
+ .add_element(live_region_vid, location);
289
+ });
280
290
281
291
if let Some(annotation_index) = constant.user_ty {
282
292
if let Err(terr) = self.cx.relate_type_and_user_type(
@@ -528,56 +538,64 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
528
538
529
539
let parent_body = mem::replace(&mut self.body, promoted_body);
530
540
541
+ // Use new sets of constraints and closure bounds so that we can
542
+ // modify their locations.
531
543
let all_facts = &mut None;
532
544
let mut constraints = Default::default();
533
545
let mut closure_bounds = Default::default();
546
+ let mut liveness_constraints = LivenessValues::new(
547
+ Rc::new(RegionValueElements::new(promoted_body)),
548
+ );
534
549
// Don't try to add borrow_region facts for the promoted MIR
535
- mem::swap(self.cx.borrowck_context.all_facts, all_facts);
536
550
537
- // Use a new sets of constraints and closure bounds so that we can
538
- // modify their locations.
539
- mem::swap(
540
- &mut self.cx.borrowck_context.constraints.outlives_constraints,
541
- &mut constraints
542
- );
543
- mem::swap(
544
- &mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
545
- &mut closure_bounds
546
- );
551
+ let mut swap_constraints = |this: &mut Self| {
552
+ mem::swap(this.cx.borrowck_context.all_facts, all_facts);
553
+ mem::swap(
554
+ &mut this.cx.borrowck_context.constraints.outlives_constraints,
555
+ &mut constraints
556
+ );
557
+ mem::swap(
558
+ &mut this.cx.borrowck_context.constraints.closure_bounds_mapping,
559
+ &mut closure_bounds
560
+ );
561
+ mem::swap(
562
+ &mut this.cx.borrowck_context.constraints.liveness_constraints,
563
+ &mut liveness_constraints
564
+ );
565
+ };
566
+
567
+ swap_constraints(self);
547
568
548
569
self.visit_body(promoted_body);
549
570
571
+
550
572
if !self.errors_reported {
551
573
// if verifier failed, don't do further checks to avoid ICEs
552
574
self.cx.typeck_mir(promoted_body);
553
575
}
554
576
555
577
self.body = parent_body;
556
578
// Merge the outlives constraints back in, at the given location.
557
- mem::swap(self.cx.borrowck_context.all_facts, all_facts);
558
- mem::swap(
559
- &mut self.cx.borrowck_context.constraints.outlives_constraints,
560
- &mut constraints
561
- );
562
- mem::swap(
563
- &mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
564
- &mut closure_bounds
565
- );
579
+ swap_constraints(self);
566
580
567
581
let locations = location.to_locations();
568
582
for constraint in constraints.outlives().iter() {
569
583
let mut constraint = *constraint;
570
584
constraint.locations = locations;
571
585
if let ConstraintCategory::Return
572
- | ConstraintCategory::UseAsConst
573
- | ConstraintCategory::UseAsStatic = constraint.category
586
+ | ConstraintCategory::UseAsConst
587
+ | ConstraintCategory::UseAsStatic = constraint.category
574
588
{
575
589
// "Returning" from a promoted is an assigment to a
576
590
// temporary from the user's point of view.
577
591
constraint.category = ConstraintCategory::Boring;
578
592
}
579
593
self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
580
594
}
595
+ for live_region in liveness_constraints.rows() {
596
+ self.cx.borrowck_context.constraints.liveness_constraints
597
+ .add_element(live_region, location);
598
+ }
581
599
582
600
if !closure_bounds.is_empty() {
583
601
let combined_bounds_mapping = closure_bounds
0 commit comments