Privatize the fields of RegionInferenceContext

This commit is contained in:
Mark Mansi 2019-12-28 19:35:18 -06:00 committed by mark
parent 786db7399f
commit 66c5d5b706
4 changed files with 71 additions and 38 deletions

View File

@ -113,18 +113,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// one (e.g., this is just some random part of the CFG).
pub(super) fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
self.to_error_region_vid(r)
.and_then(|r| self.nonlexical_regioncx.definitions[r].external_name)
.and_then(|r| self.nonlexical_regioncx.region_definition(r).external_name)
}
/// Returns the `RegionVid` corresponding to the region returned by
/// `to_error_region`.
pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
if self.nonlexical_regioncx.universal_regions.is_universal_region(r) {
if self.nonlexical_regioncx.universal_regions().is_universal_region(r) {
Some(r)
} else {
let r_scc = self.nonlexical_regioncx.constraint_sccs.scc(r);
let upper_bound = self.nonlexical_regioncx.universal_upper_bound(r);
if self.nonlexical_regioncx.scc_values.contains(r_scc, upper_bound) {
if self.nonlexical_regioncx.upper_bound_in_region_scc(r, upper_bound) {
self.to_error_region_vid(upper_bound)
} else {
None
@ -137,7 +137,7 @@ fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) {
if let ty::BoundRegion::BrEnv = free_region.bound_region {
if let DefiningTy::Closure(def_id, substs) =
self.nonlexical_regioncx.universal_regions.defining_ty
self.nonlexical_regioncx.universal_regions().defining_ty
{
let closure_kind_ty = substs.as_closure().kind_ty(def_id, self.infcx.tcx);
return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind();
@ -302,8 +302,8 @@ pub(in crate::borrow_check) fn report_error(
}
let (fr_is_local, outlived_fr_is_local): (bool, bool) = (
self.nonlexical_regioncx.universal_regions.is_local_free_region(fr),
self.nonlexical_regioncx.universal_regions.is_local_free_region(outlived_fr),
self.nonlexical_regioncx.universal_regions().is_local_free_region(fr),
self.nonlexical_regioncx.universal_regions().is_local_free_region(outlived_fr),
);
debug!(
@ -378,7 +378,7 @@ fn report_fnmut_error(
// We should check if the return type of this closure is in fact a closure - in that
// case, we can special case the error further.
let return_type_is_closure =
self.nonlexical_regioncx.universal_regions.unnormalized_output_ty.is_closure();
self.nonlexical_regioncx.universal_regions().unnormalized_output_ty.is_closure();
let message = if return_type_is_closure {
"returns a closure that contains a reference to a captured variable, which then \
escapes the closure body"
@ -445,7 +445,7 @@ fn report_escaping_data_error(
errci.outlived_fr,
);
let escapes_from = match self.nonlexical_regioncx.universal_regions.defining_ty {
let escapes_from = match self.nonlexical_regioncx.universal_regions().defining_ty {
DefiningTy::Closure(..) => "closure",
DefiningTy::Generator(..) => "generator",
DefiningTy::FnDef(..) => "function",

View File

@ -191,7 +191,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
) -> Option<RegionName> {
debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter);
assert!(self.nonlexical_regioncx.universal_regions.is_universal_region(fr));
assert!(self.nonlexical_regioncx.universal_regions().is_universal_region(fr));
if let Some(value) = renctx.get(&fr) {
return Some(value.clone());
@ -277,7 +277,7 @@ fn give_name_from_error_region(
.hir()
.as_local_hir_id(self.mir_def_id)
.expect("non-local mir");
let def_ty = self.nonlexical_regioncx.universal_regions.defining_ty;
let def_ty = self.nonlexical_regioncx.universal_regions().defining_ty;
if let DefiningTy::Closure(def_id, substs) = def_ty {
let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) =
@ -345,11 +345,11 @@ fn give_name_if_anonymous_region_appears_in_arguments(
renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
let implicit_inputs =
self.nonlexical_regioncx.universal_regions.defining_ty.implicit_inputs();
self.nonlexical_regioncx.universal_regions().defining_ty.implicit_inputs();
let argument_index =
self.nonlexical_regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?;
let arg_ty = self.nonlexical_regioncx.universal_regions.unnormalized_input_tys
let arg_ty = self.nonlexical_regioncx.universal_regions().unnormalized_input_tys
[implicit_inputs + argument_index];
if let Some(region_name) =
self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index, renctx)
@ -684,7 +684,7 @@ fn give_name_if_anonymous_region_appears_in_output(
) -> Option<RegionName> {
let tcx = self.infcx.tcx;
let return_ty = self.nonlexical_regioncx.universal_regions.unnormalized_output_ty;
let return_ty = self.nonlexical_regioncx.universal_regions().unnormalized_output_ty;
debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty);
if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) {
return None;
@ -734,7 +734,7 @@ fn give_name_if_anonymous_region_appears_in_yield_ty(
) -> Option<RegionName> {
// Note: generators from `async fn` yield `()`, so we don't have to
// worry about them here.
let yield_ty = self.nonlexical_regioncx.universal_regions.yield_ty?;
let yield_ty = self.nonlexical_regioncx.universal_regions().yield_ty?;
debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,);
let tcx = self.infcx.tcx;

View File

@ -16,7 +16,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
fr: RegionVid,
) -> Option<(Option<Symbol>, Span)> {
debug!("get_var_name_and_span_for_region(fr={:?})", fr);
assert!(self.universal_regions.is_universal_region(fr));
assert!(self.universal_regions().is_universal_region(fr));
debug!("get_var_name_and_span_for_region: attempting upvar");
self.get_upvar_index_for_region(tcx, fr)
@ -35,7 +35,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// Search the upvars (if any) to find one that references fr. Return its index.
crate fn get_upvar_index_for_region(&self, tcx: TyCtxt<'tcx>, fr: RegionVid) -> Option<usize> {
let upvar_index =
self.universal_regions.defining_ty.upvar_tys(tcx).position(|upvar_ty| {
self.universal_regions().defining_ty.upvar_tys(tcx).position(|upvar_ty| {
debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty);
tcx.any_free_region_meets(&upvar_ty, |r| {
let r = r.to_region_vid();
@ -44,7 +44,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
})
})?;
let upvar_ty = self.universal_regions.defining_ty.upvar_tys(tcx).nth(upvar_index);
let upvar_ty = self.universal_regions().defining_ty.upvar_tys(tcx).nth(upvar_index);
debug!(
"get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}",
@ -85,9 +85,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
tcx: TyCtxt<'tcx>,
fr: RegionVid,
) -> Option<usize> {
let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
let argument_index =
self.universal_regions.unnormalized_input_tys.iter().skip(implicit_inputs).position(
self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position(
|arg_ty| {
debug!("get_argument_index_for_region: arg_ty = {:?}", arg_ty);
tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
@ -96,7 +96,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!(
"get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index],
fr,
argument_index,
self.universal_regions().unnormalized_input_tys[argument_index],
);
Some(argument_index)
@ -110,7 +112,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
local_names: &IndexVec<Local, Option<Symbol>>,
argument_index: usize,
) -> (Option<Symbol>, Span) {
let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
let argument_local = Local::new(implicit_inputs + argument_index + 1);
debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);

View File

@ -44,49 +44,48 @@ pub struct RegionInferenceContext<'tcx> {
/// variables are identified by their index (`RegionVid`). The
/// definition contains information about where the region came
/// from as well as its final inferred value.
pub(in crate::borrow_check) definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
/// The liveness constraints added to each region. For most
/// regions, these start out empty and steadily grow, though for
/// each universally quantified region R they start out containing
/// the entire CFG and `end(R)`.
pub(in crate::borrow_check) liveness_constraints: LivenessValues<RegionVid>,
liveness_constraints: LivenessValues<RegionVid>,
/// The outlives constraints computed by the type-check.
pub(in crate::borrow_check) constraints: Rc<OutlivesConstraintSet>,
constraints: Rc<OutlivesConstraintSet>,
/// The constraint-set, but in graph form, making it easy to traverse
/// the constraints adjacent to a particular region. Used to construct
/// the SCC (see `constraint_sccs`) and for error reporting.
pub(in crate::borrow_check) constraint_graph: Rc<NormalConstraintGraph>,
constraint_graph: Rc<NormalConstraintGraph>,
/// The SCC computed from `constraints` and the constraint
/// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
/// compute the values of each region.
pub(in crate::borrow_check) constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
/// Reverse of the SCC constraint graph -- i.e., an edge `A -> B`
/// exists if `B: A`. Computed lazilly.
pub(in crate::borrow_check) rev_constraint_graph: Option<Rc<VecGraph<ConstraintSccIndex>>>,
rev_constraint_graph: Option<Rc<VecGraph<ConstraintSccIndex>>>,
/// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
pub(in crate::borrow_check) member_constraints:
Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>,
member_constraints: Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>,
/// Records the member constraints that we applied to each scc.
/// This is useful for error reporting. Once constraint
/// propagation is done, this vector is sorted according to
/// `member_region_scc`.
pub(in crate::borrow_check) member_constraints_applied: Vec<AppliedMemberConstraint>,
member_constraints_applied: Vec<AppliedMemberConstraint>,
/// Map closure bounds to a `Span` that should be used for error reporting.
pub(in crate::borrow_check) closure_bounds_mapping:
closure_bounds_mapping:
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
/// Contains the minimum universe of any variable within the same
/// SCC. We will ensure that no SCC contains values that are not
/// visible from this index.
pub(in crate::borrow_check) scc_universes: IndexVec<ConstraintSccIndex, ty::UniverseIndex>,
scc_universes: IndexVec<ConstraintSccIndex, ty::UniverseIndex>,
/// Contains a "representative" from each SCC. This will be the
/// minimal RegionVid belonging to that universe. It is used as a
@ -95,23 +94,23 @@ pub struct RegionInferenceContext<'tcx> {
/// of its SCC and be sure that -- if they have the same repr --
/// they *must* be equal (though not having the same repr does not
/// mean they are unequal).
pub(in crate::borrow_check) scc_representatives: IndexVec<ConstraintSccIndex, ty::RegionVid>,
scc_representatives: IndexVec<ConstraintSccIndex, ty::RegionVid>,
/// The final inferred values of the region variables; we compute
/// one value per SCC. To get the value for any given *region*,
/// you first find which scc it is a part of.
pub(in crate::borrow_check) scc_values: RegionValues<ConstraintSccIndex>,
scc_values: RegionValues<ConstraintSccIndex>,
/// Type constraints that we check after solving.
pub(in crate::borrow_check) type_tests: Vec<TypeTest<'tcx>>,
type_tests: Vec<TypeTest<'tcx>>,
/// Information about the universally quantified regions in scope
/// on this function.
pub(in crate::borrow_check) universal_regions: Rc<UniversalRegions<'tcx>>,
universal_regions: Rc<UniversalRegions<'tcx>>,
/// Information about how the universally quantified regions in
/// scope on this function relate to one another.
pub(in crate::borrow_check) universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
}
/// Each time that `apply_member_constraint` is successful, it appends
@ -1840,6 +1839,38 @@ fn check_member_constraints(
.unwrap()
}
/// Get the region outlived by `longer_fr` and live at `element`.
crate fn region_from_element(&self, longer_fr: RegionVid, element: RegionElement) -> RegionVid {
match element {
RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
RegionElement::RootUniversalRegion(r) => r,
RegionElement::PlaceholderRegion(error_placeholder) => self
.definitions
.iter_enumerated()
.filter_map(|(r, definition)| match definition.origin {
NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
_ => None,
})
.next()
.unwrap(),
}
}
/// Get the region definition of `r`.
crate fn region_definition(&self, r: RegionVid) -> &RegionDefinition<'tcx> {
&self.definitions[r]
}
/// Check if the SCC of `r` contains `upper`.
crate fn upper_bound_in_region_scc(&self, r: RegionVid, upper: RegionVid) -> bool {
let r_scc = self.constraint_sccs.scc(r);
self.scc_values.contains(r_scc, upper)
}
crate fn universal_regions(&self) -> Rc<UniversalRegions<'tcx>> {
self.universal_regions.clone()
}
/// Tries to find the best constraint to blame for the fact that
/// `R: from_region`, where `R` is some region that meets
/// `target_test`. This works by following the constraint graph,