rustc_borrowck::region_infer

Struct RegionInferenceContext

source
pub struct RegionInferenceContext<'tcx> {
Show 14 fields pub var_infos: VarInfos, definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>, liveness_constraints: LivenessValues, constraints: Frozen<OutlivesConstraintSet<'tcx>>, constraint_graph: Frozen<ConstraintGraph<Normal>>, constraint_sccs: Sccs<RegionVid, ConstraintSccIndex, RegionTracker>, rev_scc_graph: Option<ReverseSccGraph>, member_constraints: Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>, member_constraints_applied: Vec<AppliedMemberConstraint>, universe_causes: FxIndexMap<UniverseIndex, UniverseInfo<'tcx>>, scc_values: RegionValues<ConstraintSccIndex>, type_tests: Vec<TypeTest<'tcx>>, universal_regions: Rc<UniversalRegions<'tcx>>, universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
}

Fields§

§var_infos: VarInfos§definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>

Contains the definition for every region variable. Region variables are identified by their index (RegionVid). The definition contains information about where the region came from as well as its final inferred value.

§liveness_constraints: LivenessValues

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).

§constraints: Frozen<OutlivesConstraintSet<'tcx>>

The outlives constraints computed by the type-check.

§constraint_graph: Frozen<ConstraintGraph<Normal>>

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.

§constraint_sccs: Sccs<RegionVid, ConstraintSccIndex, RegionTracker>

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.

§rev_scc_graph: Option<ReverseSccGraph>

Reverse of the SCC constraint graph – i.e., an edge A -> B exists if B: A. This is used to compute the universal regions that are required to outlive a given SCC. Computed lazily.

§member_constraints: Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>

The “R0 member of [R1..Rn]” constraints, indexed by SCC.

§member_constraints_applied: Vec<AppliedMemberConstraint>

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.

§universe_causes: FxIndexMap<UniverseIndex, UniverseInfo<'tcx>>

Map universe indexes to information on why we created it.

§scc_values: RegionValues<ConstraintSccIndex>

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.

§type_tests: Vec<TypeTest<'tcx>>

Type constraints that we check after solving.

§universal_regions: Rc<UniversalRegions<'tcx>>

Information about the universally quantified regions in scope on this function.

§universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>

Information about how the universally quantified regions in scope on this function relate to one another.

Implementations§

source§

impl<'tcx> RegionInferenceContext<'tcx>

source

