Privatize the fields of RegionInferenceContext
This commit is contained in:
parent
786db7399f
commit
66c5d5b706
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user