1use std::fmt::Debug;
2use std::rc::Rc;
34use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
5use rustc_index::Idx;
6use rustc_index::bit_set::SparseBitMatrix;
7use rustc_index::interval::{IntervalSet, SparseIntervalMatrix};
8use rustc_middle::bug;
9use rustc_middle::mir::{BasicBlock, Location};
10use rustc_middle::ty::{self, RegionVid};
11use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};
12use tracing::debug;
1314use crate::BorrowIndex;
15use crate::polonius::LiveLoans;
1617impl ::std::fmt::Debug for PlaceholderIndex {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
fmt.write_fmt(format_args!("PlaceholderIndex({0})", self.as_u32()))
}
}rustc_index::newtype_index! {
18/// A single integer representing a `ty::Placeholder`.
19#[debug_format = "PlaceholderIndex({})"]
20pub(crate) struct PlaceholderIndex {}
21}2223/// An individual element in a region value -- the value of a
24/// particular region variable consists of a set of these elements.
25#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for RegionElement<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
RegionElement::Location(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Location", &__self_0),
RegionElement::RootUniversalRegion(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"RootUniversalRegion", &__self_0),
RegionElement::PlaceholderRegion(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"PlaceholderRegion", &__self_0),
}
}
}Debug, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for RegionElement<'tcx> {
#[inline]
fn clone(&self) -> RegionElement<'tcx> {
match self {
RegionElement::Location(__self_0) =>
RegionElement::Location(::core::clone::Clone::clone(__self_0)),
RegionElement::RootUniversalRegion(__self_0) =>
RegionElement::RootUniversalRegion(::core::clone::Clone::clone(__self_0)),
RegionElement::PlaceholderRegion(__self_0) =>
RegionElement::PlaceholderRegion(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for RegionElement<'tcx> {
#[inline]
fn eq(&self, other: &RegionElement<'tcx>) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(RegionElement::Location(__self_0),
RegionElement::Location(__arg1_0)) => __self_0 == __arg1_0,
(RegionElement::RootUniversalRegion(__self_0),
RegionElement::RootUniversalRegion(__arg1_0)) =>
__self_0 == __arg1_0,
(RegionElement::PlaceholderRegion(__self_0),
RegionElement::PlaceholderRegion(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
26pub(crate) enum RegionElement<'tcx> {
27/// A point in the control-flow graph.
28Location(Location),
2930/// A universally quantified region from the root universe (e.g.,
31 /// a lifetime parameter).
32RootUniversalRegion(RegionVid),
3334/// A placeholder (e.g., instantiated from a `for<'a> fn(&'a u32)`
35 /// type).
36PlaceholderRegion(ty::PlaceholderRegion<'tcx>),
37}
3839/// Either a mapping of which points a region is live at (for regular bodies),
40/// or which regions are live in the body somewhere (for promoteds, which do
41/// not care about where they are live, only that they are).
42#[derive(#[automatically_derived]
impl ::core::clone::Clone for LiveRegions {
#[inline]
fn clone(&self) -> LiveRegions {
match self {
LiveRegions::AtPoints(__self_0) =>
LiveRegions::AtPoints(::core::clone::Clone::clone(__self_0)),
LiveRegions::InBody(__self_0) =>
LiveRegions::InBody(::core::clone::Clone::clone(__self_0)),
}
}
}Clone)] // FIXME(#146079)
43enum LiveRegions {
44/// region `'r` is live at locations `L`.
45AtPoints(SparseIntervalMatrix<RegionVid, PointIndex>),
46/// Region `'r` is live in function body.
47InBody(FxHashSet<RegionVid>),
48}
4950/// Records the CFG locations where each region is live. When we initially compute liveness, we use
51/// an interval matrix storing liveness ranges for each region-vid.
52#[derive(#[automatically_derived]
impl ::core::clone::Clone for LivenessValues {
#[inline]
fn clone(&self) -> LivenessValues {
LivenessValues {
location_map: ::core::clone::Clone::clone(&self.location_map),
live_regions: ::core::clone::Clone::clone(&self.live_regions),
live_loans: ::core::clone::Clone::clone(&self.live_loans),
}
}
}Clone)] // FIXME(#146079)
53pub(crate) struct LivenessValues {
54/// The map from locations to points.
55location_map: Rc<DenseLocationMap>,
5657/// Where a region is live.
58live_regions: LiveRegions,
5960/// When using `-Zpolonius=next`, the set of loans that are live at a given point in the CFG.
61live_loans: Option<LiveLoans>,
62}
6364impl LivenessValues {
65/// Create an empty map of regions to locations where they're live.
66pub(crate) fn with_specific_points(location_map: Rc<DenseLocationMap>) -> Self {
67LivenessValues {
68 live_regions: LiveRegions::AtPoints(SparseIntervalMatrix::new(
69location_map.num_points(),
70 )),
71location_map,
72 live_loans: None,
73 }
74 }
7576/// Create an empty map of regions to locations where they're live.
77 ///
78 /// Unlike `with_specific_points`, does not track exact locations where something is live, only
79 /// which regions are live.
80pub(crate) fn without_specific_points(location_map: Rc<DenseLocationMap>) -> Self {
81LivenessValues {
82 live_regions: LiveRegions::InBody(Default::default()),
83location_map,
84 live_loans: None,
85 }
86 }
8788/// Returns the liveness matrix of points where each region is live. Panics if the liveness
89 /// values have been created without any per-point data (that is, for promoteds).
90pub(crate) fn points(&self) -> &SparseIntervalMatrix<RegionVid, PointIndex> {
91if let LiveRegions::AtPoints(points) = &self.live_regions {
92points93 } else {
94::rustc_middle::util::bug::bug_fmt(format_args!("this `LivenessValues` wasn\'t created using `with_specific_points`"))bug!("this `LivenessValues` wasn't created using `with_specific_points`")95 }
96 }
9798/// Get the liveness status of a region `r`, if any.
99 /// Panics if liveness data is not tracked for any region.
100pub(crate) fn point_liveness(&self, region: RegionVid) -> Option<&IntervalSet<PointIndex>> {
101self.points().row(region)
102 }
103104/// Iterate through each region that has a value in this set.
105// We are passing query instability implications to the caller.
106#[rustc_lint_query_instability]
107 #[allow(rustc::potential_query_instability)]
108pub(crate) fn live_regions_unordered(&self) -> impl Iterator<Item = RegionVid> {
109if let LiveRegions::InBody(live_regions) = &self.live_regions {
110live_regions.iter().copied()
111 } else {
112::rustc_middle::util::bug::bug_fmt(format_args!("this `LivenessValues` wasn\'t created using `without_specific_points`"))bug!("this `LivenessValues` wasn't created using `without_specific_points`")113 }
114 }
115116/// Records `region` as being live at the given `location`.
117pub(crate) fn add_location(&mut self, region: RegionVid, location: Location) {
118let point = self.location_map.point_from_location(location);
119{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/region_infer/values.rs:119",
"rustc_borrowck::region_infer::values",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/values.rs"),
::tracing_core::__macro_support::Option::Some(119u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::values"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("LivenessValues::add_location(region={0:?}, location={1:?})",
region, location) as &dyn Value))])
});
} else { ; }
};debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location);
120match &mut self.live_regions {
121 LiveRegions::AtPoints(points) => {
122points.insert(region, point);
123 }
124125 LiveRegions::InBody(live_regions) if self.location_map.point_in_range(point) => {
126live_regions.insert(region);
127 }
128129 LiveRegions::InBody(_) => (),
130 };
131 }
132133/// Records `region` as being live at all the given `points`.
134pub(crate) fn add_points(&mut self, region: RegionVid, points: &IntervalSet<PointIndex>) {
135{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/region_infer/values.rs:135",
"rustc_borrowck::region_infer::values",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/values.rs"),
::tracing_core::__macro_support::Option::Some(135u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::values"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("LivenessValues::add_points(region={0:?}, points={1:?})",
region, points) as &dyn Value))])
});
} else { ; }
};debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points);
136match &mut self.live_regions {
137 LiveRegions::AtPoints(these_points) => {
138these_points.union_row(region, points);
139 }
140 LiveRegions::InBody(live_regions)
141if points.iter().any(|point| self.location_map.point_in_range(point)) =>
142 {
143live_regions.insert(region);
144 }
145 LiveRegions::InBody(_) => (),
146 };
147 }
148149/// Records `region` as being live at all the control-flow points.
150pub(crate) fn add_all_points(&mut self, region: RegionVid) {
151match &mut self.live_regions {
152 LiveRegions::AtPoints(points) => points.insert_all_into_row(region),
153 LiveRegions::InBody(live_regions) => {
154live_regions.insert(region);
155 }
156 }
157 }
158159/// Returns whether `region` is marked live at the given
160 /// [`location`][rustc_middle::mir::Location].
161pub(crate) fn is_live_at(&self, region: RegionVid, location: Location) -> bool {
162let point = self.location_map.point_from_location(location);
163self.is_live_at_point(region, point)
164 }
165166/// Returns whether `region` is marked live at the given
167 /// [`point`][rustc_mir_dataflow::points::PointIndex].
168#[inline]
169pub(crate) fn is_live_at_point(&self, region: RegionVid, point: PointIndex) -> bool {
170self.point_liveness(region).is_some_and(|r| r.contains(point))
171 }
172173/// Returns an iterator of all the points where `region` is live.
174fn live_points(&self, region: RegionVid) -> impl Iterator<Item = PointIndex> {
175self.point_liveness(region)
176 .into_iter()
177 .flat_map(|set| set.iter())
178 .take_while(|&p| self.location_map.point_in_range(p))
179 }
180181/// For debugging purposes, returns a pretty-printed string of the points where the `region` is
182 /// live.
183pub(crate) fn pretty_print_live_points(&self, region: RegionVid) -> String {
184pretty_print_region_elements(
185self.live_points(region)
186 .map(|p| RegionElement::Location(self.location_map.to_location(p))),
187 )
188 }
189190#[inline]
191pub(crate) fn point_from_location(&self, location: Location) -> PointIndex {
192self.location_map.point_from_location(location)
193 }
194195#[inline]
196pub(crate) fn location_from_point(&self, point: PointIndex) -> Location {
197self.location_map.to_location(point)
198 }
199200/// When using `-Zpolonius=next`, records the given live loans for the loan scopes and active
201 /// loans dataflow computations.
202pub(crate) fn record_live_loans(&mut self, live_loans: LiveLoans) {
203self.live_loans = Some(live_loans);
204 }
205206/// When using `-Zpolonius=next`, returns whether the `loan_idx` is live at the given `point`.
207pub(crate) fn is_loan_live_at(&self, loan_idx: BorrowIndex, point: PointIndex) -> bool {
208self.live_loans
209 .as_ref()
210 .expect("Accessing live loans requires `-Zpolonius=next`")
211 .contains(point, loan_idx)
212 }
213}
214215/// Maps from `ty::PlaceholderRegion` values that are used in the rest of
216/// rustc to the internal `PlaceholderIndex` values that are used in
217/// NLL.
218#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for PlaceholderIndices<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"PlaceholderIndices", "indices", &&self.indices)
}
}Debug, #[automatically_derived]
impl<'tcx> ::core::default::Default for PlaceholderIndices<'tcx> {
#[inline]
fn default() -> PlaceholderIndices<'tcx> {
PlaceholderIndices { indices: ::core::default::Default::default() }
}
}Default)]
219#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for PlaceholderIndices<'tcx> {
#[inline]
fn clone(&self) -> PlaceholderIndices<'tcx> {
PlaceholderIndices {
indices: ::core::clone::Clone::clone(&self.indices),
}
}
}Clone)] // FIXME(#146079)
220pub(crate) struct PlaceholderIndices<'tcx> {
221 indices: FxIndexSet<ty::PlaceholderRegion<'tcx>>,
222}
223224impl<'tcx> PlaceholderIndices<'tcx> {
225/// Returns the `PlaceholderIndex` for the inserted `PlaceholderRegion`
226pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion<'tcx>) -> PlaceholderIndex {
227let (index, _) = self.indices.insert_full(placeholder);
228index.into()
229 }
230231pub(crate) fn lookup_index(
232&self,
233 placeholder: ty::PlaceholderRegion<'tcx>,
234 ) -> PlaceholderIndex {
235self.indices.get_index_of(&placeholder).unwrap().into()
236 }
237238pub(crate) fn lookup_placeholder(
239&self,
240 placeholder: PlaceholderIndex,
241 ) -> ty::PlaceholderRegion<'tcx> {
242self.indices[placeholder.index()]
243 }
244245pub(crate) fn len(&self) -> usize {
246self.indices.len()
247 }
248}
249250/// Stores the full values for a set of regions (in contrast to
251/// `LivenessValues`, which only stores those points in the where a
252/// region is live). The full value for a region may contain points in
253/// the CFG, but also free regions as well as bound universe
254/// placeholders.
255///
256/// Example:
257///
258/// ```text
259/// fn foo(x: &'a u32) -> &'a u32 {
260/// let y: &'0 u32 = x; // let's call this `'0`
261/// y
262/// }
263/// ```
264///
265/// Here, the variable `'0` would contain the free region `'a`,
266/// because (since it is returned) it must live for at least `'a`. But
267/// it would also contain various points from within the function.
268pub(crate) struct RegionValues<'tcx, N: Idx> {
269 location_map: Rc<DenseLocationMap>,
270 placeholder_indices: PlaceholderIndices<'tcx>,
271 points: SparseIntervalMatrix<N, PointIndex>,
272 free_regions: SparseBitMatrix<N, RegionVid>,
273274/// Placeholders represent bound regions -- so something like `'a`
275 /// in `for<'a> fn(&'a u32)`.
276placeholders: SparseBitMatrix<N, PlaceholderIndex>,
277}
278279impl<'tcx, N: Idx> RegionValues<'tcx, N> {
280/// Creates a new set of "region values" that tracks causal information.
281 /// Each of the regions in num_region_variables will be initialized with an
282 /// empty set of points and no causal information.
283pub(crate) fn new(
284 location_map: Rc<DenseLocationMap>,
285 num_universal_regions: usize,
286 placeholder_indices: PlaceholderIndices<'tcx>,
287 ) -> Self {
288let num_points = location_map.num_points();
289let num_placeholders = placeholder_indices.len();
290Self {
291location_map,
292 points: SparseIntervalMatrix::new(num_points),
293placeholder_indices,
294 free_regions: SparseBitMatrix::new(num_universal_regions),
295 placeholders: SparseBitMatrix::new(num_placeholders),
296 }
297 }
298299/// Adds all elements in `r_from` to `r_to` (because e.g., `r_to:
300 /// r_from`).
301pub(crate) fn add_region(&mut self, r_to: N, r_from: N) -> bool {
302self.points.union_rows(r_from, r_to)
303 | self.free_regions.union_rows(r_from, r_to)
304 | self.placeholders.union_rows(r_from, r_to)
305 }
306307/// Returns the lowest statement index in `start..=end` which is not contained by `r`.
308pub(crate) fn first_non_contained_inclusive(
309&self,
310 r: N,
311 block: BasicBlock,
312 start: usize,
313 end: usize,
314 ) -> Option<usize> {
315let row = self.points.row(r)?;
316let block = self.location_map.entry_point(block);
317let start = block.plus(start);
318let end = block.plus(end);
319let first_unset = row.first_unset_in(start..=end)?;
320Some(first_unset.index() - block.index())
321 }
322323/// Merge a row of liveness into our points.
324pub(crate) fn merge_liveness(&mut self, to: N, liveness: &IntervalSet<PointIndex>) {
325self.points.union_row(to, liveness);
326 }
327328/// Returns `true` if `sup_region` contains all the CFG points that
329 /// `sub_region` contains. Ignores universal regions.
330pub(crate) fn contains_points(&self, sup_region: N, sub_region: N) -> bool {
331if let Some(sub_row) = self.points.row(sub_region) {
332if let Some(sup_row) = self.points.row(sup_region) {
333sup_row.superset(sub_row)
334 } else {
335// sup row is empty, so sub row must be empty
336sub_row.is_empty()
337 }
338 } else {
339// sub row is empty, always true
340true
341}
342 }
343344/// Returns the locations contained within a given region `r`.
345pub(crate) fn locations_outlived_by(&self, r: N) -> impl Iterator<Item = Location> {
346self.points.row(r).into_iter().flat_map(move |set| {
347set.iter()
348 .take_while(move |&p| self.location_map.point_in_range(p))
349 .map(move |p| self.location_map.to_location(p))
350 })
351 }
352353/// Returns just the universal regions that are contained in a given region's value.
354pub(crate) fn universal_regions_outlived_by(&self, r: N) -> impl Iterator<Item = RegionVid> {
355self.free_regions.row(r).into_iter().flat_map(|set| set.iter())
356 }
357358/// Returns all the elements contained in a given region's value.
359pub(crate) fn placeholders_contained_in(
360&self,
361 r: N,
362 ) -> impl Iterator<Item = ty::PlaceholderRegion<'tcx>> {
363self.placeholders
364 .row(r)
365 .into_iter()
366 .flat_map(|set| set.iter())
367 .map(move |p| self.placeholder_indices.lookup_placeholder(p))
368 }
369370/// Returns all the elements contained in a given region's value.
371pub(crate) fn elements_contained_in(&self, r: N) -> impl Iterator<Item = RegionElement<'tcx>> {
372let points_iter = self.locations_outlived_by(r).map(RegionElement::Location);
373374let free_regions_iter =
375self.universal_regions_outlived_by(r).map(RegionElement::RootUniversalRegion);
376377let placeholder_universes_iter =
378self.placeholders_contained_in(r).map(RegionElement::PlaceholderRegion);
379380points_iter.chain(free_regions_iter).chain(placeholder_universes_iter)
381 }
382383/// Returns a "pretty" string value of the region. Meant for debugging.
384pub(crate) fn region_value_str(&self, r: N) -> String {
385pretty_print_region_elements(self.elements_contained_in(r))
386 }
387388/// Add a the free region with rvid `region` to SCC `scc`
389pub(crate) fn add_free_region(&mut self, scc: N, region: RegionVid) {
390self.free_regions.insert(scc, region);
391 }
392393pub(crate) fn add_placeholder(&mut self, scc: N, placeholder: ty::PlaceholderRegion<'tcx>) {
394let index = self.placeholder_indices.lookup_index(placeholder);
395self.placeholders.insert(scc, index);
396 }
397398/// Determine if `scc` contains the CFG point `p`.
399pub(crate) fn contains_point(&self, scc: N, p: Location) -> bool {
400let index = self.location_map.point_from_location(p);
401self.points.contains(scc, index)
402 }
403404/// Determine if `scc` contains the free region `free_region`.
405pub(crate) fn contains_free_region(&self, scc: N, free_region: RegionVid) -> bool {
406self.free_regions.contains(scc, free_region)
407 }
408}
409410/// For debugging purposes, returns a pretty-printed string of the given points.
411pub(crate) fn pretty_print_points(
412 location_map: &DenseLocationMap,
413 points: impl IntoIterator<Item = PointIndex>,
414) -> String {
415pretty_print_region_elements(
416points417 .into_iter()
418 .take_while(|&p| location_map.point_in_range(p))
419 .map(|p| location_map.to_location(p))
420 .map(RegionElement::Location),
421 )
422}
423424/// For debugging purposes, returns a pretty-printed string of the given region elements.
425fn pretty_print_region_elements<'tcx>(
426 elements: impl IntoIterator<Item = RegionElement<'tcx>>,
427) -> String {
428let mut result = String::new();
429result.push('{');
430431// Set to Some(l1, l2) when we have observed all the locations
432 // from l1..=l2 (inclusive) but not yet printed them. This
433 // gets extended if we then see l3 where l3 is the successor
434 // to l2.
435let mut open_location: Option<(Location, Location)> = None;
436437let mut sep = "";
438let mut push_sep = |s: &mut String| {
439s.push_str(sep);
440sep = ", ";
441 };
442443for element in elements {
444match element {
445 RegionElement::Location(l) => {
446if let Some((location1, location2)) = open_location {
447if location2.block == l.block
448 && location2.statement_index == l.statement_index - 1
449{
450 open_location = Some((location1, l));
451continue;
452 }
453454 push_sep(&mut result);
455 push_location_range(&mut result, location1, location2);
456 }
457458 open_location = Some((l, l));
459 }
460461 RegionElement::RootUniversalRegion(fr) => {
462if let Some((location1, location2)) = open_location {
463 push_sep(&mut result);
464 push_location_range(&mut result, location1, location2);
465 open_location = None;
466 }
467468 push_sep(&mut result);
469 result.push_str(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0:?}", fr))
})format!("{fr:?}"));
470 }
471472 RegionElement::PlaceholderRegion(placeholder) => {
473if let Some((location1, location2)) = open_location {
474 push_sep(&mut result);
475 push_location_range(&mut result, location1, location2);
476 open_location = None;
477 }
478479 push_sep(&mut result);
480 result.push_str(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0:?}", placeholder))
})format!("{placeholder:?}"));
481 }
482 }
483 }
484485if let Some((location1, location2)) = open_location {
486push_sep(&mut result);
487push_location_range(&mut result, location1, location2);
488 }
489490result.push('}');
491492return result;
493494fn push_location_range(s: &mut String, location1: Location, location2: Location) {
495if location1 == location2 {
496s.push_str(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0:?}", location1))
})format!("{location1:?}"));
497 } else {
498match (&location1.block, &location2.block) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(location1.block, location2.block);
499s.push_str(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0:?}[{1}..={2}]", location1.block,
location1.statement_index, location2.statement_index))
})format!(
500"{:?}[{}..={}]",
501 location1.block, location1.statement_index, location2.statement_index
502 ));
503 }
504 }
505}