pub(crate) fn get_var_name_and_span_for_region( &self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>, local_names: &IndexSlice<Local, Option<Symbol>>, upvars: &[&CapturedPlace<'tcx>], fr: RegionVid, ) -> Option<(Option<Symbol>, Span)>

source

pub(crate) fn get_upvar_index_for_region( &self, tcx: TyCtxt<'tcx>, fr: RegionVid, ) -> Option<usize>

Search the upvars (if any) to find one that references fr. Return its index.

source

pub(crate) fn get_upvar_name_and_span_for_region( &self, tcx: TyCtxt<'tcx>, upvars: &[&CapturedPlace<'tcx>], upvar_index: usize, ) -> (Symbol, Span)

Given the index of an upvar, finds its name and the span from where it was declared.

source

pub(crate) fn get_argument_index_for_region( &self, tcx: TyCtxt<'tcx>, fr: RegionVid, ) -> Option<usize>

Search the argument types for one that references fr (which should be a free region). Returns Some(_) with the index of the input if one is found.

N.B., in the case of a closure, the index is indexing into the signature as seen by the user - in particular, index 0 is not the implicit self parameter.

source

pub(crate) fn get_argument_name_and_span_for_region( &self, body: &Body<'tcx>, local_names: &IndexSlice<Local, Option<Symbol>>, argument_index: usize, ) -> (Option<Symbol>, Span)

Given the index of an argument, finds its name (if any) and the span from where it was declared.

source§

impl<'tcx> RegionInferenceContext<'tcx>

source

pub(crate) fn dump_mir( &self, tcx: TyCtxt<'tcx>, out: &mut dyn Write, ) -> Result<()>

Write out our state into the .mir files.

source

fn for_each_constraint( &self, tcx: TyCtxt<'tcx>, with_msg: &mut dyn FnMut(&str) -> Result<()>, ) -> Result<()>

Debugging aid: Invokes the with_msg callback repeatedly with our internal region constraints. These are dumped into the -Zdump-mir file so that we can figure out why the region inference resulted in the values that it did when debugging.

source§

impl<'tcx> RegionInferenceContext<'tcx>

source

pub(crate) fn dump_graphviz_raw_constraints( &self, w: &mut dyn Write, ) -> Result<()>

Write out the region constraint graph.

source

pub(crate) fn dump_graphviz_scc_constraints( &self, w: &mut dyn Write, ) -> Result<()>

Write out the region constraint SCC graph.

source§

impl<'tcx> RegionInferenceContext<'tcx>

source

pub(crate) fn infer_opaque_types( &self, infcx: &InferCtxt<'tcx>, opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>, ) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>

Resolve any opaque types that were encountered while borrow checking this item. This is then used to get the type in the type_of query.

For example consider fn f<'a>(x: &'a i32) -> impl Sized + 'a { x }. This is lowered to give HIR something like

type f<‘a>::_Return<’_x> = impl Sized + ’_x; fn f<’a>(x: &’a i32) -> f<’a>::_Return<’a> { x }

When checking the return type record the type from the return and the type used in the return value. In this case they might be _Return<'1> and &'2 i32 respectively.

Once we to this method, we have completed region inference and want to call infer_opaque_definition_from_instantiation to get the inferred type of _Return<'_x>. infer_opaque_definition_from_instantiation compares lifetimes directly, so we need to map the inference variables back to concrete lifetimes: 'static, ReEarlyParam or ReLateParam.

First we map the regions in the generic parameters _Return<'1> to their external_name giving _Return<'a>. This step is a bit involved. See the rustc-dev-guide chapter for more info.

Then we map all the lifetimes in the concrete type to an equal universal region that occurs in the opaque type’s args, in this case this would result in &'a i32. We only consider regions in the args in case there is an equal region that does not. For example, this should be allowed: fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }

This will then allow infer_opaque_definition_from_instantiation to determine that _Return<'_x> = &'_x i32.

There’s a slight complication around closures. Given fn f<'a: 'a>() { || {} } the closure’s type is something like f::<'a>::{{closure}}. The region parameter from f is essentially ignored by type checking so ends up being inferred to an empty region. Calling universal_upper_bound for such a region gives fr_fn_body, which has no external_name in which case we use '{erased} as the region to pass to infer_opaque_definition_from_instantiation.

source

pub(crate) fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T
where T: TypeFoldable<TyCtxt<'tcx>>,

Map the regions in the type to named regions. This is similar to what infer_opaque_types does, but can infer any universal region, not only ones from the args for the opaque type. It also doesn’t double check that the regions produced are in fact equal to the named region they are replaced with. This is fine because this function is only to improve the region names in error messages.

source§

impl RegionInferenceContext<'_>

source

pub(super) fn compute_reverse_scc_graph(&mut self)

Compute the reverse SCC-based constraint graph (lazily).

source§

impl<'tcx> RegionInferenceContext<'tcx>

source

pub(crate) fn new( infcx: &BorrowckInferCtxt<'tcx>, var_infos: VarInfos, universal_regions: Rc<UniversalRegions<'tcx>>, placeholder_indices: Rc<PlaceholderIndices>, universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, outlives_constraints: OutlivesConstraintSet<'tcx>, member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, universe_causes: FxIndexMap<UniverseIndex, UniverseInfo<'tcx>>, type_tests: Vec<TypeTest<'tcx>>, liveness_constraints: LivenessValues, elements: Rc<DenseLocationMap>, ) -> Self

Creates a new region inference context with a total of num_region_variables valid inference variables; the first N of those will be constant regions representing the free regions defined in universal_regions.

The outlives_constraints and type_tests are an initial set of constraints produced by the MIR type check.

source

fn init_free_and_bound_regions(&mut self)

Initializes the region variables for each universally quantified region (lifetime parameter). The first N variables always correspond to the regions appearing in the function signature (both named and anonymous) and where-clauses. This function iterates over those regions and initializes them with minimum values.

For example:

fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }

would initialize two variables like so:

R0 = { CFG, R0 } // 'a
R1 = { CFG, R0, R1 } // 'b

Here, R0 represents 'a, and it contains (a) the entire CFG and (b) any universally quantified regions that it outlives, which in this case is just itself. R1 ('b) in contrast also outlives 'a and hence contains R0 and R1.

This bit of logic also handles invalid universe relations for higher-kinded types.

We Walk each SCC A and B such that A: B and ensure that universe(A) can see universe(B).

This serves to enforce the ‘empty/placeholder’ hierarchy (described in more detail on RegionKind):

static -----+
  |         |
empty(U0) placeholder(U1)
  |      /
empty(U1)

In particular, imagine we have variables R0 in U0 and R1 created in U1, and constraints like this;

R1: !1 // R1 outlives the placeholder in U1
R1: R0 // R1 outlives R0

Here, we wish for R1 to be 'static, because it cannot outlive placeholder(U1) and empty(U0) any other way.

Thanks to this loop, what happens is that the R1: R0 constraint has lowered the universe of R1 to U0, which in turn means that the R1: !1 constraint here will cause R1 to become 'static.

source

pub fn regions(&self) -> impl Iterator<Item = RegionVid> + 'tcx

Returns an iterator over all the region indices.

source

pub fn to_region_vid(&self, r: Region<'tcx>) -> RegionVid

Given a universal region in scope on the MIR, returns the corresponding index.

(Panics if r is not a registered universal region.)

source

pub fn outlives_constraints( &self, ) -> impl Iterator<Item = OutlivesConstraint<'tcx>> + '_

Returns an iterator over all the outlives constraints.

source

pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diag<'_, ()>)

Adds annotations for #[rustc_regions]; see UniversalRegions::annotate.

source

pub(crate) fn region_contains( &self, r: RegionVid, p: impl ToElementIndex, ) -> bool

Returns true if the region r contains the point p.

Panics if called before solve() executes,

source

pub(crate) fn first_non_contained_inclusive( &self, r: RegionVid, block: BasicBlock, start: usize, end: usize, ) -> Option<usize>

Returns the lowest statement index in start..=end which is not contained by r.

Panics if called before solve() executes.

source

pub(crate) fn region_value_str(&self, r: RegionVid) -> String

Returns access to the value of r for debugging purposes.

source

pub(crate) fn placeholders_contained_in<'a>( &'a self, r: RegionVid, ) -> impl Iterator<Item = PlaceholderRegion> + 'a

source

pub(crate) fn region_universe(&self, r: RegionVid) -> UniverseIndex

Returns access to the value of r for debugging purposes.

source

pub(crate) fn applied_member_constraints( &self, scc: ConstraintSccIndex, ) -> &[AppliedMemberConstraint]

Once region solving has completed, this function will return the member constraints that were applied to the value of a given SCC scc. See AppliedMemberConstraint.

source

pub(crate) fn solve( &mut self, infcx: &InferCtxt<'tcx>, body: &Body<'tcx>, polonius_output: Option<Box<PoloniusOutput>>, ) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>)

Performs region inference and report errors if we see any unsatisfiable constraints. If this is a closure, returns the region requirements to propagate to our creator, if any.

source

fn propagate_constraints(&mut self)

Propagate the region constraints: this will grow the values for each region variable until all the constraints are satisfied. Note that some values may grow too large to be feasible, but we check this later.

source

fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex)

Computes the value of the SCC scc_a, which has not yet been computed, by unioning the values of its successors. Assumes that all successors have been computed already (which is assured by iterating over SCCs in dependency order).

source

fn apply_member_constraint( &mut self, scc: ConstraintSccIndex, member_constraint_index: NllMemberConstraintIndex, choice_regions: &[RegionVid], )

Invoked for each R0 member of [R1..Rn] constraint.

scc is the SCC containing R0, and choice_regions are the R1..Rn regions – they are always known to be universal regions (and if that’s not true, we just don’t attempt to enforce the constraint).

The current value of scc at the time the method is invoked is considered a lower bound. If possible, we will modify the constraint to set it equal to one of the option regions. If we make any changes, returns true, else false.

This function only adds the member constraints to the region graph, it does not check them. They are later checked in check_member_constraints after the region graph has been computed.

source

fn universe_compatible( &self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex, ) -> bool

Returns true if all the elements in the value of scc_b are nameable in scc_a. Used during constraint propagation, and only once the value of scc_b has been computed.

source

fn check_type_tests( &self, infcx: &InferCtxt<'tcx>, propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>, errors_buffer: &mut RegionErrors<'tcx>, )

Once regions have been propagated, this method is used to see whether the “type tests” produced by typeck were satisfied; type tests encode type-outlives relationships like T: 'a. See TypeTest for more details.

source

fn try_promote_type_test( &self, infcx: &InferCtxt<'tcx>, type_test: &TypeTest<'tcx>, propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>, ) -> bool

Invoked when we have some type-test (e.g., T: 'X) that we cannot prove to be satisfied. If this is a closure, we will attempt to “promote” this type-test into our ClosureRegionRequirements and hence pass it up the creator. To do this, we have to phrase the type-test in terms of external free regions, as local free regions are not nameable by the closure’s creator.

Promotion works as follows: we first check that the type T contains only regions that the creator knows about. If this is true, then – as a consequence – we know that all regions in the type T are free regions that outlive the closure body. If false, then promotion fails.

Once we’ve promoted T, we have to “promote” 'X to some region that is “external” to the closure. Generally speaking, a region may be the union of some points in the closure body as well as various free lifetimes. We can ignore the points in the closure body: if the type T can be expressed in terms of external regions, we know it outlives the points in the closure body. That just leaves the free regions.

The idea then is to lower the T: 'X constraint into multiple bounds – e.g., if 'X is the union of two free lifetimes, '1 and '2, then we would create T: '1 and T: '2.

source

fn try_promote_type_test_subject( &self, infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>, ) -> Option<ClosureOutlivesSubject<'tcx>>

When we promote a type test T: 'r, we have to replace all region variables in the type T with an equal universal region from the closure signature. This is not always possible, so this is a fallible process.

source

pub(crate) fn approx_universal_upper_bound(&self, r: RegionVid) -> RegionVid

Like universal_upper_bound, but returns an approximation more suitable for diagnostics. If r contains multiple disjoint universal regions (e.g. ’a and ’b in fn foo<'a, 'b> { ... }, we pick the lower-numbered region. This corresponds to picking named regions over unnamed regions (e.g. picking early-bound regions over a closure late-bound region).

This means that the returned value may not be a true upper bound, since only ’static is known to outlive disjoint universal regions. Therefore, this method should only be used in diagnostic code, where displaying some named universal region is better than falling back to ’static.

source

fn eval_verify_bound( &self, infcx: &InferCtxt<'tcx>, generic_ty: Ty<'tcx>, lower_bound: RegionVid, verify_bound: &VerifyBound<'tcx>, ) -> bool

Tests if test is true when applied to lower_bound at point.

source

fn eval_if_eq( &self, infcx: &InferCtxt<'tcx>, generic_ty: Ty<'tcx>, lower_bound: RegionVid, verify_if_eq_b: Binder<'tcx, VerifyIfEq<'tcx>>, ) -> bool

source

fn normalize_to_scc_representatives<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
where T: TypeFoldable<TyCtxt<'tcx>>,

This is a conservative normalization procedure. It takes every free region in value and replaces it with the “representative” of its SCC (see scc_representatives field). We are guaranteed that if two values normalize to the same thing, then they are equal; this is a conservative check in that they could still be equal even if they normalize to different results. (For example, there might be two regions with the same value that are not in the same SCC).

N.B., this is not an ideal approach and I would like to revisit it. However, it works pretty well in practice. In particular, this is needed to deal with projection outlives bounds like

<T as Foo<'0>>::Item: '1

In particular, this routine winds up being important when there are bounds like where <T as Foo<'a>>::Item: 'b in the environment. In this case, if we can show that '0 == 'a, and that 'b: '1, then we know that the clause is satisfied. In such cases, particularly due to limitations of the trait solver =), we usually wind up with a where-clause like T: Foo<'a> in scope, which thus forces '0 == 'a to be added as a constraint, and thus ensures that they are in the same SCC.

So why can’t we do a more correct routine? Well, we could almost use the relate_tys code, but the way it is currently setup it creates inference variables to deal with higher-ranked things and so forth, and right now the inference context is not permitted to make more inference variables. So we use this kind of hacky solution.

source

pub fn eval_equal(&self, r1: RegionVid, r2: RegionVid) -> bool

Evaluate whether sup_region == sub_region.

Panics if called before solve() executes,

source

pub fn eval_outlives( &self, sup_region: RegionVid, sub_region: RegionVid, ) -> bool

Evaluate whether sup_region: sub_region.

Panics if called before solve() executes,

source

fn check_universal_regions( &self, propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>, errors_buffer: &mut RegionErrors<'tcx>, )

Once regions have been propagated, this method is used to see whether any of the constraints were too strong. In particular, we want to check for a case where a universally quantified region exceeded its bounds. Consider:

fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }

In this case, returning x requires &'a u32 <: &'b u32 and hence we establish (transitively) a constraint that 'a: 'b. The propagate_constraints code above will therefore add end('a) into the region for 'b – but we have no evidence that 'b outlives 'a, so we want to report an error.

If propagated_outlives_requirements is Some, then we will push unsatisfied obligations into there. Otherwise, we’ll report them as errors.

source

fn check_polonius_subset_errors( &self, propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>, errors_buffer: &mut RegionErrors<'tcx>, polonius_output: &PoloniusOutput, )

Checks if Polonius has found any unexpected free region relations.

In Polonius terms, a “subset error” (or “illegal subset relation error”) is the equivalent of NLL’s “checking if any region constraints were too strong”: a placeholder origin 'a was unexpectedly found to be a subset of another placeholder origin 'b, and means in NLL terms that the “longer free region” 'a outlived the “shorter free region” 'b.

More details can be found in this blog post by Niko: https://smallcultfollowing.com/babysteps/blog/2019/01/17/polonius-and-region-errors/

In the canonical example

fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }

returning x requires &'a u32 <: &'b u32 and hence we establish (transitively) a constraint that 'a: 'b. It is an error that we have no evidence that this constraint holds.

If propagated_outlives_requirements is Some, then we will push unsatisfied obligations into there. Otherwise, we’ll report them as errors.

source

fn scc_universe(&self, scc: ConstraintSccIndex) -> UniverseIndex

The minimum universe of any variable reachable from this SCC, inside or outside of it.

source

fn check_universal_region( &self, longer_fr: RegionVid, propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>, errors_buffer: &mut RegionErrors<'tcx>, )

Checks the final value for the free region fr to see if it grew too large. In particular, examine what end(X) points wound up in fr’s final value; for each end(X) where X != fr, we want to check that fr: X. If not, that’s either an error, or something we have to propagate to our creator.

Things that are to be propagated are accumulated into the outlives_requirements vector.

source

fn check_universal_region_relation( &self, longer_fr: RegionVid, shorter_fr: RegionVid, propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>, ) -> RegionRelationCheckResult

Checks that we can prove that longer_fr: shorter_fr. If we can’t we attempt to propagate the constraint outward (e.g. to a closure environment), but if that fails, there is an error.

source

fn try_propagate_universal_region_error( &self, longer_fr: RegionVid, shorter_fr: RegionVid, propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>, ) -> RegionRelationCheckResult

Attempt to propagate a region error (e.g. 'a: 'b) that is not met to a closure’s creator. If we cannot, then the caller should report an error to the user.

source

fn check_bound_universal_region( &self, longer_fr: RegionVid, placeholder: PlaceholderRegion, errors_buffer: &mut RegionErrors<'tcx>, )

source

fn check_member_constraints( &self, infcx: &InferCtxt<'tcx>, errors_buffer: &mut RegionErrors<'tcx>, )

source

pub(crate) fn provides_universal_region( &self, r: RegionVid, fr1: RegionVid, fr2: RegionVid, ) -> bool

We have a constraint fr1: fr2 that is not satisfied, where fr2 represents some universal region. Here, r is some region where we know that fr1: r and this function has the job of determining whether r is “to blame” for the fact that fr1: fr2 is required.

This is true under two conditions:

  • r == fr2
  • fr2 is 'static and r is some placeholder in a universe that cannot be named by fr1; in that case, we will require that fr1: 'static because it is the only way to fr1: r to be satisfied. (See add_incompatible_universe.)
source

pub(crate) fn cannot_name_placeholder( &self, r1: RegionVid, r2: RegionVid, ) -> bool

If r2 represents a placeholder region, then this returns true if r1 cannot name that placeholder in its value; otherwise, returns false.

source

pub(crate) fn find_outlives_blame_span( &self, fr1: RegionVid, fr1_origin: NllRegionVariableOrigin, fr2: RegionVid, ) -> (ConstraintCategory<'tcx>, ObligationCause<'tcx>)

Finds a good ObligationCause to blame for the fact that fr1 outlives fr2.

source

pub(crate) fn find_constraint_paths_between_regions( &self, from_region: RegionVid, target_test: impl Fn(RegionVid) -> bool, ) -> Option<(Vec<OutlivesConstraint<'tcx>>, RegionVid)>

Walks the graph of constraints (where 'a: 'b is considered an edge 'a -> 'b) to find all paths from from_region to to_region. The paths are accumulated into the vector results. The paths are stored as a series of ConstraintIndex values – in other words, a list of edges.

Returns: a series of constraints as well as the region R that passed the target test.

source

pub(crate) fn find_sub_region_live_at( &self, fr1: RegionVid, location: Location, ) -> RegionVid

Finds some region R such that fr1: R and R is live at location.

source

pub(crate) fn region_from_element( &self, longer_fr: RegionVid, element: &RegionElement, ) -> RegionVid

Get the region outlived by longer_fr and live at element.

source

pub(crate) fn region_definition(&self, r: RegionVid) -> &RegionDefinition<'tcx>

Get the region definition of r.

source

pub(crate) fn upper_bound_in_region_scc( &self, r: RegionVid, upper: RegionVid, ) -> bool

Check if the SCC of r contains upper.

source

pub(crate) fn universal_regions(&self) -> &UniversalRegions<'tcx>

source

pub(crate) fn best_blame_constraint( &self, from_region: RegionVid, from_region_origin: NllRegionVariableOrigin, target_test: impl Fn(RegionVid) -> bool, ) -> (BlameConstraint<'tcx>, Vec<ExtraConstraintInfo>)

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, creating a constraint path that forces R to outlive from_region, and then finding the best choices within that path to blame.

source

pub(crate) fn universe_info( &self, universe: UniverseIndex, ) -> UniverseInfo<'tcx>

source

pub(crate) fn find_loop_terminator_location( &self, r: RegionVid, body: &Body<'_>, ) -> Option<Location>

Tries to find the terminator of the loop in which the region ‘r’ resides. Returns the location of the terminator if found.

source

pub fn constraint_sccs( &self, ) -> &Sccs<RegionVid, ConstraintSccIndex, RegionTracker>

Access to the SCC constraint graph. This can be used to quickly under-approximate the regions which are equal to each other and their relative orderings.

source

pub(crate) fn region_graph(&self) -> RegionGraph<'_, 'tcx, Normal>

Access to the region graph, built from the outlives constraints.

source

pub(crate) fn is_region_live_at_all_points(&self, region: RegionVid) -> bool

Returns whether the given region is considered live at all points: whether it is a placeholder or a free region.

source

pub(crate) fn is_loan_live_at( &self, loan_idx: BorrowIndex, location: Location, ) -> bool

Returns whether the loan_idx is live at the given location: whether its issuing region is contained within the type of a variable that is live at this point. Note: for now, the sets of live loans is only available when using -Zpolonius=next.

source

fn scc_representative(&self, scc: ConstraintSccIndex) -> RegionVid

Returns the representative RegionVid for a given SCC. See RegionTracker for how a region variable ID is chosen.

It is a hacky way to manage checking regions for equality, since we can ‘canonicalize’ each region to the representative 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).

Auto Trait Implementations§

§

impl<'tcx> Freeze for RegionInferenceContext<'tcx>

§

impl<'tcx> !RefUnwindSafe for RegionInferenceContext<'tcx>

§

impl<'tcx> !Send for RegionInferenceContext<'tcx>

§

impl<'tcx> !Sync for RegionInferenceContext<'tcx>

§

impl<'tcx> Unpin for RegionInferenceContext<'tcx>

§

impl<'tcx> !UnwindSafe for RegionInferenceContext<'tcx>

Blanket Implementations§

source§

impl<T> Aligned for T

source§

const ALIGN: Alignment = _

Alignment of Self.
source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T, R> CollectAndApply<T, R> for T

source§

fn collect_and_apply<I, F>(iter: I, f: F) -> R
where I: Iterator<Item = T>, F: FnOnce(&[T]) -> R,

Equivalent to f(&iter.collect::<Vec<_>>()).

source§

type Output = R

source§

impl<T> Filterable for T

source§

fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>

Creates a filterable data provider with the given name for debugging. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<P> IntoQueryParam<P> for P

source§

impl<T> MaybeResult<T> for T

source§

type Error = !

source§

fn from(_: Result<T, <T as MaybeResult<T>>::Error>) -> T

source§

fn to_result(self) -> Result<T, <T as MaybeResult<T>>::Error>

source§

impl<T> Same for T

source§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<I, T, U> Upcast<I, U> for T
where U: UpcastFrom<I, T>,

source§

fn upcast(self, interner: I) -> U

source§

impl<I, T> UpcastFrom<I, T> for T

source§

fn upcast_from(from: T, _tcx: I) -> T

source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V

source§

impl<Tcx, T> Value<Tcx> for T
where Tcx: DepContext,

source§

default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<'a, T> Captures<'a> for T
where T: ?Sized,

source§

impl<T> ErasedDestructor for T
where T: 'static,

source§

impl<T> MaybeSendSync for T

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 952 bytes