Skip to content

Commit 780f6c5

Browse files
committed
extract out fully_perform_op_and_get_region_constraints
1 parent 7ff8980 commit 780f6c5

File tree

1 file changed

+57
-20
lines changed
  • src/librustc_mir/borrow_check/nll/type_check

1 file changed

+57
-20
lines changed

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -712,21 +712,65 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
712712
traits::ObligationCause::misc(span, self.body_id)
713713
}
714714

715-
#[inline(never)]
716-
fn fully_perform_op<OP, R>(
715+
/// Given some operation `op` that manipulates types, proves
716+
/// predicates, or otherwise uses the inference context, executes
717+
/// `op` and then executes all the further obligations that `op`
718+
/// returns. This will yield a set of outlives constraints amongst
719+
/// regions which are extracted and stored as having occured at
720+
/// `locations`.
721+
///
722+
/// **Any `rustc::infer` operations that might generate region
723+
/// constraints should occur within this method so that those
724+
/// constraints can be properly localized!**
725+
fn fully_perform_op<R>(
717726
&mut self,
718727
locations: Locations,
719728
describe_op: impl Fn() -> String,
720-
op: OP,
721-
) -> Result<R, TypeError<'tcx>>
722-
where
723-
OP: FnOnce(&mut Self) -> InferResult<'tcx, R>,
724-
{
729+
op: impl FnOnce(&mut Self) -> InferResult<'tcx, R>,
730+
) -> Result<R, TypeError<'tcx>> {
731+
let (r, opt_data) = self.fully_perform_op_and_get_region_constraint_data(
732+
|| format!("{} at {:?}", describe_op(), locations),
733+
op,
734+
)?;
735+
736+
if let Some(data) = opt_data {
737+
self.push_region_constraints(locations, data);
738+
}
739+
740+
Ok(r)
741+
}
742+
743+
fn push_region_constraints(
744+
&mut self,
745+
locations: Locations,
746+
data: Rc<RegionConstraintData<'tcx>>,
747+
) {
748+
debug!(
749+
"push_region_constraints: constraints generated at {:?} are {:#?}",
750+
locations, data
751+
);
752+
753+
self.constraints
754+
.outlives_sets
755+
.push(OutlivesSet { locations, data });
756+
}
757+
758+
/// Helper for `fully_perform_op`, but also used on its own
759+
/// sometimes to enable better caching: executes `op` fully (along
760+
/// with resulting obligations) and returns the full set of region
761+
/// obligations. If the same `op` were to be performed at some
762+
/// other location, then the same set of region obligations would
763+
/// be generated there, so this can be useful for caching.
764+
#[inline(never)]
765+
fn fully_perform_op_and_get_region_constraint_data<R>(
766+
&mut self,
767+
describe_op: impl Fn() -> String,
768+
op: impl FnOnce(&mut Self) -> InferResult<'tcx, R>,
769+
) -> Result<(R, Option<Rc<RegionConstraintData<'tcx>>>), TypeError<'tcx>> {
725770
if cfg!(debug_assertions) {
726771
info!(
727-
"fully_perform_op(describe_op={}) at {:?}",
772+
"fully_perform_op_and_get_region_constraint_data({})",
728773
describe_op(),
729-
locations
730774
);
731775
}
732776

@@ -745,18 +789,11 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
745789
);
746790

747791
let data = self.infcx.take_and_reset_region_constraints();
748-
if !data.is_empty() {
749-
debug!(
750-
"fully_perform_op: constraints generated at {:?} are {:#?}",
751-
locations, data
752-
);
753-
let data = Rc::new(data);
754-
self.constraints
755-
.outlives_sets
756-
.push(OutlivesSet { locations, data });
792+
if data.is_empty() {
793+
Ok((value, None))
794+
} else {
795+
Ok((value, Some(Rc::new(data))))
757796
}
758-
759-
Ok(value)
760797
}
761798

762799
#[inline(never)]

0 commit comments

Comments
 (0)