Skip to main content

rustc_mir_dataflow/
value_analysis.rs

1use std::debug_assert_matches;
2use std::fmt::{Debug, Formatter};
3use std::ops::Range;
4
5use rustc_abi::{FieldIdx, VariantIdx};
6use rustc_data_structures::fx::{FxHashMap, FxIndexSet, StdEntry};
7use rustc_index::IndexVec;
8use rustc_index::bit_set::GrowableBitSet;
9use rustc_middle::mir::visit::{PlaceContext, Visitor};
10use rustc_middle::mir::*;
11use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized};
12use tracing::debug;
13
14use crate::JoinSemiLattice;
15use crate::lattice::{HasBottom, HasTop};
16
17#[automatically_derived]
impl ::core::marker::Copy for PlaceIndex { }
impl PlaceIndex {
    #[doc = r" Maximum value the index can take, as a `u32`."]
    pub const MAX_AS_U32: u32 = 0xFFFF_FF00;
    #[doc = r" Maximum value the index can take."]
    pub const MAX: Self = Self::from_u32(0xFFFF_FF00);
    #[doc = r" Zero value of the index."]
    pub const ZERO: Self = Self::from_u32(0);
    #[doc = r" Creates a new index from a given `usize`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_usize(value: usize) -> Self {
        if !(value <= (0xFFFF_FF00 as usize)) {
            ::core::panicking::panic("assertion failed: value <= (0xFFFF_FF00 as usize)")
        };
        unsafe { Self::from_u32_unchecked(value as u32) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u32(value: u32) -> Self {
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u16`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u16(value: u16) -> Self {
        let value = value as u32;
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Safety"]
    #[doc = r""]
    #[doc =
    r" The provided value must be less than or equal to the maximum value for the newtype."]
    #[doc =
    r" Providing a value outside this range is undefined due to layout restrictions."]
    #[doc = r""]
    #[doc = r" Prefer using `from_u32`."]
    #[inline]
    pub const unsafe fn from_u32_unchecked(value: u32) -> Self {
        Self {
            private_use_as_methods_instead: unsafe {
                std::mem::transmute(value)
            },
        }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn index(self) -> usize { self.as_usize() }
    #[doc = r" Extracts the value of this index as a `u32`."]
    #[inline]
    pub const fn as_u32(self) -> u32 {
        unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn as_usize(self) -> usize { self.as_u32() as usize }
}
impl std::ops::Add<usize> for PlaceIndex {
    type Output = Self;
    #[inline]
    fn add(self, other: usize) -> Self {
        Self::from_usize(self.index() + other)
    }
}
impl std::ops::AddAssign<usize> for PlaceIndex {
    #[inline]
    fn add_assign(&mut self, other: usize) { *self = *self + other; }
}
impl rustc_index::Idx for PlaceIndex {
    #[inline]
    fn new(value: usize) -> Self { Self::from_usize(value) }
    #[inline]
    fn index(self) -> usize { self.as_usize() }
}
impl From<PlaceIndex> for u32 {
    #[inline]
    fn from(v: PlaceIndex) -> u32 { v.as_u32() }
}
impl From<PlaceIndex> for usize {
    #[inline]
    fn from(v: PlaceIndex) -> usize { v.as_usize() }
}
impl From<usize> for PlaceIndex {
    #[inline]
    fn from(value: usize) -> Self { Self::from_usize(value) }
}
impl From<u32> for PlaceIndex {
    #[inline]
    fn from(value: u32) -> Self { Self::from_u32(value) }
}
impl ::std::cmp::Eq for PlaceIndex {}
impl ::std::cmp::PartialEq for PlaceIndex {
    fn eq(&self, other: &Self) -> bool { self.as_u32().eq(&other.as_u32()) }
}
impl ::std::marker::StructuralPartialEq for PlaceIndex {}
impl ::std::hash::Hash for PlaceIndex {
    fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
        self.as_u32().hash(state)
    }
}
impl ::std::fmt::Debug for PlaceIndex {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("{0}", self.as_u32()))
    }
}rustc_index::newtype_index!(
18    /// This index uniquely identifies a place.
19    ///
20    /// Not every place has a `PlaceIndex`, and not every `PlaceIndex` corresponds to a tracked
21    /// place. However, every tracked place and all places along its projection have a `PlaceIndex`.
22    pub struct PlaceIndex {}
23);
24
25#[automatically_derived]
impl ::core::marker::Copy for ValueIndex { }
impl ValueIndex {
    #[doc = r" Maximum value the index can take, as a `u32`."]
    pub const MAX_AS_U32: u32 = 0xFFFF_FF00;
    #[doc = r" Maximum value the index can take."]
    pub const MAX: Self = Self::from_u32(0xFFFF_FF00);
    #[doc = r" Zero value of the index."]
    pub const ZERO: Self = Self::from_u32(0);
    #[doc = r" Creates a new index from a given `usize`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_usize(value: usize) -> Self {
        if !(value <= (0xFFFF_FF00 as usize)) {
            ::core::panicking::panic("assertion failed: value <= (0xFFFF_FF00 as usize)")
        };
        unsafe { Self::from_u32_unchecked(value as u32) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u32(value: u32) -> Self {
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u16`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u16(value: u16) -> Self {
        let value = value as u32;
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Safety"]
    #[doc = r""]
    #[doc =
    r" The provided value must be less than or equal to the maximum value for the newtype."]
    #[doc =
    r" Providing a value outside this range is undefined due to layout restrictions."]
    #[doc = r""]
    #[doc = r" Prefer using `from_u32`."]
    #[inline]
    pub const unsafe fn from_u32_unchecked(value: u32) -> Self {
        Self {
            private_use_as_methods_instead: unsafe {
                std::mem::transmute(value)
            },
        }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn index(self) -> usize { self.as_usize() }
    #[doc = r" Extracts the value of this index as a `u32`."]
    #[inline]
    pub const fn as_u32(self) -> u32 {
        unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn as_usize(self) -> usize { self.as_u32() as usize }
}
impl std::ops::Add<usize> for ValueIndex {
    type Output = Self;
    #[inline]
    fn add(self, other: usize) -> Self {
        Self::from_usize(self.index() + other)
    }
}
impl std::ops::AddAssign<usize> for ValueIndex {
    #[inline]
    fn add_assign(&mut self, other: usize) { *self = *self + other; }
}
impl rustc_index::Idx for ValueIndex {
    #[inline]
    fn new(value: usize) -> Self { Self::from_usize(value) }
    #[inline]
    fn index(self) -> usize { self.as_usize() }
}
impl From<ValueIndex> for u32 {
    #[inline]
    fn from(v: ValueIndex) -> u32 { v.as_u32() }
}
impl From<ValueIndex> for usize {
    #[inline]
    fn from(v: ValueIndex) -> usize { v.as_usize() }
}
impl From<usize> for ValueIndex {
    #[inline]
    fn from(value: usize) -> Self { Self::from_usize(value) }
}
impl From<u32> for ValueIndex {
    #[inline]
    fn from(value: u32) -> Self { Self::from_u32(value) }
}
impl ::std::cmp::Eq for ValueIndex {}
impl ::std::cmp::PartialEq for ValueIndex {
    fn eq(&self, other: &Self) -> bool { self.as_u32().eq(&other.as_u32()) }
}
impl ::std::marker::StructuralPartialEq for ValueIndex {}
impl ::std::hash::Hash for ValueIndex {
    fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
        self.as_u32().hash(state)
    }
}
impl ::std::fmt::Debug for ValueIndex {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("{0}", self.as_u32()))
    }
}rustc_index::newtype_index!(
26    /// This index uniquely identifies a tracked place and therefore a slot in [`State`].
27    pub struct ValueIndex {}
28);
29
30/// See [`State`].
31#[derive(#[automatically_derived]
impl<V: ::core::cmp::PartialEq> ::core::marker::StructuralPartialEq for
    StateData<V> {
}
#[automatically_derived]
impl<V: ::core::cmp::PartialEq> ::core::cmp::PartialEq for StateData<V> {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.bottom == other.bottom && self.map == other.map
    }
}PartialEq, #[automatically_derived]
impl<V: ::core::cmp::Eq> ::core::cmp::Eq for StateData<V> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<V>;
        let _: ::core::cmp::AssertParamIsEq<FxHashMap<ValueIndex, V>>;
    }
}Eq, #[automatically_derived]
impl<V: ::core::fmt::Debug> ::core::fmt::Debug for StateData<V> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "StateData",
            "bottom", &self.bottom, "map", &&self.map)
    }
}Debug)]
32pub struct StateData<V> {
33    bottom: V,
34    /// This map only contains values that are not `⊥`.
35    map: FxHashMap<ValueIndex, V>,
36}
37
38impl<V: HasBottom> StateData<V> {
39    fn new() -> StateData<V> {
40        StateData { bottom: V::BOTTOM, map: FxHashMap::default() }
41    }
42
43    fn get(&self, idx: ValueIndex) -> &V {
44        self.map.get(&idx).unwrap_or(&self.bottom)
45    }
46
47    fn insert(&mut self, idx: ValueIndex, elem: V) {
48        if elem.is_bottom() {
49            self.map.remove(&idx);
50        } else {
51            self.map.insert(idx, elem);
52        }
53    }
54}
55
56impl<V: Clone> Clone for StateData<V> {
57    fn clone(&self) -> Self {
58        StateData { bottom: self.bottom.clone(), map: self.map.clone() }
59    }
60
61    fn clone_from(&mut self, source: &Self) {
62        self.map.clone_from(&source.map)
63    }
64}
65
66impl<V: JoinSemiLattice + Clone> JoinSemiLattice for StateData<V> {
67    fn join(&mut self, other: &Self) -> bool {
68        let mut changed = false;
69        #[allow(rustc::potential_query_instability)]
70        for (i, v) in other.map.iter() {
71            match self.map.entry(*i) {
72                StdEntry::Vacant(e) => {
73                    e.insert(v.clone());
74                    changed = true
75                }
76                StdEntry::Occupied(e) => changed |= e.into_mut().join(v),
77            }
78        }
79        changed
80    }
81}
82
83/// Dataflow state.
84///
85/// Every instance specifies a lattice that represents the possible values of a single tracked
86/// place. If we call this lattice `V` and set of tracked places `P`, then a [`State`] is an
87/// element of `{unreachable} ∪ (P -> V)`. This again forms a lattice, where the bottom element is
88/// `unreachable` and the top element is the mapping `p ↦ ⊤`. Note that the mapping `p ↦ ⊥` is not
89/// the bottom element (because joining an unreachable and any other reachable state yields a
90/// reachable state). All operations on unreachable states are ignored.
91///
92/// Flooding means assigning a value (by default `⊤`) to all tracked projections of a given place.
93#[derive(#[automatically_derived]
impl<V: ::core::cmp::PartialEq> ::core::marker::StructuralPartialEq for
    State<V> {
}
#[automatically_derived]
impl<V: ::core::cmp::PartialEq> ::core::cmp::PartialEq for State<V> {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::Reachable(__self_0), Self::Reachable(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl<V: ::core::cmp::Eq> ::core::cmp::Eq for State<V> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<StateData<V>>;
    }
}Eq, #[automatically_derived]
impl<V: ::core::fmt::Debug> ::core::fmt::Debug for State<V> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Unreachable =>
                ::core::fmt::Formatter::write_str(f, "Unreachable"),
            Self::Reachable(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Reachable", &__self_0),
        }
    }
}Debug)]
94pub enum State<V> {
95    Unreachable,
96    Reachable(StateData<V>),
97}
98
99impl<V: Clone> Clone for State<V> {
100    fn clone(&self) -> Self {
101        match self {
102            Self::Reachable(x) => Self::Reachable(x.clone()),
103            Self::Unreachable => Self::Unreachable,
104        }
105    }
106
107    fn clone_from(&mut self, source: &Self) {
108        match (&mut *self, source) {
109            (Self::Reachable(x), Self::Reachable(y)) => {
110                x.clone_from(&y);
111            }
112            _ => *self = source.clone(),
113        }
114    }
115}
116
117impl<V: Clone + HasBottom> State<V> {
118    pub fn new_reachable() -> State<V> {
119        State::Reachable(StateData::new())
120    }
121
122    pub fn is_reachable(&self) -> bool {
123        #[allow(non_exhaustive_omitted_patterns)] match self {
    State::Reachable(_) => true,
    _ => false,
}matches!(self, State::Reachable(_))
124    }
125
126    /// Assign `value` to all places that are contained in `place` or may alias one.
127    pub fn flood_with(&mut self, place: PlaceRef<'_>, map: &Map<'_>, value: V) {
128        self.flood_with_tail_elem(place, None, map, value)
129    }
130
131    /// Assign `TOP` to all places that are contained in `place` or may alias one.
132    pub fn flood(&mut self, place: PlaceRef<'_>, map: &Map<'_>)
133    where
134        V: HasTop,
135    {
136        self.flood_with(place, map, V::TOP)
137    }
138
139    /// Assign `value` to the discriminant of `place` and all places that may alias it.
140    fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map<'_>, value: V) {
141        self.flood_with_tail_elem(place, Some(TrackElem::Discriminant), map, value)
142    }
143
144    /// Assign `TOP` to the discriminant of `place` and all places that may alias it.
145    pub fn flood_discr(&mut self, place: PlaceRef<'_>, map: &Map<'_>)
146    where
147        V: HasTop,
148    {
149        self.flood_discr_with(place, map, V::TOP)
150    }
151
152    /// This method is the most general version of the `flood_*` method.
153    ///
154    /// Assign `value` on the given place and all places that may alias it. In particular, when
155    /// the given place has a variant downcast, we invoke the function on all the other variants.
156    ///
157    /// `tail_elem` allows to support discriminants that are not a place in MIR, but that we track
158    /// as such.
159    fn flood_with_tail_elem(
160        &mut self,
161        place: PlaceRef<'_>,
162        tail_elem: Option<TrackElem>,
163        map: &Map<'_>,
164        value: V,
165    ) {
166        let State::Reachable(values) = self else { return };
167        map.for_each_aliasing_place(place, tail_elem, &mut |vi| values.insert(vi, value.clone()));
168    }
169
170    /// Low-level method that assigns to a place.
171    /// This does nothing if the place is not tracked.
172    ///
173    /// The target place must have been flooded before calling this method.
174    fn insert_idx(&mut self, target: PlaceIndex, result: ValueOrPlace<V>, map: &Map<'_>) {
175        match result {
176            ValueOrPlace::Value(value) => self.insert_value_idx(target, value, map),
177            ValueOrPlace::Place(source) => self.insert_place_idx(target, source, map),
178        }
179    }
180
181    /// Low-level method that assigns a value to a place.
182    /// This does nothing if the place is not tracked.
183    ///
184    /// The target place must have been flooded before calling this method.
185    pub fn insert_value_idx(&mut self, target: PlaceIndex, value: V, map: &Map<'_>) {
186        let State::Reachable(values) = self else { return };
187        if let Some(value_index) = map.places[target].value_index {
188            values.insert(value_index, value)
189        }
190    }
191
192    /// Copies `source` to `target`, including all tracked places beneath.
193    ///
194    /// If `target` contains a place that is not contained in `source`, it will be overwritten with
195    /// Top. Also, because this will copy all entries one after another, it may only be used for
196    /// places that are non-overlapping or identical.
197    ///
198    /// The target place must have been flooded before calling this method.
199    pub fn insert_place_idx(&mut self, target: PlaceIndex, source: PlaceIndex, map: &Map<'_>) {
200        let State::Reachable(values) = self else { return };
201        map.for_each_value_pair(target, source, &mut |target, source| {
202            values.insert(target, values.get(source).clone());
203        });
204    }
205
206    /// Helper method to interpret `target = result`.
207    pub fn assign(&mut self, target: PlaceRef<'_>, result: ValueOrPlace<V>, map: &Map<'_>)
208    where
209        V: HasTop,
210    {
211        self.flood(target, map);
212        if let Some(target) = map.find(target) {
213            self.insert_idx(target, result, map);
214        }
215    }
216
217    /// Retrieve the value stored for a place, or `None` if it is not tracked.
218    fn try_get(&self, place: PlaceRef<'_>, map: &Map<'_>) -> Option<V> {
219        let place = map.find(place)?;
220        self.try_get_idx(place, map)
221    }
222
223    /// Retrieve the discriminant stored for a place, or `None` if it is not tracked.
224    fn try_get_discr(&self, place: PlaceRef<'_>, map: &Map<'_>) -> Option<V> {
225        let place = map.find_discr(place)?;
226        self.try_get_idx(place, map)
227    }
228
229    /// Retrieve the value stored for a place index, or `None` if it is not tracked.
230    fn try_get_idx(&self, place: PlaceIndex, map: &Map<'_>) -> Option<V> {
231        match self {
232            State::Reachable(values) => {
233                map.places[place].value_index.map(|v| values.get(v).clone())
234            }
235            State::Unreachable => None,
236        }
237    }
238
239    /// Retrieve the value stored for a place, or ⊤ if it is not tracked.
240    ///
241    /// This method returns ⊥ if the place is tracked and the state is unreachable.
242    pub fn get(&self, place: PlaceRef<'_>, map: &Map<'_>) -> V
243    where
244        V: HasBottom + HasTop,
245    {
246        match self {
247            State::Reachable(_) => self.try_get(place, map).unwrap_or(V::TOP),
248            // Because this is unreachable, we can return any value we want.
249            State::Unreachable => V::BOTTOM,
250        }
251    }
252
253    /// Retrieve the value stored for a place, or ⊤ if it is not tracked.
254    ///
255    /// This method returns ⊥ the current state is unreachable.
256    pub fn get_discr(&self, place: PlaceRef<'_>, map: &Map<'_>) -> V
257    where
258        V: HasBottom + HasTop,
259    {
260        match self {
261            State::Reachable(_) => self.try_get_discr(place, map).unwrap_or(V::TOP),
262            // Because this is unreachable, we can return any value we want.
263            State::Unreachable => V::BOTTOM,
264        }
265    }
266
267    /// Retrieve the value stored for a place index, or ⊤ if it is not tracked.
268    ///
269    /// This method returns ⊥ the current state is unreachable.
270    pub fn get_idx(&self, place: PlaceIndex, map: &Map<'_>) -> V
271    where
272        V: HasBottom + HasTop,
273    {
274        match self {
275            State::Reachable(values) => {
276                map.places[place].value_index.map(|v| values.get(v).clone()).unwrap_or(V::TOP)
277            }
278            State::Unreachable => {
279                // Because this is unreachable, we can return any value we want.
280                V::BOTTOM
281            }
282        }
283    }
284}
285
286impl<V: JoinSemiLattice + Clone> JoinSemiLattice for State<V> {
287    fn join(&mut self, other: &Self) -> bool {
288        match (&mut *self, other) {
289            (_, State::Unreachable) => false,
290            (State::Unreachable, _) => {
291                *self = other.clone();
292                true
293            }
294            (State::Reachable(this), State::Reachable(other)) => this.join(other),
295        }
296    }
297}
298
299/// Partial mapping from [`Place`] to [`PlaceIndex`], where some places also have a [`ValueIndex`].
300///
301/// This data structure essentially maintains a tree of places and their projections. Some
302/// additional bookkeeping is done, to speed up traversal over this tree:
303/// - For iteration, every [`PlaceInfo`] contains an intrusive linked list of its children.
304/// - To directly get the child for a specific projection, there is a `projections` map.
305#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Map<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["locals", "projections", "places", "value_count", "mode",
                        "inner_values", "inner_values_buffer"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.locals, &self.projections, &self.places,
                        &self.value_count, &self.mode, &self.inner_values,
                        &&self.inner_values_buffer];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "Map", names,
            values)
    }
}Debug)]
306pub struct Map<'tcx> {
307    locals: IndexVec<Local, Option<PlaceIndex>>,
308    projections: FxHashMap<(PlaceIndex, TrackElem), PlaceIndex>,
309    places: IndexVec<PlaceIndex, PlaceInfo<'tcx>>,
310    value_count: usize,
311    mode: PlaceCollectionMode,
312    // The Range corresponds to a slice into `inner_values_buffer`.
313    inner_values: IndexVec<PlaceIndex, Range<usize>>,
314    inner_values_buffer: Vec<ValueIndex>,
315}
316
317#[derive(#[automatically_derived]
impl ::core::marker::Copy for PlaceCollectionMode { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for PlaceCollectionMode { }
#[automatically_derived]
impl ::core::clone::Clone for PlaceCollectionMode {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<Option<usize>>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for PlaceCollectionMode {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Full { value_limit: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Full",
                    "value_limit", &__self_0),
            Self::OnDemand =>
                ::core::fmt::Formatter::write_str(f, "OnDemand"),
        }
    }
}Debug)]
318pub enum PlaceCollectionMode {
319    Full { value_limit: Option<usize> },
320    OnDemand,
321}
322
323impl<'tcx> Map<'tcx> {
324    /// Returns a map that only tracks places whose type has scalar layout.
325    ///
326    /// This is currently the only way to create a [`Map`]. The way in which the tracked places are
327    /// chosen is an implementation detail and may not be relied upon (other than that their type
328    /// are scalars).
329    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("new",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(329u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("mode")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("mode");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&mode)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: Self = loop {};
            return __tracing_attr_fake_return;
        }
        {
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs:331",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(331u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("def_id")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("def_id");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::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};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&body.source.def_id())
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let capacity = 4 * body.local_decls.len();
            let mut map =
                Self {
                    locals: IndexVec::from_elem(None, &body.local_decls),
                    projections: FxHashMap::default(),
                    places: IndexVec::with_capacity(capacity),
                    value_count: 0,
                    mode,
                    inner_values: IndexVec::new(),
                    inner_values_buffer: Vec::new(),
                };
            map.register_locals(tcx, body);
            match mode {
                PlaceCollectionMode::Full { value_limit } => {
                    map.collect_places(tcx, body);
                    map.propagate_assignments(tcx, body);
                    map.create_values(tcx, body, value_limit);
                    map.trim_useless_places();
                }
                PlaceCollectionMode::OnDemand => {}
            }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs:352",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(352u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::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};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("registered {0} places ({1} nodes in total)",
                                                                map.value_count, map.places.len()) as
                                                        &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            map
        }
    }
}#[tracing::instrument(level = "trace", skip(tcx, body))]
330    pub fn new(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, mode: PlaceCollectionMode) -> Self {
331        tracing::trace!(def_id=?body.source.def_id());
332        let capacity = 4 * body.local_decls.len();
333        let mut map = Self {
334            locals: IndexVec::from_elem(None, &body.local_decls),
335            projections: FxHashMap::default(),
336            places: IndexVec::with_capacity(capacity),
337            value_count: 0,
338            mode,
339            inner_values: IndexVec::new(),
340            inner_values_buffer: Vec::new(),
341        };
342        map.register_locals(tcx, body);
343        match mode {
344            PlaceCollectionMode::Full { value_limit } => {
345                map.collect_places(tcx, body);
346                map.propagate_assignments(tcx, body);
347                map.create_values(tcx, body, value_limit);
348                map.trim_useless_places();
349            }
350            PlaceCollectionMode::OnDemand => {}
351        }
352        debug!("registered {} places ({} nodes in total)", map.value_count, map.places.len());
353        map
354    }
355
356    /// Register all non-excluded places that have scalar layout.
357    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("register_locals",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(357u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{ meta.fields().value_set_all(&[]) })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let exclude = excluded_locals(body);
            for (local, decl) in body.local_decls.iter_enumerated() {
                if exclude.contains(local) { continue; }
                if decl.ty.is_async_drop_in_place_coroutine(tcx) { continue; }
                if true {
                    if !self.locals[local].is_none() {
                        ::core::panicking::panic("assertion failed: self.locals[local].is_none()")
                    };
                };
                let place = self.places.push(PlaceInfo::new(decl.ty, None));
                self.locals[local] = Some(place);
            }
        }
    }
}#[tracing::instrument(level = "trace", skip(self, tcx, body))]
358    fn register_locals(&mut self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
359        let exclude = excluded_locals(body);
360
361        // Start by constructing the places for each bare local.
362        for (local, decl) in body.local_decls.iter_enumerated() {
363            if exclude.contains(local) {
364                continue;
365            }
366            if decl.ty.is_async_drop_in_place_coroutine(tcx) {
367                continue;
368            }
369
370            // Create a place for the local.
371            debug_assert!(self.locals[local].is_none());
372            let place = self.places.push(PlaceInfo::new(decl.ty, None));
373            self.locals[local] = Some(place);
374        }
375    }
376
377    /// Collect syntactic places from body, and create `PlaceIndex` for them.
378    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("collect_places",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(378u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{ meta.fields().value_set_all(&[]) })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let mut collector = PlaceCollector { tcx, body, map: self };
            collector.visit_body(body);
        }
    }
}#[tracing::instrument(level = "trace", skip(self, tcx, body))]
379    fn collect_places(&mut self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
380        let mut collector = PlaceCollector { tcx, body, map: self };
381        collector.visit_body(body);
382    }
383
384    /// Just collecting syntactic places is not enough. We may need to propagate this pattern:
385    ///      _1 = (const 5u32, const 13i64);
386    ///      _2 = _1;
387    ///      _3 = (_2.0 as u32);
388    ///
389    /// `_1.0` does not appear, but we still need to track it. This is achieved by propagating
390    /// projections from assignments. We recorded an assignment between `_2` and `_1`, so we
391    /// want `_1` and `_2` to have the same sub-places.
392    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("propagate_assignments",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(392u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{ meta.fields().value_set_all(&[]) })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let mut assignments = FxIndexSet::default();
            for bbdata in body.basic_blocks.iter() {
                for stmt in bbdata.statements.iter() {
                    let Some((lhs, rhs)) =
                        stmt.kind.as_assign() else { continue };
                    match rhs {
                        Rvalue::Use(Operand::Move(rhs) | Operand::Copy(rhs), _) |
                            Rvalue::CopyForDeref(rhs) => {
                            let Some(lhs) =
                                self.register_place_and_discr(tcx, body,
                                    *lhs) else { continue; };
                            let Some(rhs) =
                                self.register_place_and_discr(tcx, body,
                                    *rhs) else { continue; };
                            assignments.insert((lhs, rhs));
                        }
                        Rvalue::Aggregate(kind, fields) => {
                            let Some(mut lhs) =
                                self.register_place_and_discr(tcx, body,
                                    *lhs) else { continue; };
                            match **kind {
                                AggregateKind::Adt(_, _, _, _, Some(_)) => continue,
                                AggregateKind::Adt(_, variant, _, _, None) => {
                                    let ty = self.places[lhs].ty;
                                    if ty.is_enum() {
                                        lhs =
                                            self.register_place_index(ty, lhs,
                                                TrackElem::Variant(variant));
                                    }
                                }
                                AggregateKind::RawPtr(..) | AggregateKind::Array(_) |
                                    AggregateKind::Tuple | AggregateKind::Closure(..) |
                                    AggregateKind::Coroutine(..) |
                                    AggregateKind::CoroutineClosure(..) => {}
                            }
                            for (index, field) in fields.iter_enumerated() {
                                if let Some(rhs) = field.place() &&
                                        let Some(rhs) =
                                            self.register_place_and_discr(tcx, body, rhs) {
                                    let lhs =
                                        self.register_place_index(self.places[rhs].ty, lhs,
                                            TrackElem::Field(index));
                                    assignments.insert((lhs, rhs));
                                }
                            }
                        }
                        _ => {}
                    }
                }
            }
            let mut num_places = 0;
            while num_places < self.places.len() {
                num_places = self.places.len();
                for assign in 0.. {
                    let Some(&(lhs, rhs)) =
                        assignments.get_index(assign) else { break };
                    let mut child = self.places[lhs].first_child;
                    while let Some(lhs_child) = child {
                        let PlaceInfo { ty, proj_elem, next_sibling, .. } =
                            self.places[lhs_child];
                        let rhs_child =
                            self.register_place_index(ty, rhs,
                                proj_elem.expect("child is not a projection"));
                        assignments.insert((lhs_child, rhs_child));
                        child = next_sibling;
                    }
                    let mut child = self.places[rhs].first_child;
                    while let Some(rhs_child) = child {
                        let PlaceInfo { ty, proj_elem, next_sibling, .. } =
                            self.places[rhs_child];
                        let lhs_child =
                            self.register_place_index(ty, lhs,
                                proj_elem.expect("child is not a projection"));
                        assignments.insert((lhs_child, rhs_child));
                        child = next_sibling;
                    }
                }
            }
        }
    }
}#[tracing::instrument(level = "trace", skip(self, tcx, body))]
393    fn propagate_assignments(&mut self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
394        // Collect syntactic places and assignments between them.
395        let mut assignments = FxIndexSet::default();
396
397        for bbdata in body.basic_blocks.iter() {
398            for stmt in bbdata.statements.iter() {
399                let Some((lhs, rhs)) = stmt.kind.as_assign() else { continue };
400                match rhs {
401                    Rvalue::Use(Operand::Move(rhs) | Operand::Copy(rhs), _)
402                    | Rvalue::CopyForDeref(rhs) => {
403                        let Some(lhs) = self.register_place_and_discr(tcx, body, *lhs) else {
404                            continue;
405                        };
406                        let Some(rhs) = self.register_place_and_discr(tcx, body, *rhs) else {
407                            continue;
408                        };
409                        assignments.insert((lhs, rhs));
410                    }
411                    Rvalue::Aggregate(kind, fields) => {
412                        let Some(mut lhs) = self.register_place_and_discr(tcx, body, *lhs) else {
413                            continue;
414                        };
415                        match **kind {
416                            // Do not propagate unions.
417                            AggregateKind::Adt(_, _, _, _, Some(_)) => continue,
418                            AggregateKind::Adt(_, variant, _, _, None) => {
419                                let ty = self.places[lhs].ty;
420                                if ty.is_enum() {
421                                    lhs = self.register_place_index(
422                                        ty,
423                                        lhs,
424                                        TrackElem::Variant(variant),
425                                    );
426                                }
427                            }
428                            AggregateKind::RawPtr(..)
429                            | AggregateKind::Array(_)
430                            | AggregateKind::Tuple
431                            | AggregateKind::Closure(..)
432                            | AggregateKind::Coroutine(..)
433                            | AggregateKind::CoroutineClosure(..) => {}
434                        }
435                        for (index, field) in fields.iter_enumerated() {
436                            if let Some(rhs) = field.place()
437                                && let Some(rhs) = self.register_place_and_discr(tcx, body, rhs)
438                            {
439                                let lhs = self.register_place_index(
440                                    self.places[rhs].ty,
441                                    lhs,
442                                    TrackElem::Field(index),
443                                );
444                                assignments.insert((lhs, rhs));
445                            }
446                        }
447                    }
448                    _ => {}
449                }
450            }
451        }
452
453        // This is a fixpoint loop does. While we are still creating places, run through
454        // all the assignments, and register places for children.
455        let mut num_places = 0;
456        while num_places < self.places.len() {
457            num_places = self.places.len();
458
459            for assign in 0.. {
460                let Some(&(lhs, rhs)) = assignments.get_index(assign) else { break };
461
462                // Mirror children from `lhs` in `rhs`.
463                let mut child = self.places[lhs].first_child;
464                while let Some(lhs_child) = child {
465                    let PlaceInfo { ty, proj_elem, next_sibling, .. } = self.places[lhs_child];
466                    let rhs_child = self.register_place_index(
467                        ty,
468                        rhs,
469                        proj_elem.expect("child is not a projection"),
470                    );
471                    assignments.insert((lhs_child, rhs_child));
472                    child = next_sibling;
473                }
474
475                // Conversely, mirror children from `rhs` in `lhs`.
476                let mut child = self.places[rhs].first_child;
477                while let Some(rhs_child) = child {
478                    let PlaceInfo { ty, proj_elem, next_sibling, .. } = self.places[rhs_child];
479                    let lhs_child = self.register_place_index(
480                        ty,
481                        lhs,
482                        proj_elem.expect("child is not a projection"),
483                    );
484                    assignments.insert((lhs_child, rhs_child));
485                    child = next_sibling;
486                }
487            }
488        }
489    }
490
491    /// Create values for places whose type have scalar layout.
492    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("create_values",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(492u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("value_limit")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("value_limit");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&value_limit)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if true {
                {
                    match self.mode {
                        PlaceCollectionMode::Full { .. } => {}
                        ref left_val => {
                            ::core::panicking::assert_matches_failed(left_val,
                                "PlaceCollectionMode::Full { .. }",
                                ::core::option::Option::None);
                        }
                    }
                };
            };
            let typing_env = body.typing_env(tcx);
            for place_info in self.places.iter_mut() {
                if let Some(value_limit) = value_limit &&
                        self.value_count >= value_limit {
                    break;
                }
                if let Ok(ty) =
                        tcx.try_normalize_erasing_regions(typing_env,
                            Unnormalized::new_wip(place_info.ty)) {
                    place_info.ty = ty;
                }
                if !place_info.value_index.is_none() {
                    ::core::panicking::panic("assertion failed: place_info.value_index.is_none()")
                };
                if let Ok(layout) =
                            tcx.layout_of(typing_env.as_query_input(place_info.ty)) &&
                        layout.backend_repr.is_scalar() {
                    place_info.value_index = Some(self.value_count.into());
                    self.value_count += 1;
                }
            }
            self.inner_values_buffer = Vec::with_capacity(self.value_count);
            self.inner_values = IndexVec::from_elem(0..0, &self.places);
            for local in body.local_decls.indices() {
                if let Some(place) = self.locals[local] {
                    self.cache_preorder_invoke(place);
                }
            }
        }
    }
}#[tracing::instrument(level = "trace", skip(self, tcx, body))]
493    fn create_values(&mut self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>, value_limit: Option<usize>) {
494        debug_assert_matches!(self.mode, PlaceCollectionMode::Full { .. });
495        let typing_env = body.typing_env(tcx);
496        for place_info in self.places.iter_mut() {
497            // The user requires a bound on the number of created values.
498            if let Some(value_limit) = value_limit
499                && self.value_count >= value_limit
500            {
501                break;
502            }
503
504            if let Ok(ty) =
505                tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(place_info.ty))
506            {
507                place_info.ty = ty;
508            }
509
510            // Allocate a value slot if it doesn't have one, and the user requested one.
511            assert!(place_info.value_index.is_none());
512            if let Ok(layout) = tcx.layout_of(typing_env.as_query_input(place_info.ty))
513                && layout.backend_repr.is_scalar()
514            {
515                place_info.value_index = Some(self.value_count.into());
516                self.value_count += 1;
517            }
518        }
519
520        // Pre-compute the tree of ValueIndex nested in each PlaceIndex.
521        // `inner_values_buffer[inner_values[place]]` is the set of all the values
522        // reachable by projecting `place`.
523        self.inner_values_buffer = Vec::with_capacity(self.value_count);
524        self.inner_values = IndexVec::from_elem(0..0, &self.places);
525        for local in body.local_decls.indices() {
526            if let Some(place) = self.locals[local] {
527                self.cache_preorder_invoke(place);
528            }
529        }
530    }
531
532    /// Trim useless places.
533    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("trim_useless_places",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(533u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{ meta.fields().value_set_all(&[]) })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if true {
                {
                    match self.mode {
                        PlaceCollectionMode::Full { .. } => {}
                        ref left_val => {
                            ::core::panicking::assert_matches_failed(left_val,
                                "PlaceCollectionMode::Full { .. }",
                                ::core::option::Option::None);
                        }
                    }
                };
            };
            for opt_place in self.locals.iter_mut() {
                if let Some(place) = *opt_place &&
                        self.inner_values[place].is_empty() {
                    *opt_place = None;
                }
            }

            #[allow(rustc::potential_query_instability)]
            self.projections.retain(|_, child|
                    !self.inner_values[*child].is_empty());
        }
    }
}#[tracing::instrument(level = "trace", skip(self))]
534    fn trim_useless_places(&mut self) {
535        debug_assert_matches!(self.mode, PlaceCollectionMode::Full { .. });
536        for opt_place in self.locals.iter_mut() {
537            if let Some(place) = *opt_place
538                && self.inner_values[place].is_empty()
539            {
540                *opt_place = None;
541            }
542        }
543        #[allow(rustc::potential_query_instability)]
544        self.projections.retain(|_, child| !self.inner_values[*child].is_empty());
545    }
546
547    {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
            ::tracing::Level::TRACE <=
                ::tracing::level_filters::LevelFilter::current() || { false }
    {
    __tracing_attr_span =
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("register_place_index",
                                "rustc_mir_dataflow::value_analysis",
                                ::tracing::Level::TRACE,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                ::tracing_core::__macro_support::Option::Some(547u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("ty")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("ty");
                                                    NAME.as_str()
                                                },
                                                {
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("base")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("base");
                                                    NAME.as_str()
                                                },
                                                {
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("elem")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("elem");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::SPAN)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let mut interest = ::tracing::subscriber::Interest::never();
            if ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        { interest = __CALLSITE.interest(); !interest.is_never() }
                    &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest) {
                let meta = __CALLSITE.metadata();
                ::tracing::Span::new(meta,
                    &{
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
                                                        as &dyn ::tracing::field::Value)),
                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&base)
                                                        as &dyn ::tracing::field::Value)),
                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&elem)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return: PlaceIndex = loop {};
                        return __tracing_attr_fake_return;
                    }
                    {
                        *self.projections.entry((base,
                                        elem)).or_insert_with(||
                                    {
                                        let next = self.places.push(PlaceInfo::new(ty, Some(elem)));
                                        self.places[next].next_sibling =
                                            self.places[base].first_child;
                                        self.places[base].first_child = Some(next);
                                        next
                                    })
                    }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs:547",
                        "rustc_mir_dataflow::value_analysis",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                        ::tracing_core::__macro_support::Option::Some(547u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[tracing::instrument(level = "trace", skip(self), ret)]
548    pub fn register_place_index(
549        &mut self,
550        ty: Ty<'tcx>,
551        base: PlaceIndex,
552        elem: TrackElem,
553    ) -> PlaceIndex {
554        *self.projections.entry((base, elem)).or_insert_with(|| {
555            let next = self.places.push(PlaceInfo::new(ty, Some(elem)));
556            self.places[next].next_sibling = self.places[base].first_child;
557            self.places[base].first_child = Some(next);
558            next
559        })
560    }
561
562    {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
            ::tracing::Level::TRACE <=
                ::tracing::level_filters::LevelFilter::current() || { false }
    {
    __tracing_attr_span =
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("register_place",
                                "rustc_mir_dataflow::value_analysis",
                                ::tracing::Level::TRACE,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                ::tracing_core::__macro_support::Option::Some(562u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("place")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("place");
                                                    NAME.as_str()
                                                },
                                                {
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("tail")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("tail");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::SPAN)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let mut interest = ::tracing::subscriber::Interest::never();
            if ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        { interest = __CALLSITE.interest(); !interest.is_never() }
                    &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest) {
                let meta = __CALLSITE.metadata();
                ::tracing::Span::new(meta,
                    &{
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
                                                        as &dyn ::tracing::field::Value)),
                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&tail)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return: Option<PlaceIndex> =
                            loop {};
                        return __tracing_attr_fake_return;
                    }
                    {
                        let mut place_index = self.locals[place.local]?;
                        let mut ty =
                            PlaceTy::from_ty(body.local_decls[place.local].ty);
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event /rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs:573",
                                                "rustc_mir_dataflow::value_analysis",
                                                ::tracing::Level::TRACE,
                                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                                ::tracing_core::__macro_support::Option::Some(573u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                                ::tracing_core::field::FieldSet::new(&[{
                                                                    const NAME:
                                                                        ::tracing::__macro_support::FieldName<{
                                                                            ::tracing::__macro_support::FieldName::len("place_index")
                                                                        }> =
                                                                        ::tracing::__macro_support::FieldName::new("place_index");
                                                                    NAME.as_str()
                                                                },
                                                                {
                                                                    const NAME:
                                                                        ::tracing::__macro_support::FieldName<{
                                                                            ::tracing::__macro_support::FieldName::len("ty")
                                                                        }> =
                                                                        ::tracing::__macro_support::FieldName::new("ty");
                                                                    NAME.as_str()
                                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                ::tracing::metadata::Kind::EVENT)
                                        };
                                    ::tracing::callsite::DefaultCallsite::new(&META)
                                };
                            let enabled =
                                ::tracing::Level::TRACE <=
                                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                        ::tracing::Level::TRACE <=
                                            ::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};
                                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place_index)
                                                                    as &dyn ::tracing::field::Value)),
                                                        (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
                                                                    as &dyn ::tracing::field::Value))])
                                    });
                            } else { ; }
                        };
                        for proj in place.projection {
                            let track_elem = proj.try_into().ok()?;
                            ty = ty.projection_ty(tcx, proj);
                            place_index =
                                self.register_place_index(ty.ty, place_index, track_elem);
                            {
                                use ::tracing::__macro_support::Callsite as _;
                                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                    {
                                        static META: ::tracing::Metadata<'static> =
                                            {
                                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs:579",
                                                    "rustc_mir_dataflow::value_analysis",
                                                    ::tracing::Level::TRACE,
                                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                                    ::tracing_core::__macro_support::Option::Some(579u32),
                                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                                    ::tracing_core::field::FieldSet::new(&[{
                                                                        const NAME:
                                                                            ::tracing::__macro_support::FieldName<{
                                                                                ::tracing::__macro_support::FieldName::len("proj")
                                                                            }> =
                                                                            ::tracing::__macro_support::FieldName::new("proj");
                                                                        NAME.as_str()
                                                                    },
                                                                    {
                                                                        const NAME:
                                                                            ::tracing::__macro_support::FieldName<{
                                                                                ::tracing::__macro_support::FieldName::len("place_index")
                                                                            }> =
                                                                            ::tracing::__macro_support::FieldName::new("place_index");
                                                                        NAME.as_str()
                                                                    },
                                                                    {
                                                                        const NAME:
                                                                            ::tracing::__macro_support::FieldName<{
                                                                                ::tracing::__macro_support::FieldName::len("ty")
                                                                            }> =
                                                                            ::tracing::__macro_support::FieldName::new("ty");
                                                                        NAME.as_str()
                                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                    ::tracing::metadata::Kind::EVENT)
                                            };
                                        ::tracing::callsite::DefaultCallsite::new(&META)
                                    };
                                let enabled =
                                    ::tracing::Level::TRACE <=
                                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                            ::tracing::Level::TRACE <=
                                                ::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};
                                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&proj)
                                                                        as &dyn ::tracing::field::Value)),
                                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place_index)
                                                                        as &dyn ::tracing::field::Value)),
                                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
                                                                        as &dyn ::tracing::field::Value))])
                                        });
                                } else { ; }
                            };
                        }
                        if let Some(tail) = tail {
                            let ty =
                                match tail {
                                    TrackElem::Discriminant => ty.ty.discriminant_ty(tcx),
                                    TrackElem::Variant(..) | TrackElem::Field(..) =>
                                        ::core::panicking::panic("not implemented"),
                                    TrackElem::DerefLen => tcx.types.usize,
                                };
                            place_index =
                                self.register_place_index(ty, place_index, tail);
                        }
                        Some(place_index)
                    }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs:562",
                        "rustc_mir_dataflow::value_analysis",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                        ::tracing_core::__macro_support::Option::Some(562u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[tracing::instrument(level = "trace", skip(self, tcx, body), ret)]
563    pub fn register_place(
564        &mut self,
565        tcx: TyCtxt<'tcx>,
566        body: &Body<'tcx>,
567        place: Place<'tcx>,
568        tail: Option<TrackElem>,
569    ) -> Option<PlaceIndex> {
570        // Create a place for this projection.
571        let mut place_index = self.locals[place.local]?;
572        let mut ty = PlaceTy::from_ty(body.local_decls[place.local].ty);
573        tracing::trace!(?place_index, ?ty);
574
575        for proj in place.projection {
576            let track_elem = proj.try_into().ok()?;
577            ty = ty.projection_ty(tcx, proj);
578            place_index = self.register_place_index(ty.ty, place_index, track_elem);
579            tracing::trace!(?proj, ?place_index, ?ty);
580        }
581
582        if let Some(tail) = tail {
583            let ty = match tail {
584                TrackElem::Discriminant => ty.ty.discriminant_ty(tcx),
585                TrackElem::Variant(..) | TrackElem::Field(..) => unimplemented!(),
586                TrackElem::DerefLen => tcx.types.usize,
587            };
588            place_index = self.register_place_index(ty, place_index, tail);
589        }
590
591        Some(place_index)
592    }
593
594    {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
            ::tracing::Level::TRACE <=
                ::tracing::level_filters::LevelFilter::current() || { false }
    {
    __tracing_attr_span =
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("register_place_and_discr",
                                "rustc_mir_dataflow::value_analysis",
                                ::tracing::Level::TRACE,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                ::tracing_core::__macro_support::Option::Some(594u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("place")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("place");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::SPAN)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let mut interest = ::tracing::subscriber::Interest::never();
            if ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        { interest = __CALLSITE.interest(); !interest.is_never() }
                    &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest) {
                let meta = __CALLSITE.metadata();
                ::tracing::Span::new(meta,
                    &{
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return: Option<PlaceIndex> =
                            loop {};
                        return __tracing_attr_fake_return;
                    }
                    {
                        let place = self.register_place(tcx, body, place, None)?;
                        let ty = self.places[place].ty;
                        if let ty::Ref(_, ref_ty, _) | ty::RawPtr(ref_ty, _) =
                                    ty.kind() && let ty::Slice(..) = ref_ty.kind() {
                            self.register_place_index(tcx.types.usize, place,
                                TrackElem::DerefLen);
                        } else if ty.is_enum() {
                            let discriminant_ty = ty.discriminant_ty(tcx);
                            self.register_place_index(discriminant_ty, place,
                                TrackElem::Discriminant);
                        }
                        Some(place)
                    }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs:594",
                        "rustc_mir_dataflow::value_analysis",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                        ::tracing_core::__macro_support::Option::Some(594u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[tracing::instrument(level = "trace", skip(self, tcx, body), ret)]
595    fn register_place_and_discr(
596        &mut self,
597        tcx: TyCtxt<'tcx>,
598        body: &Body<'tcx>,
599        place: Place<'tcx>,
600    ) -> Option<PlaceIndex> {
601        let place = self.register_place(tcx, body, place, None)?;
602        let ty = self.places[place].ty;
603
604        if let ty::Ref(_, ref_ty, _) | ty::RawPtr(ref_ty, _) = ty.kind()
605            && let ty::Slice(..) = ref_ty.kind()
606        {
607            self.register_place_index(tcx.types.usize, place, TrackElem::DerefLen);
608        } else if ty.is_enum() {
609            let discriminant_ty = ty.discriminant_ty(tcx);
610            self.register_place_index(discriminant_ty, place, TrackElem::Discriminant);
611        }
612
613        Some(place)
614    }
615
616    {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
            ::tracing::Level::TRACE <=
                ::tracing::level_filters::LevelFilter::current() || { false }
    {
    __tracing_attr_span =
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("register_value",
                                "rustc_mir_dataflow::value_analysis",
                                ::tracing::Level::TRACE,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                ::tracing_core::__macro_support::Option::Some(616u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("place")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("place");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::SPAN)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let mut interest = ::tracing::subscriber::Interest::never();
            if ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        { interest = __CALLSITE.interest(); !interest.is_never() }
                    &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest) {
                let meta = __CALLSITE.metadata();
                ::tracing::Span::new(meta,
                    &{
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return: Option<ValueIndex> =
                            loop {};
                        return __tracing_attr_fake_return;
                    }
                    {
                        let place_info = &mut self.places[place];
                        if let Some(value) = place_info.value_index {
                            return Some(value);
                        }
                        if let Ok(ty) =
                                tcx.try_normalize_erasing_regions(typing_env,
                                    Unnormalized::new_wip(place_info.ty)) {
                            place_info.ty = ty;
                        }
                        if let Ok(layout) =
                                    tcx.layout_of(typing_env.as_query_input(place_info.ty)) &&
                                layout.backend_repr.is_scalar() {
                            place_info.value_index = Some(self.value_count.into());
                            self.value_count += 1;
                        }
                        place_info.value_index
                    }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs:616",
                        "rustc_mir_dataflow::value_analysis",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                        ::tracing_core::__macro_support::Option::Some(616u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[tracing::instrument(level = "trace", skip(self, tcx, typing_env), ret)]
617    pub fn register_value(
618        &mut self,
619        tcx: TyCtxt<'tcx>,
620        typing_env: ty::TypingEnv<'tcx>,
621        place: PlaceIndex,
622    ) -> Option<ValueIndex> {
623        let place_info = &mut self.places[place];
624        if let Some(value) = place_info.value_index {
625            return Some(value);
626        }
627
628        if let Ok(ty) =
629            tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(place_info.ty))
630        {
631            place_info.ty = ty;
632        }
633
634        // Allocate a value slot if it doesn't have one, and the user requested one.
635        if let Ok(layout) = tcx.layout_of(typing_env.as_query_input(place_info.ty))
636            && layout.backend_repr.is_scalar()
637        {
638            place_info.value_index = Some(self.value_count.into());
639            self.value_count += 1;
640        }
641
642        place_info.value_index
643    }
644
645    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("register_copy_tree",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(645u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("source")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("source");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("target")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("target");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&source)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&target)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if let Some(source_value) = self.places[source].value_index {
                let target_value =
                    *self.places[target].value_index.get_or_insert_with(||
                                {
                                    let value_index = self.value_count.into();
                                    self.value_count += 1;
                                    value_index
                                });
                f(source_value, target_value)
            }
            let mut source_child_iter = self.places[source].first_child;
            while let Some(source_child) = source_child_iter {
                source_child_iter = self.places[source_child].next_sibling;
                let source_info = &self.places[source_child];
                let source_ty = source_info.ty;
                let source_elem = source_info.proj_elem.unwrap();
                let target_child =
                    self.register_place_index(source_ty, target, source_elem);
                self.register_copy_tree(source_child, target_child, f);
            }
        }
    }
}#[tracing::instrument(level = "trace", skip(self, f))]
646    pub fn register_copy_tree(
647        &mut self,
648        // Tree to copy.
649        source: PlaceIndex,
650        // Tree to build.
651        target: PlaceIndex,
652        f: &mut impl FnMut(ValueIndex, ValueIndex),
653    ) {
654        if let Some(source_value) = self.places[source].value_index {
655            let target_value = *self.places[target].value_index.get_or_insert_with(|| {
656                let value_index = self.value_count.into();
657                self.value_count += 1;
658                value_index
659            });
660            f(source_value, target_value)
661        }
662
663        // Iterate over `source` children and recurse.
664        let mut source_child_iter = self.places[source].first_child;
665        while let Some(source_child) = source_child_iter {
666            source_child_iter = self.places[source_child].next_sibling;
667
668            // Try to find corresponding child and recurse. Reasoning is similar as above.
669            let source_info = &self.places[source_child];
670            let source_ty = source_info.ty;
671            let source_elem = source_info.proj_elem.unwrap();
672            let target_child = self.register_place_index(source_ty, target, source_elem);
673            self.register_copy_tree(source_child, target_child, f);
674        }
675    }
676
677    /// Precompute the list of values inside `root` and store it inside
678    /// as a slice within `inner_values_buffer`.
679    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("cache_preorder_invoke",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(679u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("root")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("root");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&root)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if true {
                {
                    match self.mode {
                        PlaceCollectionMode::Full { .. } => {}
                        ref left_val => {
                            ::core::panicking::assert_matches_failed(left_val,
                                "PlaceCollectionMode::Full { .. }",
                                ::core::option::Option::None);
                        }
                    }
                };
            };
            let start = self.inner_values_buffer.len();
            if let Some(vi) = self.places[root].value_index {
                self.inner_values_buffer.push(vi);
            }
            let mut next_child = self.places[root].first_child;
            while let Some(child) = next_child {
                self.cache_preorder_invoke(child);
                next_child = self.places[child].next_sibling;
            }
            let end = self.inner_values_buffer.len();
            self.inner_values[root] = start..end;
        }
    }
}#[tracing::instrument(level = "trace", skip(self))]
680    fn cache_preorder_invoke(&mut self, root: PlaceIndex) {
681        debug_assert_matches!(self.mode, PlaceCollectionMode::Full { .. });
682        let start = self.inner_values_buffer.len();
683        if let Some(vi) = self.places[root].value_index {
684            self.inner_values_buffer.push(vi);
685        }
686
687        // We manually iterate instead of using `children` as we need to mutate `self`.
688        let mut next_child = self.places[root].first_child;
689        while let Some(child) = next_child {
690            self.cache_preorder_invoke(child);
691            next_child = self.places[child].next_sibling;
692        }
693
694        let end = self.inner_values_buffer.len();
695        self.inner_values[root] = start..end;
696    }
697}
698
699struct PlaceCollector<'a, 'tcx> {
700    tcx: TyCtxt<'tcx>,
701    body: &'a Body<'tcx>,
702    map: &'a mut Map<'tcx>,
703}
704
705impl<'tcx> Visitor<'tcx> for PlaceCollector<'_, 'tcx> {
706    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("visit_place",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(706u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("place")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("place");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("ctxt")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("ctxt");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ctxt)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if !ctxt.is_use() { return; }
            self.map.register_place_and_discr(self.tcx, self.body, *place);
        }
    }
}#[tracing::instrument(level = "trace", skip(self))]
707    fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, _: Location) {
708        if !ctxt.is_use() {
709            return;
710        }
711
712        self.map.register_place_and_discr(self.tcx, self.body, *place);
713    }
714}
715
716impl<'tcx> Map<'tcx> {
717    /// Applies a single projection element, yielding the corresponding child.
718    pub fn apply(&self, place: PlaceIndex, elem: TrackElem) -> Option<PlaceIndex> {
719        self.projections.get(&(place, elem)).copied()
720    }
721
722    /// Locates the given place, if it exists in the tree.
723    fn find_extra(
724        &self,
725        place: PlaceRef<'_>,
726        extra: impl IntoIterator<Item = TrackElem>,
727    ) -> Option<PlaceIndex> {
728        let mut index = *self.locals[place.local].as_ref()?;
729
730        for &elem in place.projection {
731            index = self.apply(index, elem.try_into().ok()?)?;
732        }
733        for elem in extra {
734            index = self.apply(index, elem)?;
735        }
736
737        Some(index)
738    }
739
740    /// Locates the given place, if it exists in the tree.
741    pub fn find(&self, place: PlaceRef<'_>) -> Option<PlaceIndex> {
742        self.find_extra(place, [])
743    }
744
745    /// Locates the given place and applies `Discriminant`, if it exists in the tree.
746    pub fn find_discr(&self, place: PlaceRef<'_>) -> Option<PlaceIndex> {
747        self.find_extra(place, [TrackElem::Discriminant])
748    }
749
750    /// Locates the given place and applies `DerefLen`, if it exists in the tree.
751    pub fn find_len(&self, place: PlaceRef<'_>) -> Option<PlaceIndex> {
752        self.find_extra(place, [TrackElem::DerefLen])
753    }
754
755    /// Locates the value corresponding to the given place.
756    pub fn value(&self, place: PlaceIndex) -> Option<ValueIndex> {
757        self.places[place].value_index
758    }
759
760    /// Iterate over all direct children.
761    fn children(&self, parent: PlaceIndex) -> impl Iterator<Item = PlaceIndex> {
762        Children::new(self, parent)
763    }
764
765    /// Invoke a function on the given place and all places that may alias it.
766    ///
767    /// In particular, when the given place has a variant downcast, we invoke the function on all
768    /// the other variants.
769    ///
770    /// `tail_elem` allows to support discriminants that are not a place in MIR, but that we track
771    /// as such.
772    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("for_each_aliasing_place",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(772u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("place")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("place");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("tail_elem")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("tail_elem");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&tail_elem)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if place.is_indirect_first_projection() { return; }
            let Some(mut index) = self.locals[place.local] else { return; };
            let elems =
                place.projection.iter().map(|&elem|
                            elem.try_into()).chain(tail_elem.map(Ok));
            for elem in elems {
                if self.places[index].ty.is_union() {
                    self.for_each_value_inside(index, f);
                    return;
                }
                if let Some(vi) = self.places[index].value_index { f(vi); }
                let Ok(elem) = elem else { return };
                let sub = self.apply(index, elem);
                if let TrackElem::Variant(..) | TrackElem::Discriminant = elem
                    {
                    self.for_each_variant_sibling(index, sub, f);
                }
                let Some(sub) = sub else { return };
                index = sub;
            }
            self.for_each_value_inside(index, f);
        }
    }
}#[tracing::instrument(level = "trace", skip(self, f))]
773    pub fn for_each_aliasing_place(
774        &self,
775        place: PlaceRef<'_>,
776        tail_elem: Option<TrackElem>,
777        f: &mut impl FnMut(ValueIndex),
778    ) {
779        if place.is_indirect_first_projection() {
780            // We do not track indirect places.
781            return;
782        }
783        let Some(mut index) = self.locals[place.local] else {
784            // The local is not tracked at all, so it does not alias anything.
785            return;
786        };
787        let elems = place.projection.iter().map(|&elem| elem.try_into()).chain(tail_elem.map(Ok));
788        for elem in elems {
789            // All fields of a union alias each other.
790            if self.places[index].ty.is_union() {
791                self.for_each_value_inside(index, f);
792                return;
793            }
794
795            // A field aliases the parent place.
796            if let Some(vi) = self.places[index].value_index {
797                f(vi);
798            }
799
800            let Ok(elem) = elem else { return };
801            let sub = self.apply(index, elem);
802            if let TrackElem::Variant(..) | TrackElem::Discriminant = elem {
803                // Enum variant fields and enum discriminants alias each another.
804                self.for_each_variant_sibling(index, sub, f);
805            }
806            let Some(sub) = sub else { return };
807            index = sub;
808        }
809        self.for_each_value_inside(index, f);
810    }
811
812    /// Invoke the given function on all the descendants of the given place, except one branch.
813    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("for_each_variant_sibling",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(813u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("parent")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("parent");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("preserved_child")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("preserved_child");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&parent)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&preserved_child)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            for sibling in self.children(parent) {
                let elem = self.places[sibling].proj_elem;
                if let Some(TrackElem::Variant(..) | TrackElem::Discriminant)
                            = elem && Some(sibling) != preserved_child {
                    self.for_each_value_inside(sibling, f);
                }
            }
        }
    }
}#[tracing::instrument(level = "trace", skip(self, f))]
814    fn for_each_variant_sibling(
815        &self,
816        parent: PlaceIndex,
817        preserved_child: Option<PlaceIndex>,
818        f: &mut impl FnMut(ValueIndex),
819    ) {
820        for sibling in self.children(parent) {
821            let elem = self.places[sibling].proj_elem;
822            // Only invalidate variants and discriminant. Fields (for coroutines) are not
823            // invalidated by assignment to a variant.
824            if let Some(TrackElem::Variant(..) | TrackElem::Discriminant) = elem
825                // Only invalidate the other variants, the current one is fine.
826                && Some(sibling) != preserved_child
827            {
828                self.for_each_value_inside(sibling, f);
829            }
830        }
831    }
832
833    /// Invoke a function on each value in the given place and all descendants.
834    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("for_each_value_inside",
                                    "rustc_mir_dataflow::value_analysis",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/5d8fec0669a64607db9ccbf663e7c23125bf4748/compiler/rustc_mir_dataflow/src/value_analysis.rs"),
                                    ::tracing_core::__macro_support::Option::Some(834u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::value_analysis"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("root")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("root");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&root)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if let Some(range) = self.inner_values.get(root) {
                let values = &self.inner_values_buffer[range.clone()];
                for &v in values { f(v) }
            } else {
                if let Some(root) = self.places[root].value_index { f(root) }
                for child in self.children(root) {
                    self.for_each_value_inside(child, f);
                }
            }
        }
    }
}#[tracing::instrument(level = "trace", skip(self, f))]
835    fn for_each_value_inside(&self, root: PlaceIndex, f: &mut impl FnMut(ValueIndex)) {
836        if let Some(range) = self.inner_values.get(root) {
837            // Optimized path: we have cached the inner values.
838            let values = &self.inner_values_buffer[range.clone()];
839            for &v in values {
840                f(v)
841            }
842        } else {
843            if let Some(root) = self.places[root].value_index {
844                f(root)
845            }
846
847            for child in self.children(root) {
848                self.for_each_value_inside(child, f);
849            }
850        }
851    }
852
853    /// Invoke a function on each value in the given place and all descendants.
854    pub fn for_each_projection_value<O>(
855        &self,
856        root: PlaceIndex,
857        value: O,
858        project: &mut impl FnMut(TrackElem, &O) -> Option<O>,
859        f: &mut impl FnMut(PlaceIndex, &O),
860    ) {
861        // Fast path is there is nothing to do.
862        if let Some(value_range) = self.inner_values.get(root)
863            && value_range.is_empty()
864        {
865            return;
866        }
867
868        if self.places[root].value_index.is_some() {
869            f(root, &value)
870        }
871
872        for child in self.children(root) {
873            let elem = self.places[child].proj_elem.unwrap();
874            if let Some(value) = project(elem, &value) {
875                self.for_each_projection_value(child, value, project, f);
876            }
877        }
878    }
879
880    /// Recursively iterates on each value contained in `target`, paired with matching projection
881    /// inside `source`.
882    fn for_each_value_pair(
883        &self,
884        target: PlaceIndex,
885        source: PlaceIndex,
886        f: &mut impl FnMut(ValueIndex, ValueIndex),
887    ) {
888        // If both places are tracked, we copy the value to the target.
889        // If the target is tracked, but the source is not, we do nothing, as invalidation has
890        // already been performed.
891        if let Some(target_value) = self.places[target].value_index
892            && let Some(source_value) = self.places[source].value_index
893        {
894            f(target_value, source_value)
895        }
896        for target_child in self.children(target) {
897            // Try to find corresponding child and recurse. Reasoning is similar as above.
898            let projection = self.places[target_child].proj_elem.unwrap();
899            if let Some(source_child) = self.projections.get(&(source, projection)) {
900                self.for_each_value_pair(target_child, *source_child, f);
901            }
902        }
903    }
904}
905
906/// This is the information tracked for every [`PlaceIndex`] and is stored by [`Map`].
907///
908/// Together, `first_child` and `next_sibling` form an intrusive linked list, which is used to
909/// model a tree structure (a replacement for a member like `children: Vec<PlaceIndex>`).
910#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for PlaceInfo<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f, "PlaceInfo",
            "ty", &self.ty, "value_index", &self.value_index, "proj_elem",
            &self.proj_elem, "first_child", &self.first_child, "next_sibling",
            &&self.next_sibling)
    }
}Debug)]
911struct PlaceInfo<'tcx> {
912    /// Type of the referenced place.
913    ty: Ty<'tcx>,
914
915    /// We store a [`ValueIndex`] if and only if the placed is tracked by the analysis.
916    value_index: Option<ValueIndex>,
917
918    /// The projection used to go from parent to this node (only None for root).
919    proj_elem: Option<TrackElem>,
920
921    /// The leftmost child.
922    first_child: Option<PlaceIndex>,
923
924    /// Index of the sibling to the right of this node.
925    next_sibling: Option<PlaceIndex>,
926}
927
928impl<'tcx> PlaceInfo<'tcx> {
929    fn new(ty: Ty<'tcx>, proj_elem: Option<TrackElem>) -> Self {
930        Self { ty, next_sibling: None, first_child: None, proj_elem, value_index: None }
931    }
932}
933
934struct Children<'a, 'tcx> {
935    map: &'a Map<'tcx>,
936    next: Option<PlaceIndex>,
937}
938
939impl<'a, 'tcx> Children<'a, 'tcx> {
940    fn new(map: &'a Map<'tcx>, parent: PlaceIndex) -> Self {
941        Self { map, next: map.places[parent].first_child }
942    }
943}
944
945impl Iterator for Children<'_, '_> {
946    type Item = PlaceIndex;
947
948    fn next(&mut self) -> Option<Self::Item> {
949        match self.next {
950            Some(child) => {
951                self.next = self.map.places[child].next_sibling;
952                Some(child)
953            }
954            None => None,
955        }
956    }
957}
958
959/// Used as the result of an operand or r-value.
960#[derive(#[automatically_derived]
impl<V: ::core::fmt::Debug> ::core::fmt::Debug for ValueOrPlace<V> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Value(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Value",
                    &__self_0),
            Self::Place(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Place",
                    &__self_0),
        }
    }
}Debug)]
961pub enum ValueOrPlace<V> {
962    Value(V),
963    Place(PlaceIndex),
964}
965
966impl<V: HasTop> ValueOrPlace<V> {
967    pub const TOP: Self = ValueOrPlace::Value(V::TOP);
968}
969
970/// The set of projection elements that can be used by a tracked place.
971///
972/// Although only field projections are currently allowed, this could change in the future.
973#[derive(#[automatically_derived]
impl ::core::marker::Copy for TrackElem { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for TrackElem { }
#[automatically_derived]
impl ::core::clone::Clone for TrackElem {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<FieldIdx>;
        let _: ::core::clone::AssertParamIsClone<VariantIdx>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for TrackElem {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Field(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Field",
                    &__self_0),
            Self::Variant(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Variant", &__self_0),
            Self::Discriminant =>
                ::core::fmt::Formatter::write_str(f, "Discriminant"),
            Self::DerefLen =>
                ::core::fmt::Formatter::write_str(f, "DerefLen"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for TrackElem { }
#[automatically_derived]
impl ::core::cmp::PartialEq for TrackElem {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::Field(__self_0), Self::Field(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Variant(__self_0), Self::Variant(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for TrackElem {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<FieldIdx>;
        let _: ::core::cmp::AssertParamIsEq<VariantIdx>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for TrackElem {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
            state);
        match self {
            Self::Field(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            Self::Variant(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash)]
974pub enum TrackElem {
975    Field(FieldIdx),
976    Variant(VariantIdx),
977    Discriminant,
978    // Length of a slice.
979    DerefLen,
980}
981
982impl<V, T> TryFrom<ProjectionElem<V, T>> for TrackElem {
983    type Error = ();
984
985    fn try_from(value: ProjectionElem<V, T>) -> Result<Self, Self::Error> {
986        match value {
987            ProjectionElem::Field(field, _) => Ok(TrackElem::Field(field)),
988            ProjectionElem::Downcast(_, idx) => Ok(TrackElem::Variant(idx)),
989            _ => Err(()),
990        }
991    }
992}
993
994/// Invokes `f` on all direct fields of `ty`.
995pub fn iter_fields<'tcx>(
996    ty: Ty<'tcx>,
997    tcx: TyCtxt<'tcx>,
998    typing_env: ty::TypingEnv<'tcx>,
999    mut f: impl FnMut(Option<VariantIdx>, FieldIdx, Ty<'tcx>),
1000) {
1001    match ty.kind() {
1002        ty::Tuple(list) => {
1003            for (field, ty) in list.iter().enumerate() {
1004                f(None, field.into(), ty);
1005            }
1006        }
1007        ty::Adt(def, args) => {
1008            if def.is_union() {
1009                return;
1010            }
1011            for (v_index, v_def) in def.variants().iter_enumerated() {
1012                let variant = if def.is_struct() { None } else { Some(v_index) };
1013                for (f_index, f_def) in v_def.fields.iter().enumerate() {
1014                    let field_ty = f_def.ty(tcx, args);
1015                    let field_ty =
1016                        tcx.try_normalize_erasing_regions(typing_env, field_ty).unwrap_or_else(
1017                            |_| tcx.erase_and_anonymize_regions(field_ty.skip_norm_wip()),
1018                        );
1019                    f(variant, f_index.into(), field_ty);
1020                }
1021            }
1022        }
1023        ty::Closure(_, args) => {
1024            iter_fields(args.as_closure().tupled_upvars_ty(), tcx, typing_env, f);
1025        }
1026        ty::Coroutine(_, args) => {
1027            iter_fields(args.as_coroutine().tupled_upvars_ty(), tcx, typing_env, f);
1028        }
1029        ty::CoroutineClosure(_, args) => {
1030            iter_fields(args.as_coroutine_closure().tupled_upvars_ty(), tcx, typing_env, f);
1031        }
1032        _ => (),
1033    }
1034}
1035
1036/// Returns all locals with projections that have their reference or address taken.
1037pub fn excluded_locals(body: &Body<'_>) -> GrowableBitSet<Local> {
1038    struct Collector {
1039        result: GrowableBitSet<Local>,
1040    }
1041
1042    impl<'tcx> Visitor<'tcx> for Collector {
1043        fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
1044            if context.may_observe_address() && !place.is_indirect() {
1045                // A pointer to a place could be used to access other places with the same local,
1046                // hence we have to exclude the local completely.
1047                self.result.insert(place.local);
1048            }
1049        }
1050    }
1051
1052    let mut collector = Collector { result: GrowableBitSet::new_empty() };
1053    collector.visit_body(body);
1054    collector.result
1055}
1056
1057fn debug_with_context_rec<V: Debug + Eq + HasBottom>(
1058    place: PlaceIndex,
1059    place_str: &str,
1060    new: &StateData<V>,
1061    old: Option<&StateData<V>>,
1062    map: &Map<'_>,
1063    f: &mut Formatter<'_>,
1064) -> std::fmt::Result {
1065    if let Some(value) = map.places[place].value_index {
1066        match old {
1067            None => f.write_fmt(format_args!("{0}: {1:?}\n", place_str, new.get(value)))writeln!(f, "{}: {:?}", place_str, new.get(value))?,
1068            Some(old) => {
1069                if new.get(value) != old.get(value) {
1070                    f.write_fmt(format_args!("\u{1f}-{0}: {1:?}\n", place_str, old.get(value)))writeln!(f, "\u{001f}-{}: {:?}", place_str, old.get(value))?;
1071                    f.write_fmt(format_args!("\u{1f}+{0}: {1:?}\n", place_str, new.get(value)))writeln!(f, "\u{001f}+{}: {:?}", place_str, new.get(value))?;
1072                }
1073            }
1074        }
1075    }
1076
1077    for child in map.children(place) {
1078        let info_elem = map.places[child].proj_elem.unwrap();
1079        let child_place_str = match info_elem {
1080            TrackElem::Discriminant => {
1081                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("discriminant({0})", place_str))
    })format!("discriminant({place_str})")
1082            }
1083            TrackElem::Variant(idx) => {
1084                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("({0} as {1:?})", place_str, idx))
    })format!("({place_str} as {idx:?})")
1085            }
1086            TrackElem::Field(field) => {
1087                if place_str.starts_with('*') {
1088                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("({0}).{1}", place_str,
                field.index()))
    })format!("({}).{}", place_str, field.index())
1089                } else {
1090                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}.{1}", place_str,
                field.index()))
    })format!("{}.{}", place_str, field.index())
1091                }
1092            }
1093            TrackElem::DerefLen => {
1094                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Len(*{0})", place_str))
    })format!("Len(*{})", place_str)
1095            }
1096        };
1097        debug_with_context_rec(child, &child_place_str, new, old, map, f)?;
1098    }
1099
1100    Ok(())
1101}
1102
1103pub fn debug_with_context<V: Debug + Eq + HasBottom>(
1104    new: &StateData<V>,
1105    old: Option<&StateData<V>>,
1106    map: &Map<'_>,
1107    f: &mut Formatter<'_>,
1108) -> std::fmt::Result {
1109    for (local, place) in map.locals.iter_enumerated() {
1110        if let Some(place) = place {
1111            debug_with_context_rec(*place, &::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", local))
    })format!("{local:?}"), new, old, map, f)?;
1112        }
1113    }
1114    Ok(())
1115}