Skip to main content

rustc_borrowck/type_check/
mod.rs

1//! This pass type-checks the MIR to ensure it is not broken.
2
3use std::rc::Rc;
4use std::{fmt, iter, mem};
5
6use rustc_abi::FieldIdx;
7use rustc_data_structures::frozen::Frozen;
8use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
9use rustc_errors::ErrorGuaranteed;
10use rustc_hir as hir;
11use rustc_hir::def::DefKind;
12use rustc_hir::def_id::LocalDefId;
13use rustc_hir::lang_items::LangItem;
14use rustc_index::{IndexSlice, IndexVec};
15use rustc_infer::infer::canonical::QueryRegionConstraints;
16use rustc_infer::infer::outlives::env::RegionBoundPairs;
17use rustc_infer::infer::region_constraints::RegionConstraintData;
18use rustc_infer::infer::{
19    BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin,
20};
21use rustc_infer::traits::PredicateObligations;
22use rustc_middle::bug;
23use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
24use rustc_middle::mir::*;
25use rustc_middle::traits::query::NoSolution;
26use rustc_middle::ty::adjustment::PointerCoercion;
27use rustc_middle::ty::cast::CastTy;
28use rustc_middle::ty::{
29    self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
30    GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, UserArgs, UserTypeAnnotationIndex, fold_regions,
31};
32use rustc_mir_dataflow::move_paths::MoveData;
33use rustc_mir_dataflow::points::DenseLocationMap;
34use rustc_span::def_id::CRATE_DEF_ID;
35use rustc_span::{Span, Spanned, sym};
36use rustc_trait_selection::infer::InferCtxtExt;
37use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
38use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
39use tracing::{debug, instrument, trace};
40
41use crate::borrow_set::BorrowSet;
42use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet};
43use crate::diagnostics::UniverseInfo;
44use crate::polonius::PoloniusContext;
45use crate::polonius::legacy::{PoloniusFacts, PoloniusLocationTable};
46use crate::region_infer::TypeTest;
47use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices};
48use crate::session_diagnostics::{MoveUnsized, SimdIntrinsicArgConst};
49use crate::type_check::free_region_relations::{CreateResult, UniversalRegionRelations};
50use crate::universal_regions::{DefiningTy, UniversalRegions};
51use crate::{BorrowCheckRootCtxt, BorrowckInferCtxt, DeferredClosureRequirements, path_utils};
52
53macro_rules! span_mirbug {
54    ($context:expr, $elem:expr, $($message:tt)*) => ({
55        $crate::type_check::mirbug(
56            $context.tcx(),
57            $context.last_span,
58            format!(
59                "broken MIR in {:?} ({:?}): {}",
60                $context.body().source.def_id(),
61                $elem,
62                format_args!($($message)*),
63            ),
64        )
65    })
66}
67
68pub(crate) mod canonical;
69pub(crate) mod constraint_conversion;
70pub(crate) mod free_region_relations;
71mod input_output;
72pub(crate) mod liveness;
73mod relate_tys;
74
75/// Type checks the given `mir` in the context of the inference
76/// context `infcx`. Returns any region constraints that have yet to
77/// be proven. This result includes liveness constraints that
78/// ensure that regions appearing in the types of all local variables
79/// are live at all points where that local variable may later be
80/// used.
81///
82/// This phase of type-check ought to be infallible -- this is because
83/// the original, HIR-based type-check succeeded. So if any errors
84/// occur here, we will get a `bug!` reported.
85///
86/// # Parameters
87///
88/// - `infcx` -- inference context to use
89/// - `body` -- MIR body to type-check
90/// - `promoted` -- map of promoted constants within `body`
91/// - `universal_regions` -- the universal regions from `body`s function signature
92/// - `location_table` -- for datalog polonius, the map between `Location`s and `RichLocation`s
93/// - `borrow_set` -- information about borrows occurring in `body`
94/// - `polonius_facts` -- when using Polonius, this is the generated set of Polonius facts
95/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
96/// - `location_map` -- map between MIR `Location` and `PointIndex`
97pub(crate) fn type_check<'tcx>(
98    root_cx: &mut BorrowCheckRootCtxt<'tcx>,
99    infcx: &BorrowckInferCtxt<'tcx>,
100    body: &Body<'tcx>,
101    promoted: &IndexSlice<Promoted, Body<'tcx>>,
102    universal_regions: UniversalRegions<'tcx>,
103    location_table: &PoloniusLocationTable,
104    borrow_set: &BorrowSet<'tcx>,
105    polonius_facts: &mut Option<PoloniusFacts>,
106    move_data: &MoveData<'tcx>,
107    location_map: Rc<DenseLocationMap>,
108) -> MirTypeckResults<'tcx> {
109    let mut constraints = MirTypeckRegionConstraints {
110        placeholder_indices: PlaceholderIndices::default(),
111        placeholder_index_to_region: IndexVec::default(),
112        liveness_constraints: LivenessValues::with_specific_points(Rc::clone(&location_map)),
113        outlives_constraints: OutlivesConstraintSet::default(),
114        type_tests: Vec::default(),
115        universe_causes: FxIndexMap::default(),
116    };
117
118    let CreateResult {
119        universal_region_relations,
120        region_bound_pairs,
121        normalized_inputs_and_output,
122        known_type_outlives_obligations,
123    } = free_region_relations::create(infcx, universal_regions, &mut constraints);
124
125    {
126        // Scope these variables so it's clear they're not used later
127        let pre_obligations = infcx.take_registered_region_obligations();
128        if !pre_obligations.is_empty() {
    {
        ::core::panicking::panic_fmt(format_args!("there should be no incoming region obligations = {0:#?}",
                pre_obligations));
    }
};assert!(
129            pre_obligations.is_empty(),
130            "there should be no incoming region obligations = {pre_obligations:#?}",
131        );
132        let pre_assumptions = infcx.take_registered_region_assumptions();
133        if !pre_assumptions.is_empty() {
    {
        ::core::panicking::panic_fmt(format_args!("there should be no incoming region assumptions = {0:#?}",
                pre_assumptions));
    }
};assert!(
134            pre_assumptions.is_empty(),
135            "there should be no incoming region assumptions = {pre_assumptions:#?}",
136        );
137    }
138
139    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:139",
                        "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(139u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                        ::tracing_core::field::FieldSet::new(&["normalized_inputs_and_output"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&normalized_inputs_and_output)
                                            as &dyn Value))])
            });
    } else { ; }
};debug!(?normalized_inputs_and_output);
140
141    let polonius_context = if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
142        Some(PoloniusContext::default())
143    } else {
144        None
145    };
146
147    let mut deferred_closure_requirements = Default::default();
148    let mut typeck = TypeChecker {
149        root_cx,
150        infcx,
151        last_span: body.span,
152        body,
153        promoted,
154        user_type_annotations: &body.user_type_annotations,
155        region_bound_pairs: &region_bound_pairs,
156        known_type_outlives_obligations: &known_type_outlives_obligations,
157        reported_errors: Default::default(),
158        universal_regions: &universal_region_relations.universal_regions,
159        location_table,
160        polonius_facts,
161        borrow_set,
162        constraints: &mut constraints,
163        deferred_closure_requirements: &mut deferred_closure_requirements,
164        polonius_context,
165    };
166
167    typeck.check_user_type_annotations();
168    typeck.visit_body(body);
169    typeck.equate_inputs_and_outputs(&normalized_inputs_and_output);
170    typeck.check_signature_annotation();
171
172    liveness::generate(&mut typeck, &location_map, move_data);
173
174    let polonius_context = typeck.polonius_context;
175
176    // In case type check encountered an error region, we suppress unhelpful extra
177    // errors in by clearing out all outlives bounds that we may end up checking.
178    if let Some(guar) = universal_region_relations.universal_regions.encountered_re_error() {
179        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:179",
                        "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(179u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("encountered an error region; removing constraints!")
                                            as &dyn Value))])
            });
    } else { ; }
};debug!("encountered an error region; removing constraints!");
180        constraints.outlives_constraints = Default::default();
181        constraints.type_tests = Default::default();
182        root_cx.set_tainted_by_errors(guar);
183        infcx.set_tainted_by_errors(guar);
184    }
185
186    MirTypeckResults {
187        constraints,
188        universal_region_relations,
189        region_bound_pairs,
190        known_type_outlives_obligations,
191        deferred_closure_requirements,
192        polonius_context,
193    }
194}
195
196#[track_caller]
197fn mirbug(tcx: TyCtxt<'_>, span: Span, msg: String) {
198    // We sometimes see MIR failures (notably predicate failures) due to
199    // the fact that we check rvalue sized predicates here. So use `span_delayed_bug`
200    // to avoid reporting bugs in those cases.
201    tcx.dcx().span_delayed_bug(span, msg);
202}
203
204enum FieldAccessError {
205    OutOfRange { field_count: usize },
206}
207
208/// The MIR type checker. Visits the MIR and enforces all the
209/// constraints needed for it to be valid and well-typed. Along the
210/// way, it accrues region constraints -- these can later be used by
211/// NLL region checking.
212struct TypeChecker<'a, 'tcx> {
213    root_cx: &'a mut BorrowCheckRootCtxt<'tcx>,
214    infcx: &'a BorrowckInferCtxt<'tcx>,
215    last_span: Span,
216    body: &'a Body<'tcx>,
217    /// The bodies of all promoteds. As promoteds have a completely separate CFG
218    /// recursing into them may corrupt your data structures if you're not careful.
219    promoted: &'a IndexSlice<Promoted, Body<'tcx>>,
220    /// User type annotations are shared between the main MIR and the MIR of
221    /// all of the promoted items.
222    user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
223    region_bound_pairs: &'a RegionBoundPairs<'tcx>,
224    known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>],
225    reported_errors: FxIndexSet<(Ty<'tcx>, Span)>,
226    universal_regions: &'a UniversalRegions<'tcx>,
227    location_table: &'a PoloniusLocationTable,
228    polonius_facts: &'a mut Option<PoloniusFacts>,
229    borrow_set: &'a BorrowSet<'tcx>,
230    constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
231    deferred_closure_requirements: &'a mut DeferredClosureRequirements<'tcx>,
232    /// When using `-Zpolonius=next`, the liveness helper data used to create polonius constraints.
233    polonius_context: Option<PoloniusContext>,
234}
235
236/// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions
237/// inference computation.
238pub(crate) struct MirTypeckResults<'tcx> {
239    pub(crate) constraints: MirTypeckRegionConstraints<'tcx>,
240    pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
241    pub(crate) region_bound_pairs: Frozen<RegionBoundPairs<'tcx>>,
242    pub(crate) known_type_outlives_obligations: Frozen<Vec<ty::PolyTypeOutlivesPredicate<'tcx>>>,
243    pub(crate) deferred_closure_requirements: DeferredClosureRequirements<'tcx>,
244    pub(crate) polonius_context: Option<PoloniusContext>,
245}
246
247/// A collection of region constraints that must be satisfied for the
248/// program to be considered well-typed.
249#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for MirTypeckRegionConstraints<'tcx> {
    #[inline]
    fn clone(&self) -> MirTypeckRegionConstraints<'tcx> {
        MirTypeckRegionConstraints {
            placeholder_indices: ::core::clone::Clone::clone(&self.placeholder_indices),
            placeholder_index_to_region: ::core::clone::Clone::clone(&self.placeholder_index_to_region),
            liveness_constraints: ::core::clone::Clone::clone(&self.liveness_constraints),
            outlives_constraints: ::core::clone::Clone::clone(&self.outlives_constraints),
            universe_causes: ::core::clone::Clone::clone(&self.universe_causes),
            type_tests: ::core::clone::Clone::clone(&self.type_tests),
        }
    }
}Clone)] // FIXME(#146079)
250pub(crate) struct MirTypeckRegionConstraints<'tcx> {
251    /// Maps from a `ty::Placeholder` to the corresponding
252    /// `PlaceholderIndex` bit that we will use for it.
253    ///
254    /// To keep everything in sync, do not insert this set
255    /// directly. Instead, use the `placeholder_region` helper.
256    pub(crate) placeholder_indices: PlaceholderIndices<'tcx>,
257
258    /// Each time we add a placeholder to `placeholder_indices`, we
259    /// also create a corresponding "representative" region vid for
260    /// that wraps it. This vector tracks those. This way, when we
261    /// convert the same `ty::RePlaceholder(p)` twice, we can map to
262    /// the same underlying `RegionVid`.
263    pub(crate) placeholder_index_to_region: IndexVec<PlaceholderIndex, ty::Region<'tcx>>,
264
265    /// In general, the type-checker is not responsible for enforcing
266    /// liveness constraints; this job falls to the region inferencer,
267    /// which performs a liveness analysis. However, in some limited
268    /// cases, the MIR type-checker creates temporary regions that do
269    /// not otherwise appear in the MIR -- in particular, the
270    /// late-bound regions that it instantiates at call-sites -- and
271    /// hence it must report on their liveness constraints.
272    pub(crate) liveness_constraints: LivenessValues,
273
274    pub(crate) outlives_constraints: OutlivesConstraintSet<'tcx>,
275
276    pub(crate) universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
277
278    pub(crate) type_tests: Vec<TypeTest<'tcx>>,
279}
280
281impl<'tcx> MirTypeckRegionConstraints<'tcx> {
282    /// Creates a `Region` for a given `PlaceholderRegion`, or returns the
283    /// region that corresponds to a previously created one.
284    pub(crate) fn placeholder_region(
285        &mut self,
286        infcx: &InferCtxt<'tcx>,
287        placeholder: ty::PlaceholderRegion<'tcx>,
288    ) -> ty::Region<'tcx> {
289        let placeholder_index = self.placeholder_indices.insert(placeholder);
290        match self.placeholder_index_to_region.get(placeholder_index) {
291            Some(&v) => v,
292            None => {
293                let origin = NllRegionVariableOrigin::Placeholder(placeholder);
294                let region = infcx.next_nll_region_var_in_universe(origin, placeholder.universe);
295                self.placeholder_index_to_region.push(region);
296                region
297            }
298        }
299    }
300}
301
302/// The `Locations` type summarizes *where* region constraints are
303/// required to hold. Normally, this is at a particular point which
304/// created the obligation, but for constraints that the user gave, we
305/// want the constraint to hold at all points.
306#[derive(#[automatically_derived]
impl ::core::marker::Copy for Locations { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Locations {
    #[inline]
    fn clone(&self) -> Locations {
        let _: ::core::clone::AssertParamIsClone<Span>;
        let _: ::core::clone::AssertParamIsClone<Location>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Locations {
    #[inline]
    fn eq(&self, other: &Locations) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Locations::All(__self_0), Locations::All(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Locations::Single(__self_0), Locations::Single(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Locations {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Span>;
        let _: ::core::cmp::AssertParamIsEq<Location>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Locations {
    #[inline]
    fn partial_cmp(&self, other: &Locations)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match (self, other) {
            (Locations::All(__self_0), Locations::All(__arg1_0)) =>
                ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
            (Locations::Single(__self_0), Locations::Single(__arg1_0)) =>
                ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
            _ =>
                ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
                    &__arg1_discr),
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Locations {
    #[inline]
    fn cmp(&self, other: &Locations) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
            ::core::cmp::Ordering::Equal =>
                match (self, other) {
                    (Locations::All(__self_0), Locations::All(__arg1_0)) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    (Locations::Single(__self_0), Locations::Single(__arg1_0))
                        => ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    _ => unsafe { ::core::intrinsics::unreachable() }
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Locations {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            Locations::All(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            Locations::Single(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Locations {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Locations::All(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "All",
                    &__self_0),
            Locations::Single(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Single",
                    &__self_0),
        }
    }
}Debug)]
307pub enum Locations {
308    /// Indicates that a type constraint should always be true. This
309    /// is particularly important in the new borrowck analysis for
310    /// things like the type of the return slot. Consider this
311    /// example:
312    ///
313    /// ```compile_fail,E0515
314    /// fn foo<'a>(x: &'a u32) -> &'a u32 {
315    ///     let y = 22;
316    ///     return &y; // error
317    /// }
318    /// ```
319    ///
320    /// Here, we wind up with the signature from the return type being
321    /// something like `&'1 u32` where `'1` is a universal region. But
322    /// the type of the return slot `_0` is something like `&'2 u32`
323    /// where `'2` is an existential region variable. The type checker
324    /// requires that `&'2 u32 = &'1 u32` -- but at what point? In the
325    /// older NLL analysis, we required this only at the entry point
326    /// to the function. By the nature of the constraints, this wound
327    /// up propagating to all points reachable from start (because
328    /// `'1` -- as a universal region -- is live everywhere). In the
329    /// newer analysis, though, this doesn't work: `_0` is considered
330    /// dead at the start (it has no usable value) and hence this type
331    /// equality is basically a no-op. Then, later on, when we do `_0
332    /// = &'3 y`, that region `'3` never winds up related to the
333    /// universal region `'1` and hence no error occurs. Therefore, we
334    /// use Locations::All instead, which ensures that the `'1` and
335    /// `'2` are equal everything. We also use this for other
336    /// user-given type annotations; e.g., if the user wrote `let mut
337    /// x: &'static u32 = ...`, we would ensure that all values
338    /// assigned to `x` are of `'static` lifetime.
339    ///
340    /// The span points to the place the constraint arose. For example,
341    /// it points to the type in a user-given type annotation. If
342    /// there's no sensible span then it's DUMMY_SP.
343    All(Span),
344
345    /// An outlives constraint that only has to hold at a single location,
346    /// usually it represents a point where references flow from one spot to
347    /// another (e.g., `x = y`)
348    Single(Location),
349}
350
351impl Locations {
352    pub fn from_location(&self) -> Option<Location> {
353        match self {
354            Locations::All(_) => None,
355            Locations::Single(from_location) => Some(*from_location),
356        }
357    }
358
359    /// Gets a span representing the location.
360    pub fn span(&self, body: &Body<'_>) -> Span {
361        match self {
362            Locations::All(span) => *span,
363            Locations::Single(l) => body.source_info(*l).span,
364        }
365    }
366}
367
368impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
369    fn tcx(&self) -> TyCtxt<'tcx> {
370        self.infcx.tcx
371    }
372
373    fn body(&self) -> &Body<'tcx> {
374        self.body
375    }
376
377    /// Equate the inferred type and the annotated type for user type annotations
378    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("check_user_type_annotations",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(378u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::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::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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(&[]) })
                } 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;
        }
        {
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:380",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(380u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["self.user_type_annotations"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&self.user_type_annotations)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            for user_annotation in self.user_type_annotations {
                let CanonicalUserTypeAnnotation {
                        span, ref user_ty, inferred_ty } = *user_annotation;
                let annotation = self.instantiate_canonical(span, user_ty);
                self.ascribe_user_type(inferred_ty, annotation, span);
            }
        }
    }
}#[instrument(skip(self), level = "debug")]
379    fn check_user_type_annotations(&mut self) {
380        debug!(?self.user_type_annotations);
381        for user_annotation in self.user_type_annotations {
382            let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
383            let annotation = self.instantiate_canonical(span, user_ty);
384            self.ascribe_user_type(inferred_ty, annotation, span);
385        }
386    }
387
388    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("push_region_constraints",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(388u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["locations",
                                                    "category"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&locations)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&category)
                                                            as &dyn 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;
        }
        {
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:395",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(395u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["message"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&format_args!("constraints generated: {0:#?}",
                                                                data) as &dyn Value))])
                        });
                } else { ; }
            };
            constraint_conversion::ConstraintConversion::new(self.infcx,
                    self.universal_regions, self.region_bound_pairs,
                    self.known_type_outlives_obligations, locations,
                    locations.span(self.body), category,
                    self.constraints).convert_all(data);
        }
    }
}#[instrument(skip(self, data), level = "debug")]
389    fn push_region_constraints(
390        &mut self,
391        locations: Locations,
392        category: ConstraintCategory<'tcx>,
393        data: &QueryRegionConstraints<'tcx>,
394    ) {
395        debug!("constraints generated: {:#?}", data);
396
397        constraint_conversion::ConstraintConversion::new(
398            self.infcx,
399            self.universal_regions,
400            self.region_bound_pairs,
401            self.known_type_outlives_obligations,
402            locations,
403            locations.span(self.body),
404            category,
405            self.constraints,
406        )
407        .convert_all(data);
408    }
409
410    /// Try to relate `sub <: sup`
411    fn sub_types(
412        &mut self,
413        sub: Ty<'tcx>,
414        sup: Ty<'tcx>,
415        locations: Locations,
416        category: ConstraintCategory<'tcx>,
417    ) -> Result<(), NoSolution> {
418        // Use this order of parameters because the sup type is usually the
419        // "expected" type in diagnostics.
420        self.relate_types(sup, ty::Contravariant, sub, locations, category)
421    }
422
423    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("eq_types",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(423u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["expected", "found",
                                                    "locations"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expected)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&found)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&locations)
                                                            as &dyn 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: Result<(), NoSolution> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            self.relate_types(expected, ty::Invariant, found, locations,
                category)
        }
    }
}#[instrument(skip(self, category), level = "debug")]
424    fn eq_types(
425        &mut self,
426        expected: Ty<'tcx>,
427        found: Ty<'tcx>,
428        locations: Locations,
429        category: ConstraintCategory<'tcx>,
430    ) -> Result<(), NoSolution> {
431        self.relate_types(expected, ty::Invariant, found, locations, category)
432    }
433
434    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("relate_type_and_user_type",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(434u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["a", "v", "user_ty",
                                                    "locations", "category"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&v)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&user_ty)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&locations)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&category)
                                                            as &dyn 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: Result<(), NoSolution> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let annotated_type =
                self.user_type_annotations[user_ty.base].inferred_ty;
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:444",
                                    "rustc_borrowck::type_check", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(444u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["annotated_type"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&annotated_type)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);
            let tcx = self.infcx.tcx;
            for proj in &user_ty.projs {
                if !self.infcx.next_trait_solver() &&
                        let ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) =
                            curr_projected_ty.ty.kind() {
                    return Ok(());
                }
                let projected_ty =
                    curr_projected_ty.projection_ty_core(tcx, proj,
                        |ty| self.structurally_resolve(ty, locations),
                        |ty, variant_index, field, ()|
                            PlaceTy::field_ty(tcx, ty, variant_index, field),
                        |_|
                            ::core::panicking::panic("internal error: entered unreachable code"));
                curr_projected_ty = projected_ty;
            }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:470",
                                    "rustc_borrowck::type_check", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(470u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["curr_projected_ty"],
                                        ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&curr_projected_ty)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            let a = self.normalize(a, locations);
            let ty = self.normalize(curr_projected_ty.ty, locations);
            self.relate_types(ty, v.xform(ty::Contravariant), a, locations,
                    category)?;
            Ok(())
        }
    }
}#[instrument(skip(self), level = "debug")]
435    fn relate_type_and_user_type(
436        &mut self,
437        a: Ty<'tcx>,
438        v: ty::Variance,
439        user_ty: &UserTypeProjection,
440        locations: Locations,
441        category: ConstraintCategory<'tcx>,
442    ) -> Result<(), NoSolution> {
443        let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty;
444        trace!(?annotated_type);
445        let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);
446
447        let tcx = self.infcx.tcx;
448
449        for proj in &user_ty.projs {
450            // Necessary for non-trivial patterns whose user-type annotation is an opaque type,
451            // e.g. `let (_a,): Tait = whatever`, see #105897
452            if !self.infcx.next_trait_solver()
453                && let ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) =
454                    curr_projected_ty.ty.kind()
455            {
456                // There is nothing that we can compare here if we go through an opaque type.
457                // We're always in its defining scope as we can otherwise not project through
458                // it, so we're constraining it anyways.
459                return Ok(());
460            }
461            let projected_ty = curr_projected_ty.projection_ty_core(
462                tcx,
463                proj,
464                |ty| self.structurally_resolve(ty, locations),
465                |ty, variant_index, field, ()| PlaceTy::field_ty(tcx, ty, variant_index, field),
466                |_| unreachable!(),
467            );
468            curr_projected_ty = projected_ty;
469        }
470        trace!(?curr_projected_ty);
471
472        // Need to renormalize `a` as typecheck may have failed to normalize
473        // higher-ranked aliases if normalization was ambiguous due to inference.
474        let a = self.normalize(a, locations);
475        let ty = self.normalize(curr_projected_ty.ty, locations);
476        self.relate_types(ty, v.xform(ty::Contravariant), a, locations, category)?;
477
478        Ok(())
479    }
480
481    fn check_promoted(&mut self, promoted_body: &'a Body<'tcx>, location: Location) {
482        // Determine the constraints from the promoted MIR by running the type
483        // checker on the promoted MIR, then transfer the constraints back to
484        // the main MIR, changing the locations to the provided location.
485
486        let parent_body = mem::replace(&mut self.body, promoted_body);
487
488        // Use new sets of constraints and closure bounds so that we can
489        // modify their locations.
490        let polonius_facts = &mut None;
491        let mut constraints = Default::default();
492        let mut liveness_constraints =
493            LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body)));
494        let mut deferred_closure_requirements = Default::default();
495
496        // Don't try to add borrow_region facts for the promoted MIR as they refer
497        // to the wrong locations.
498        let mut swap_constraints = |this: &mut Self| {
499            mem::swap(this.polonius_facts, polonius_facts);
500            mem::swap(&mut this.constraints.outlives_constraints, &mut constraints);
501            mem::swap(&mut this.constraints.liveness_constraints, &mut liveness_constraints);
502            mem::swap(this.deferred_closure_requirements, &mut deferred_closure_requirements);
503        };
504
505        swap_constraints(self);
506
507        self.visit_body(promoted_body);
508
509        self.body = parent_body;
510
511        // Merge the outlives constraints back in, at the given location.
512        swap_constraints(self);
513        let locations = location.to_locations();
514        for constraint in constraints.outlives().iter() {
515            let mut constraint = *constraint;
516            constraint.locations = locations;
517            if let ConstraintCategory::Return(_)
518            | ConstraintCategory::UseAsConst
519            | ConstraintCategory::UseAsStatic = constraint.category
520            {
521                // "Returning" from a promoted is an assignment to a
522                // temporary from the user's point of view.
523                constraint.category = ConstraintCategory::Boring;
524            }
525            self.constraints.outlives_constraints.push(constraint)
526        }
527
528        // If there are nested bodies in promoteds, we also need to update their
529        // location to something in the actual body, not the promoted.
530        //
531        // We don't update the constraint categories of the resulting constraints
532        // as returns in nested bodies are a proper return, even if that nested body
533        // is in a promoted.
534        for (closure_def_id, args, _locations) in deferred_closure_requirements {
535            self.deferred_closure_requirements.push((closure_def_id, args, locations));
536        }
537
538        // If the region is live at least one location in the promoted MIR,
539        // then add a liveness constraint to the main MIR for this region
540        // at the location provided as an argument to this method
541        //
542        // add_location doesn't care about ordering so not a problem for the live regions to be
543        // unordered.
544        #[allow(rustc::potential_query_instability)]
545        for region in liveness_constraints.live_regions_unordered() {
546            self.constraints.liveness_constraints.add_location(region, location);
547        }
548    }
549}
550
551impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
552    fn visit_span(&mut self, span: Span) {
553        if !span.is_dummy() {
554            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:554",
                        "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(554u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                        ::tracing_core::field::FieldSet::new(&["span"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&span) as
                                            &dyn Value))])
            });
    } else { ; }
};debug!(?span);
555            self.last_span = span;
556        }
557    }
558
559    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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_body",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(559u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::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::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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(&[]) })
                } 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 {
                if !std::ptr::eq(self.body, body) {
                    ::core::panicking::panic("assertion failed: std::ptr::eq(self.body, body)")
                };
            };
            for (local, local_decl) in body.local_decls.iter_enumerated() {
                self.visit_local_decl(local, local_decl);
            }
            for (block, block_data) in body.basic_blocks.iter_enumerated() {
                let mut location = Location { block, statement_index: 0 };
                for stmt in &block_data.statements {
                    self.visit_statement(stmt, location);
                    location.statement_index += 1;
                }
                self.visit_terminator(block_data.terminator(), location);
                self.check_iscleanup(block_data);
            }
        }
    }
}#[instrument(skip(self, body), level = "debug")]
560    fn visit_body(&mut self, body: &Body<'tcx>) {
561        debug_assert!(std::ptr::eq(self.body, body));
562
563        for (local, local_decl) in body.local_decls.iter_enumerated() {
564            self.visit_local_decl(local, local_decl);
565        }
566
567        for (block, block_data) in body.basic_blocks.iter_enumerated() {
568            let mut location = Location { block, statement_index: 0 };
569            for stmt in &block_data.statements {
570                self.visit_statement(stmt, location);
571                location.statement_index += 1;
572            }
573
574            self.visit_terminator(block_data.terminator(), location);
575            self.check_iscleanup(block_data);
576        }
577    }
578
579    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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_statement",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(579u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["stmt", "location"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&stmt)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
                                                            as &dyn 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;
        }
        {
            self.super_statement(stmt, location);
            let tcx = self.tcx();
            match &stmt.kind {
                StatementKind::Assign(box (place, rv)) => {
                    let category =
                        match place.as_local() {
                            Some(RETURN_PLACE) => {
                                let defining_ty = &self.universal_regions.defining_ty;
                                if defining_ty.is_const() {
                                    if tcx.is_static(defining_ty.def_id()) {
                                        ConstraintCategory::UseAsStatic
                                    } else { ConstraintCategory::UseAsConst }
                                } else {
                                    ConstraintCategory::Return(ReturnConstraint::Normal)
                                }
                            }
                            Some(l) if
                                #[allow(non_exhaustive_omitted_patterns)] match self.body.local_decls[l].local_info()
                                    {
                                    LocalInfo::AggregateTemp => true,
                                    _ => false,
                                } => {
                                ConstraintCategory::Usage
                            }
                            Some(l) if !self.body.local_decls[l].is_user_variable() => {
                                ConstraintCategory::Boring
                            }
                            _ => ConstraintCategory::Assignment,
                        };
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:615",
                                            "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(615u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                            ::tracing_core::field::FieldSet::new(&["message"],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&format_args!("assignment category: {0:?} {1:?}",
                                                                        category,
                                                                        place.as_local().map(|l| &self.body.local_decls[l])) as
                                                                &dyn Value))])
                                });
                        } else { ; }
                    };
                    let place_ty = place.ty(self.body, tcx).ty;
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:622",
                                            "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(622u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                            ::tracing_core::field::FieldSet::new(&["place_ty"],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&debug(&place_ty)
                                                                as &dyn Value))])
                                });
                        } else { ; }
                    };
                    let place_ty = self.normalize(place_ty, location);
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:624",
                                            "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(624u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                            ::tracing_core::field::FieldSet::new(&["message"],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&format_args!("place_ty normalized: {0:?}",
                                                                        place_ty) as &dyn Value))])
                                });
                        } else { ; }
                    };
                    let rv_ty = rv.ty(self.body, tcx);
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:626",
                                            "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(626u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                            ::tracing_core::field::FieldSet::new(&["rv_ty"],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&debug(&rv_ty) as
                                                                &dyn Value))])
                                });
                        } else { ; }
                    };
                    let rv_ty = self.normalize(rv_ty, location);
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:628",
                                            "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(628u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                            ::tracing_core::field::FieldSet::new(&["message"],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&format_args!("normalized rv_ty: {0:?}",
                                                                        rv_ty) as &dyn Value))])
                                });
                        } else { ; }
                    };
                    if let Err(terr) =
                            self.sub_types(rv_ty, place_ty, location.to_locations(),
                                category) {
                        {
                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                self.body().source.def_id(), stmt,
                                                format_args!("bad assignment ({0:?} = {1:?}): {2:?}",
                                                    place_ty, rv_ty, terr)))
                                    }))
                        };
                    }
                    if let Some(annotation_index) = self.rvalue_user_ty(rv) &&
                            let Err(terr) =
                                self.relate_type_and_user_type(rv_ty, ty::Invariant,
                                    &UserTypeProjection {
                                            base: annotation_index,
                                            projs: ::alloc::vec::Vec::new(),
                                        }, location.to_locations(),
                                    ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg))
                        {
                        let annotation =
                            &self.user_type_annotations[annotation_index];
                        {
                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                self.body().source.def_id(), stmt,
                                                format_args!("bad user type on rvalue ({0:?} = {1:?}): {2:?}",
                                                    annotation, rv_ty, terr)))
                                    }))
                        };
                    }
                    if !self.tcx().features().unsized_fn_params() {
                        let trait_ref =
                            ty::TraitRef::new(tcx,
                                tcx.require_lang_item(LangItem::Sized, self.last_span),
                                [place_ty]);
                        self.prove_trait_ref(trait_ref, location.to_locations(),
                            ConstraintCategory::SizedBound);
                    }
                }
                StatementKind::AscribeUserType(box (place, projection),
                    variance) => {
                    let place_ty = place.ty(self.body, tcx).ty;
                    if let Err(terr) =
                            self.relate_type_and_user_type(place_ty, *variance,
                                projection, Locations::All(stmt.source_info.span),
                                ConstraintCategory::TypeAnnotation(AnnotationSource::Ascription))
                        {
                        let annotation =
                            &self.user_type_annotations[projection.base];
                        {
                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                self.body().source.def_id(), stmt,
                                                format_args!("bad type assert ({0:?} <: {1:?} with projections {2:?}): {3:?}",
                                                    place_ty, annotation, projection.projs, terr)))
                                    }))
                        };
                    }
                }
                StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(..))
                    | StatementKind::FakeRead(..) |
                    StatementKind::StorageLive(..) |
                    StatementKind::StorageDead(..) | StatementKind::Retag { .. }
                    | StatementKind::Coverage(..) |
                    StatementKind::ConstEvalCounter |
                    StatementKind::PlaceMention(..) |
                    StatementKind::BackwardIncompatibleDropHint { .. } |
                    StatementKind::Nop => {}
                StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(..))
                    | StatementKind::SetDiscriminant { .. } => {
                    ::rustc_middle::util::bug::bug_fmt(format_args!("Statement not allowed in this MIR phase"))
                }
            }
        }
    }
}#[instrument(skip(self), level = "debug")]
580    fn visit_statement(&mut self, stmt: &Statement<'tcx>, location: Location) {
581        self.super_statement(stmt, location);
582        let tcx = self.tcx();
583        match &stmt.kind {
584            StatementKind::Assign(box (place, rv)) => {
585                // Assignments to temporaries are not "interesting";
586                // they are not caused by the user, but rather artifacts
587                // of lowering. Assignments to other sorts of places *are* interesting
588                // though.
589                let category = match place.as_local() {
590                    Some(RETURN_PLACE) => {
591                        let defining_ty = &self.universal_regions.defining_ty;
592                        if defining_ty.is_const() {
593                            if tcx.is_static(defining_ty.def_id()) {
594                                ConstraintCategory::UseAsStatic
595                            } else {
596                                ConstraintCategory::UseAsConst
597                            }
598                        } else {
599                            ConstraintCategory::Return(ReturnConstraint::Normal)
600                        }
601                    }
602                    Some(l)
603                        if matches!(
604                            self.body.local_decls[l].local_info(),
605                            LocalInfo::AggregateTemp
606                        ) =>
607                    {
608                        ConstraintCategory::Usage
609                    }
610                    Some(l) if !self.body.local_decls[l].is_user_variable() => {
611                        ConstraintCategory::Boring
612                    }
613                    _ => ConstraintCategory::Assignment,
614                };
615                debug!(
616                    "assignment category: {:?} {:?}",
617                    category,
618                    place.as_local().map(|l| &self.body.local_decls[l])
619                );
620
621                let place_ty = place.ty(self.body, tcx).ty;
622                debug!(?place_ty);
623                let place_ty = self.normalize(place_ty, location);
624                debug!("place_ty normalized: {:?}", place_ty);
625                let rv_ty = rv.ty(self.body, tcx);
626                debug!(?rv_ty);
627                let rv_ty = self.normalize(rv_ty, location);
628                debug!("normalized rv_ty: {:?}", rv_ty);
629                if let Err(terr) =
630                    self.sub_types(rv_ty, place_ty, location.to_locations(), category)
631                {
632                    span_mirbug!(
633                        self,
634                        stmt,
635                        "bad assignment ({:?} = {:?}): {:?}",
636                        place_ty,
637                        rv_ty,
638                        terr
639                    );
640                }
641
642                if let Some(annotation_index) = self.rvalue_user_ty(rv)
643                    && let Err(terr) = self.relate_type_and_user_type(
644                        rv_ty,
645                        ty::Invariant,
646                        &UserTypeProjection { base: annotation_index, projs: vec![] },
647                        location.to_locations(),
648                        ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg),
649                    )
650                {
651                    let annotation = &self.user_type_annotations[annotation_index];
652                    span_mirbug!(
653                        self,
654                        stmt,
655                        "bad user type on rvalue ({:?} = {:?}): {:?}",
656                        annotation,
657                        rv_ty,
658                        terr
659                    );
660                }
661
662                if !self.tcx().features().unsized_fn_params() {
663                    let trait_ref = ty::TraitRef::new(
664                        tcx,
665                        tcx.require_lang_item(LangItem::Sized, self.last_span),
666                        [place_ty],
667                    );
668                    self.prove_trait_ref(
669                        trait_ref,
670                        location.to_locations(),
671                        ConstraintCategory::SizedBound,
672                    );
673                }
674            }
675            StatementKind::AscribeUserType(box (place, projection), variance) => {
676                let place_ty = place.ty(self.body, tcx).ty;
677                if let Err(terr) = self.relate_type_and_user_type(
678                    place_ty,
679                    *variance,
680                    projection,
681                    Locations::All(stmt.source_info.span),
682                    ConstraintCategory::TypeAnnotation(AnnotationSource::Ascription),
683                ) {
684                    let annotation = &self.user_type_annotations[projection.base];
685                    span_mirbug!(
686                        self,
687                        stmt,
688                        "bad type assert ({:?} <: {:?} with projections {:?}): {:?}",
689                        place_ty,
690                        annotation,
691                        projection.projs,
692                        terr
693                    );
694                }
695            }
696            StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(..))
697            | StatementKind::FakeRead(..)
698            | StatementKind::StorageLive(..)
699            | StatementKind::StorageDead(..)
700            | StatementKind::Retag { .. }
701            | StatementKind::Coverage(..)
702            | StatementKind::ConstEvalCounter
703            | StatementKind::PlaceMention(..)
704            | StatementKind::BackwardIncompatibleDropHint { .. }
705            | StatementKind::Nop => {}
706            StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(..))
707            | StatementKind::SetDiscriminant { .. } => {
708                bug!("Statement not allowed in this MIR phase")
709            }
710        }
711    }
712
713    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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_terminator",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(713u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["term",
                                                    "term_location"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&term)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&term_location)
                                                            as &dyn 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;
        }
        {
            self.super_terminator(term, term_location);
            let tcx = self.tcx();
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:717",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(717u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["message"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&format_args!("terminator kind: {0:?}",
                                                                term.kind) as &dyn Value))])
                        });
                } else { ; }
            };
            match &term.kind {
                TerminatorKind::Goto { .. } | TerminatorKind::UnwindResume |
                    TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return
                    | TerminatorKind::CoroutineDrop |
                    TerminatorKind::Unreachable | TerminatorKind::Drop { .. } |
                    TerminatorKind::FalseEdge { .. } |
                    TerminatorKind::FalseUnwind { .. } |
                    TerminatorKind::InlineAsm { .. } => {}
                TerminatorKind::SwitchInt { discr, .. } => {
                    let switch_ty = discr.ty(self.body, tcx);
                    if !switch_ty.is_integral() && !switch_ty.is_char() &&
                            !switch_ty.is_bool() {
                        {
                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                self.body().source.def_id(), term,
                                                format_args!("bad SwitchInt discr ty {0:?}", switch_ty)))
                                    }))
                        };
                    }
                }
                TerminatorKind::Call { func, args, .. } |
                    TerminatorKind::TailCall { func, args, .. } => {
                    let (call_source, destination, is_diverging) =
                        match term.kind {
                            TerminatorKind::Call { call_source, destination, target, ..
                                } => {
                                (call_source, destination, target.is_none())
                            }
                            TerminatorKind::TailCall { .. } => {
                                (CallSource::Normal, RETURN_PLACE.into(), false)
                            }
                            _ =>
                                ::core::panicking::panic("internal error: entered unreachable code"),
                        };
                    let func_ty = func.ty(self.body, tcx);
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:752",
                                            "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(752u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                            ::tracing_core::field::FieldSet::new(&["message"],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&format_args!("func_ty.kind: {0:?}",
                                                                        func_ty.kind()) as &dyn Value))])
                                });
                        } else { ; }
                    };
                    let sig =
                        match func_ty.kind() {
                            ty::FnDef(..) | ty::FnPtr(..) => func_ty.fn_sig(tcx),
                            _ => {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), term,
                                                        format_args!("call to non-function {0:?}", func_ty)))
                                            }))
                                };
                                return;
                            }
                        };
                    let (unnormalized_sig, map) =
                        tcx.instantiate_bound_regions(sig,
                            |br|
                                {
                                    use crate::renumber::RegionCtxt;
                                    let region_ctxt_fn =
                                        ||
                                            {
                                                let reg_info =
                                                    match br.kind {
                                                        ty::BoundRegionKind::Anon => sym::anon,
                                                        ty::BoundRegionKind::Named(def_id) => tcx.item_name(def_id),
                                                        ty::BoundRegionKind::ClosureEnv => sym::env,
                                                        ty::BoundRegionKind::NamedForPrinting(_) => {
                                                            ::rustc_middle::util::bug::bug_fmt(format_args!("only used for pretty printing"))
                                                        }
                                                    };
                                                RegionCtxt::LateBound(reg_info)
                                            };
                                    self.infcx.next_region_var(RegionVariableOrigin::BoundRegion(term.source_info.span,
                                            br.kind, BoundRegionConversionTime::FnCall), region_ctxt_fn)
                                });
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:786",
                                            "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(786u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                            ::tracing_core::field::FieldSet::new(&["unnormalized_sig"],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::DEBUG <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&debug(&unnormalized_sig)
                                                                as &dyn Value))])
                                });
                        } else { ; }
                    };
                    self.prove_predicates(unnormalized_sig.inputs_and_output.iter().map(|ty|
                                {
                                    ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty.into())))
                                }), term_location.to_locations(),
                        ConstraintCategory::Boring);
                    let sig =
                        self.deeply_normalize(unnormalized_sig, term_location);
                    if sig != unnormalized_sig {
                        self.prove_predicates(sig.inputs_and_output.iter().map(|ty|
                                    {
                                        ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty.into())))
                                    }), term_location.to_locations(),
                            ConstraintCategory::Boring);
                    }
                    self.check_call_dest(term, &sig, destination, is_diverging,
                        term_location);
                    for &late_bound_region in map.values() {
                        let region_vid =
                            self.universal_regions.to_region_vid(late_bound_region);
                        self.constraints.liveness_constraints.add_location(region_vid,
                            term_location);
                    }
                    self.check_call_inputs(term, func, &sig, args,
                        term_location, call_source);
                }
                TerminatorKind::Assert { cond, msg, .. } => {
                    let cond_ty = cond.ty(self.body, tcx);
                    if cond_ty != tcx.types.bool {
                        {
                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                self.body().source.def_id(), term,
                                                format_args!("bad Assert ({0:?}, not bool", cond_ty)))
                                    }))
                        };
                    }
                    if let AssertKind::BoundsCheck { len, index } = &**msg {
                        if len.ty(self.body, tcx) != tcx.types.usize {
                            {
                                crate::type_check::mirbug(self.tcx(), self.last_span,
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                    self.body().source.def_id(), len,
                                                    format_args!("bounds-check length non-usize {0:?}", len)))
                                        }))
                            }
                        }
                        if index.ty(self.body, tcx) != tcx.types.usize {
                            {
                                crate::type_check::mirbug(self.tcx(), self.last_span,
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                    self.body().source.def_id(), index,
                                                    format_args!("bounds-check index non-usize {0:?}", index)))
                                        }))
                            }
                        }
                    }
                }
                TerminatorKind::Yield { value, resume_arg, .. } => {
                    match self.body.yield_ty() {
                        None => {
                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                self.body().source.def_id(), term,
                                                format_args!("yield in non-coroutine")))
                                    }))
                        }
                        Some(ty) => {
                            let value_ty = value.ty(self.body, tcx);
                            if let Err(terr) =
                                    self.sub_types(value_ty, ty, term_location.to_locations(),
                                        ConstraintCategory::Yield) {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), term,
                                                        format_args!("type of yield value is {0:?}, but the yield type is {1:?}: {2:?}",
                                                            value_ty, ty, terr)))
                                            }))
                                };
                            }
                        }
                    }
                    match self.body.resume_ty() {
                        None => {
                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                self.body().source.def_id(), term,
                                                format_args!("yield in non-coroutine")))
                                    }))
                        }
                        Some(ty) => {
                            let resume_ty = resume_arg.ty(self.body, tcx);
                            if let Err(terr) =
                                    self.sub_types(ty, resume_ty.ty,
                                        term_location.to_locations(), ConstraintCategory::Yield) {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), term,
                                                        format_args!("type of resume place is {0:?}, but the resume type is {1:?}: {2:?}",
                                                            resume_ty, ty, terr)))
                                            }))
                                };
                            }
                        }
                    }
                }
            }
        }
    }
}#[instrument(skip(self), level = "debug")]
714    fn visit_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location) {
715        self.super_terminator(term, term_location);
716        let tcx = self.tcx();
717        debug!("terminator kind: {:?}", term.kind);
718        match &term.kind {
719            TerminatorKind::Goto { .. }
720            | TerminatorKind::UnwindResume
721            | TerminatorKind::UnwindTerminate(_)
722            | TerminatorKind::Return
723            | TerminatorKind::CoroutineDrop
724            | TerminatorKind::Unreachable
725            | TerminatorKind::Drop { .. }
726            | TerminatorKind::FalseEdge { .. }
727            | TerminatorKind::FalseUnwind { .. }
728            | TerminatorKind::InlineAsm { .. } => {
729                // no checks needed for these
730            }
731
732            TerminatorKind::SwitchInt { discr, .. } => {
733                let switch_ty = discr.ty(self.body, tcx);
734                if !switch_ty.is_integral() && !switch_ty.is_char() && !switch_ty.is_bool() {
735                    span_mirbug!(self, term, "bad SwitchInt discr ty {:?}", switch_ty);
736                }
737                // FIXME: check the values
738            }
739            TerminatorKind::Call { func, args, .. }
740            | TerminatorKind::TailCall { func, args, .. } => {
741                let (call_source, destination, is_diverging) = match term.kind {
742                    TerminatorKind::Call { call_source, destination, target, .. } => {
743                        (call_source, destination, target.is_none())
744                    }
745                    TerminatorKind::TailCall { .. } => {
746                        (CallSource::Normal, RETURN_PLACE.into(), false)
747                    }
748                    _ => unreachable!(),
749                };
750
751                let func_ty = func.ty(self.body, tcx);
752                debug!("func_ty.kind: {:?}", func_ty.kind());
753
754                let sig = match func_ty.kind() {
755                    ty::FnDef(..) | ty::FnPtr(..) => func_ty.fn_sig(tcx),
756                    _ => {
757                        span_mirbug!(self, term, "call to non-function {:?}", func_ty);
758                        return;
759                    }
760                };
761                let (unnormalized_sig, map) = tcx.instantiate_bound_regions(sig, |br| {
762                    use crate::renumber::RegionCtxt;
763
764                    let region_ctxt_fn = || {
765                        let reg_info = match br.kind {
766                            ty::BoundRegionKind::Anon => sym::anon,
767                            ty::BoundRegionKind::Named(def_id) => tcx.item_name(def_id),
768                            ty::BoundRegionKind::ClosureEnv => sym::env,
769                            ty::BoundRegionKind::NamedForPrinting(_) => {
770                                bug!("only used for pretty printing")
771                            }
772                        };
773
774                        RegionCtxt::LateBound(reg_info)
775                    };
776
777                    self.infcx.next_region_var(
778                        RegionVariableOrigin::BoundRegion(
779                            term.source_info.span,
780                            br.kind,
781                            BoundRegionConversionTime::FnCall,
782                        ),
783                        region_ctxt_fn,
784                    )
785                });
786                debug!(?unnormalized_sig);
787                // IMPORTANT: We have to prove well formed for the function signature before
788                // we normalize it, as otherwise types like `<&'a &'b () as Trait>::Assoc`
789                // get normalized away, causing us to ignore the `'b: 'a` bound used by the function.
790                //
791                // Normalization results in a well formed type if the input is well formed, so we
792                // don't have to check it twice.
793                //
794                // See #91068 for an example.
795                self.prove_predicates(
796                    unnormalized_sig.inputs_and_output.iter().map(|ty| {
797                        ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
798                            ty.into(),
799                        )))
800                    }),
801                    term_location.to_locations(),
802                    ConstraintCategory::Boring,
803                );
804
805                let sig = self.deeply_normalize(unnormalized_sig, term_location);
806                // HACK(#114936): `WF(sig)` does not imply `WF(normalized(sig))`
807                // with built-in `Fn` implementations, since the impl may not be
808                // well-formed itself.
809                if sig != unnormalized_sig {
810                    self.prove_predicates(
811                        sig.inputs_and_output.iter().map(|ty| {
812                            ty::Binder::dummy(ty::PredicateKind::Clause(
813                                ty::ClauseKind::WellFormed(ty.into()),
814                            ))
815                        }),
816                        term_location.to_locations(),
817                        ConstraintCategory::Boring,
818                    );
819                }
820
821                self.check_call_dest(term, &sig, destination, is_diverging, term_location);
822
823                // The ordinary liveness rules will ensure that all
824                // regions in the type of the callee are live here. We
825                // then further constrain the late-bound regions that
826                // were instantiated at the call site to be live as
827                // well. The resulting is that all the input (and
828                // output) types in the signature must be live, since
829                // all the inputs that fed into it were live.
830                for &late_bound_region in map.values() {
831                    let region_vid = self.universal_regions.to_region_vid(late_bound_region);
832                    self.constraints.liveness_constraints.add_location(region_vid, term_location);
833                }
834
835                self.check_call_inputs(term, func, &sig, args, term_location, call_source);
836            }
837            TerminatorKind::Assert { cond, msg, .. } => {
838                let cond_ty = cond.ty(self.body, tcx);
839                if cond_ty != tcx.types.bool {
840                    span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
841                }
842
843                if let AssertKind::BoundsCheck { len, index } = &**msg {
844                    if len.ty(self.body, tcx) != tcx.types.usize {
845                        span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
846                    }
847                    if index.ty(self.body, tcx) != tcx.types.usize {
848                        span_mirbug!(self, index, "bounds-check index non-usize {:?}", index)
849                    }
850                }
851            }
852            TerminatorKind::Yield { value, resume_arg, .. } => {
853                match self.body.yield_ty() {
854                    None => span_mirbug!(self, term, "yield in non-coroutine"),
855                    Some(ty) => {
856                        let value_ty = value.ty(self.body, tcx);
857                        if let Err(terr) = self.sub_types(
858                            value_ty,
859                            ty,
860                            term_location.to_locations(),
861                            ConstraintCategory::Yield,
862                        ) {
863                            span_mirbug!(
864                                self,
865                                term,
866                                "type of yield value is {:?}, but the yield type is {:?}: {:?}",
867                                value_ty,
868                                ty,
869                                terr
870                            );
871                        }
872                    }
873                }
874
875                match self.body.resume_ty() {
876                    None => span_mirbug!(self, term, "yield in non-coroutine"),
877                    Some(ty) => {
878                        let resume_ty = resume_arg.ty(self.body, tcx);
879                        if let Err(terr) = self.sub_types(
880                            ty,
881                            resume_ty.ty,
882                            term_location.to_locations(),
883                            ConstraintCategory::Yield,
884                        ) {
885                            span_mirbug!(
886                                self,
887                                term,
888                                "type of resume place is {:?}, but the resume type is {:?}: {:?}",
889                                resume_ty,
890                                ty,
891                                terr
892                            );
893                        }
894                    }
895                }
896            }
897        }
898    }
899
900    fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
901        self.super_local_decl(local, local_decl);
902
903        for user_ty in
904            local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections)
905        {
906            let span = self.user_type_annotations[user_ty.base].span;
907
908            let ty = if local_decl.is_nonref_binding() {
909                local_decl.ty
910            } else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() {
911                // If we have a binding of the form `let ref x: T = ..`
912                // then remove the outermost reference so we can check the
913                // type annotation for the remaining type.
914                rty
915            } else {
916                ::rustc_middle::util::bug::bug_fmt(format_args!("{0:?} with ref binding has wrong type {1}",
        local, local_decl.ty));bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
917            };
918
919            if let Err(terr) = self.relate_type_and_user_type(
920                ty,
921                ty::Invariant,
922                user_ty,
923                Locations::All(span),
924                ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration),
925            ) {
926                {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), local,
                        format_args!("bad user type on variable {0:?}: {1:?} != {2:?} ({3:?})",
                            local, local_decl.ty, local_decl.user_ty, terr)))
            }))
};span_mirbug!(
927                    self,
928                    local,
929                    "bad user type on variable {:?}: {:?} != {:?} ({:?})",
930                    local,
931                    local_decl.ty,
932                    local_decl.user_ty,
933                    terr,
934                );
935            }
936        }
937
938        // When `unsized_fn_params` is enabled, this is checked in `check_call_dest`,
939        // and `hir_typeck` still forces all non-argument locals to be sized (i.e., we don't
940        // fully re-check what was already checked on HIR).
941        if !self.tcx().features().unsized_fn_params() {
942            match self.body.local_kind(local) {
943                LocalKind::ReturnPointer | LocalKind::Arg => {
944                    // return values of normal functions are required to be
945                    // sized by typeck, but return values of ADT constructors are
946                    // not because we don't include a `Self: Sized` bounds on them.
947                    //
948                    // Unbound parts of arguments were never required to be Sized
949                    // - maybe we should make that a warning.
950                    return;
951                }
952                LocalKind::Temp => {
953                    let span = local_decl.source_info.span;
954                    let ty = local_decl.ty;
955                    self.ensure_place_sized(ty, span);
956                }
957            }
958        }
959    }
960
961    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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_rvalue",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(961u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["rvalue",
                                                    "location"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&rvalue)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
                                                            as &dyn 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;
        }
        {
            self.super_rvalue(rvalue, location);
            let tcx = self.tcx();
            let span = self.body.source_info(location).span;
            match rvalue {
                Rvalue::Aggregate(ak, ops) =>
                    self.check_aggregate_rvalue(rvalue, ak, ops, location),
                Rvalue::Repeat(operand, len) => {
                    let array_ty = rvalue.ty(self.body.local_decls(), tcx);
                    self.prove_predicate(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(array_ty.into())),
                        Locations::Single(location), ConstraintCategory::Boring);
                    if len.try_to_target_usize(tcx).is_none_or(|len| len > 1) {
                        match operand {
                            Operand::Copy(..) | Operand::Constant(..) |
                                Operand::RuntimeChecks(_) => {}
                            Operand::Move(place) => {
                                let ty = place.ty(self.body, tcx).ty;
                                let trait_ref =
                                    ty::TraitRef::new(tcx,
                                        tcx.require_lang_item(LangItem::Copy, span), [ty]);
                                self.prove_trait_ref(trait_ref, Locations::Single(location),
                                    ConstraintCategory::CopyBound);
                            }
                        }
                    }
                }
                Rvalue::Cast(cast_kind, op, ty) => {
                    match *cast_kind {
                        CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer(target_safety),
                            coercion_source) => {
                            let is_implicit_coercion =
                                coercion_source == CoercionSource::Implicit;
                            let src_ty = op.ty(self.body, tcx);
                            let mut src_sig = src_ty.fn_sig(tcx);
                            if let ty::FnDef(def_id, _) = *src_ty.kind() &&
                                                let ty::FnPtr(_, target_hdr) = *ty.kind() &&
                                            tcx.codegen_fn_attrs(def_id).safe_target_features &&
                                        target_hdr.safety.is_safe() &&
                                    let Some(safe_sig) =
                                        tcx.adjust_target_feature_sig(def_id, src_sig,
                                            self.body.source.def_id()) {
                                src_sig = safe_sig;
                            }
                            if src_sig.safety().is_safe() && target_safety.is_unsafe() {
                                src_sig = tcx.safe_to_unsafe_sig(src_sig);
                            }
                            if src_sig.has_bound_regions() &&
                                            let ty::FnPtr(target_fn_tys, target_hdr) = *ty.kind() &&
                                        let target_sig = target_fn_tys.with(target_hdr) &&
                                    let Some(target_sig) = target_sig.no_bound_vars() {
                                let src_sig =
                                    self.infcx.instantiate_binder_with_fresh_vars(span,
                                        BoundRegionConversionTime::HigherRankedType, src_sig);
                                let src_ty =
                                    Ty::new_fn_ptr(self.tcx(), ty::Binder::dummy(src_sig));
                                self.prove_predicate(ty::ClauseKind::WellFormed(src_ty.into()),
                                    location.to_locations(),
                                    ConstraintCategory::Cast {
                                        is_raw_ptr_dyn_type_cast: false,
                                        is_implicit_coercion,
                                        unsize_to: None,
                                    });
                                let src_ty = self.normalize(src_ty, location);
                                if let Err(terr) =
                                        self.sub_types(src_ty, *ty, location.to_locations(),
                                            ConstraintCategory::Cast {
                                                is_raw_ptr_dyn_type_cast: false,
                                                is_implicit_coercion,
                                                unsize_to: None,
                                            }) {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("equating {0:?} with {1:?} yields {2:?}",
                                                                target_sig, src_sig, terr)))
                                                }))
                                    };
                                };
                            }
                            let src_ty = Ty::new_fn_ptr(tcx, src_sig);
                            self.prove_predicate(ty::ClauseKind::WellFormed(src_ty.into()),
                                location.to_locations(),
                                ConstraintCategory::Cast {
                                    is_raw_ptr_dyn_type_cast: false,
                                    is_implicit_coercion,
                                    unsize_to: None,
                                });
                            let src_ty = self.normalize(src_ty, location);
                            if let Err(terr) =
                                    self.sub_types(src_ty, *ty, location.to_locations(),
                                        ConstraintCategory::Cast {
                                            is_raw_ptr_dyn_type_cast: false,
                                            is_implicit_coercion,
                                            unsize_to: None,
                                        }) {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), rvalue,
                                                        format_args!("equating {0:?} with {1:?} yields {2:?}",
                                                            src_ty, ty, terr)))
                                            }))
                                };
                            }
                        }
                        CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(safety),
                            coercion_source) => {
                            let sig =
                                match op.ty(self.body, tcx).kind() {
                                    ty::Closure(_, args) => args.as_closure().sig(),
                                    _ =>
                                        ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached")),
                                };
                            let ty_fn_ptr_from =
                                Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, safety));
                            let is_implicit_coercion =
                                coercion_source == CoercionSource::Implicit;
                            if let Err(terr) =
                                    self.sub_types(ty_fn_ptr_from, *ty, location.to_locations(),
                                        ConstraintCategory::Cast {
                                            is_raw_ptr_dyn_type_cast: false,
                                            is_implicit_coercion,
                                            unsize_to: None,
                                        }) {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), rvalue,
                                                        format_args!("equating {0:?} with {1:?} yields {2:?}",
                                                            ty_fn_ptr_from, ty, terr)))
                                            }))
                                };
                            }
                        }
                        CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer,
                            coercion_source) => {
                            let fn_sig = op.ty(self.body, tcx).fn_sig(tcx);
                            let fn_sig = self.normalize(fn_sig, location);
                            let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
                            let is_implicit_coercion =
                                coercion_source == CoercionSource::Implicit;
                            if let Err(terr) =
                                    self.sub_types(ty_fn_ptr_from, *ty, location.to_locations(),
                                        ConstraintCategory::Cast {
                                            is_raw_ptr_dyn_type_cast: false,
                                            is_implicit_coercion,
                                            unsize_to: None,
                                        }) {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), rvalue,
                                                        format_args!("equating {0:?} with {1:?} yields {2:?}",
                                                            ty_fn_ptr_from, ty, terr)))
                                            }))
                                };
                            }
                        }
                        CastKind::PointerCoercion(PointerCoercion::Unsize,
                            coercion_source) => {
                            let &ty = ty;
                            let trait_ref =
                                ty::TraitRef::new(tcx,
                                    tcx.require_lang_item(LangItem::CoerceUnsized, span),
                                    [op.ty(self.body, tcx), ty]);
                            let is_implicit_coercion =
                                coercion_source == CoercionSource::Implicit;
                            let unsize_to =
                                fold_regions(tcx, ty,
                                    |r, _|
                                        {
                                            if let ty::ReVar(_) = r.kind() {
                                                tcx.lifetimes.re_erased
                                            } else { r }
                                        });
                            self.prove_trait_ref(trait_ref, location.to_locations(),
                                ConstraintCategory::Cast {
                                    is_raw_ptr_dyn_type_cast: false,
                                    is_implicit_coercion,
                                    unsize_to: Some(unsize_to),
                                });
                        }
                        CastKind::PointerCoercion(PointerCoercion::MutToConstPointer,
                            coercion_source) => {
                            let ty::RawPtr(ty_from, hir::Mutability::Mut) =
                                op.ty(self.body,
                                        tcx).kind() else {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("unexpected base type for cast {0:?}", ty)))
                                                }))
                                    };
                                    return;
                                };
                            let ty::RawPtr(ty_to, hir::Mutability::Not) =
                                ty.kind() else {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("unexpected target type for cast {0:?}", ty)))
                                                }))
                                    };
                                    return;
                                };
                            let is_implicit_coercion =
                                coercion_source == CoercionSource::Implicit;
                            if let Err(terr) =
                                    self.sub_types(*ty_from, *ty_to, location.to_locations(),
                                        ConstraintCategory::Cast {
                                            is_raw_ptr_dyn_type_cast: false,
                                            is_implicit_coercion,
                                            unsize_to: None,
                                        }) {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), rvalue,
                                                        format_args!("relating {0:?} with {1:?} yields {2:?}",
                                                            ty_from, ty_to, terr)))
                                            }))
                                };
                            }
                        }
                        CastKind::PointerCoercion(PointerCoercion::ArrayToPointer,
                            coercion_source) => {
                            let ty_from = op.ty(self.body, tcx);
                            let opt_ty_elem_mut =
                                match ty_from.kind() {
                                    ty::RawPtr(array_ty, array_mut) =>
                                        match array_ty.kind() {
                                            ty::Array(ty_elem, _) => Some((ty_elem, *array_mut)),
                                            _ => None,
                                        },
                                    _ => None,
                                };
                            let Some((ty_elem, ty_mut)) =
                                opt_ty_elem_mut else {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("ArrayToPointer cast from unexpected type {0:?}",
                                                                ty_from)))
                                                }))
                                    };
                                    return;
                                };
                            let (ty_to, ty_to_mut) =
                                match ty.kind() {
                                    ty::RawPtr(ty_to, ty_to_mut) => (ty_to, *ty_to_mut),
                                    _ => {
                                        {
                                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                                ::alloc::__export::must_use({
                                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                                self.body().source.def_id(), rvalue,
                                                                format_args!("ArrayToPointer cast to unexpected type {0:?}",
                                                                    ty)))
                                                    }))
                                        };
                                        return;
                                    }
                                };
                            if ty_to_mut.is_mut() && ty_mut.is_not() {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), rvalue,
                                                        format_args!("ArrayToPointer cast from const {0:?} to mut {1:?}",
                                                            ty, ty_to)))
                                            }))
                                };
                                return;
                            }
                            let is_implicit_coercion =
                                coercion_source == CoercionSource::Implicit;
                            if let Err(terr) =
                                    self.sub_types(*ty_elem, *ty_to, location.to_locations(),
                                        ConstraintCategory::Cast {
                                            is_raw_ptr_dyn_type_cast: false,
                                            is_implicit_coercion,
                                            unsize_to: None,
                                        }) {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), rvalue,
                                                        format_args!("relating {0:?} with {1:?} yields {2:?}",
                                                            ty_elem, ty_to, terr)))
                                            }))
                                }
                            }
                        }
                        CastKind::PointerExposeProvenance => {
                            let ty_from = op.ty(self.body, tcx);
                            let cast_ty_from = CastTy::from_ty(ty_from);
                            let cast_ty_to = CastTy::from_ty(*ty);
                            match (cast_ty_from, cast_ty_to) {
                                (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_)))
                                    => (),
                                _ => {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("Invalid PointerExposeProvenance cast {0:?} -> {1:?}",
                                                                ty_from, ty)))
                                                }))
                                    }
                                }
                            }
                        }
                        CastKind::PointerWithExposedProvenance => {
                            let ty_from = op.ty(self.body, tcx);
                            let cast_ty_from = CastTy::from_ty(ty_from);
                            let cast_ty_to = CastTy::from_ty(*ty);
                            match (cast_ty_from, cast_ty_to) {
                                (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => (),
                                _ => {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("Invalid PointerWithExposedProvenance cast {0:?} -> {1:?}",
                                                                ty_from, ty)))
                                                }))
                                    }
                                }
                            }
                        }
                        CastKind::IntToInt => {
                            let ty_from = op.ty(self.body, tcx);
                            let cast_ty_from = CastTy::from_ty(ty_from);
                            let cast_ty_to = CastTy::from_ty(*ty);
                            match (cast_ty_from, cast_ty_to) {
                                (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => (),
                                _ => {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("Invalid IntToInt cast {0:?} -> {1:?}",
                                                                ty_from, ty)))
                                                }))
                                    }
                                }
                            }
                        }
                        CastKind::IntToFloat => {
                            let ty_from = op.ty(self.body, tcx);
                            let cast_ty_from = CastTy::from_ty(ty_from);
                            let cast_ty_to = CastTy::from_ty(*ty);
                            match (cast_ty_from, cast_ty_to) {
                                (Some(CastTy::Int(_)), Some(CastTy::Float)) => (),
                                _ => {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("Invalid IntToFloat cast {0:?} -> {1:?}",
                                                                ty_from, ty)))
                                                }))
                                    }
                                }
                            }
                        }
                        CastKind::FloatToInt => {
                            let ty_from = op.ty(self.body, tcx);
                            let cast_ty_from = CastTy::from_ty(ty_from);
                            let cast_ty_to = CastTy::from_ty(*ty);
                            match (cast_ty_from, cast_ty_to) {
                                (Some(CastTy::Float), Some(CastTy::Int(_))) => (),
                                _ => {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("Invalid FloatToInt cast {0:?} -> {1:?}",
                                                                ty_from, ty)))
                                                }))
                                    }
                                }
                            }
                        }
                        CastKind::FloatToFloat => {
                            let ty_from = op.ty(self.body, tcx);
                            let cast_ty_from = CastTy::from_ty(ty_from);
                            let cast_ty_to = CastTy::from_ty(*ty);
                            match (cast_ty_from, cast_ty_to) {
                                (Some(CastTy::Float), Some(CastTy::Float)) => (),
                                _ => {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("Invalid FloatToFloat cast {0:?} -> {1:?}",
                                                                ty_from, ty)))
                                                }))
                                    }
                                }
                            }
                        }
                        CastKind::FnPtrToPtr => {
                            let ty_from = op.ty(self.body, tcx);
                            let cast_ty_from = CastTy::from_ty(ty_from);
                            let cast_ty_to = CastTy::from_ty(*ty);
                            match (cast_ty_from, cast_ty_to) {
                                (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => (),
                                _ => {
                                    {
                                        crate::type_check::mirbug(self.tcx(), self.last_span,
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                            self.body().source.def_id(), rvalue,
                                                            format_args!("Invalid FnPtrToPtr cast {0:?} -> {1:?}",
                                                                ty_from, ty)))
                                                }))
                                    }
                                }
                            }
                        }
                        CastKind::PtrToPtr => {
                            let ty_from = op.ty(self.body, tcx);
                            let Some(CastTy::Ptr(src)) =
                                CastTy::from_ty(ty_from) else {
                                    ::core::panicking::panic("internal error: entered unreachable code");
                                };
                            let Some(CastTy::Ptr(dst)) =
                                CastTy::from_ty(*ty) else {
                                    ::core::panicking::panic("internal error: entered unreachable code");
                                };
                            if self.infcx.type_is_sized_modulo_regions(self.infcx.param_env,
                                    dst.ty) {
                                let trait_ref =
                                    ty::TraitRef::new(tcx,
                                        tcx.require_lang_item(LangItem::Sized, self.last_span),
                                        [dst.ty]);
                                self.prove_trait_ref(trait_ref, location.to_locations(),
                                    ConstraintCategory::Cast {
                                        is_raw_ptr_dyn_type_cast: false,
                                        is_implicit_coercion: true,
                                        unsize_to: None,
                                    });
                            } else if let ty::Dynamic(src_tty, src_lt) =
                                        *self.struct_tail(src.ty, location).kind() &&
                                    let ty::Dynamic(dst_tty, dst_lt) =
                                        *self.struct_tail(dst.ty, location).kind() {
                                match (src_tty.principal(), dst_tty.principal()) {
                                    (Some(_), Some(_)) => {
                                        let src_obj =
                                            Ty::new_dynamic(tcx,
                                                tcx.mk_poly_existential_predicates(&src_tty.without_auto_traits().collect::<Vec<_>>()),
                                                src_lt);
                                        let dst_obj =
                                            Ty::new_dynamic(tcx,
                                                tcx.mk_poly_existential_predicates(&dst_tty.without_auto_traits().collect::<Vec<_>>()),
                                                dst_lt);
                                        {
                                            use ::tracing::__macro_support::Callsite as _;
                                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                                {
                                                    static META: ::tracing::Metadata<'static> =
                                                        {
                                                            ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:1507",
                                                                "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                                                ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                                                ::tracing_core::__macro_support::Option::Some(1507u32),
                                                                ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                                                ::tracing_core::field::FieldSet::new(&["src_tty", "dst_tty",
                                                                                "src_obj", "dst_obj"],
                                                                    ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                                ::tracing::metadata::Kind::EVENT)
                                                        };
                                                    ::tracing::callsite::DefaultCallsite::new(&META)
                                                };
                                            let enabled =
                                                ::tracing::Level::DEBUG <=
                                                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                                        ::tracing::Level::DEBUG <=
                                                            ::tracing::level_filters::LevelFilter::current() &&
                                                    {
                                                        let interest = __CALLSITE.interest();
                                                        !interest.is_never() &&
                                                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                                interest)
                                                    };
                                            if enabled {
                                                (|value_set: ::tracing::field::ValueSet|
                                                            {
                                                                let meta = __CALLSITE.metadata();
                                                                ::tracing::Event::dispatch(meta, &value_set);
                                                                ;
                                                            })({
                                                        #[allow(unused_imports)]
                                                        use ::tracing::field::{debug, display, Value};
                                                        let mut iter = __CALLSITE.metadata().fields().iter();
                                                        __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                                            ::tracing::__macro_support::Option::Some(&debug(&src_tty) as
                                                                                    &dyn Value)),
                                                                        (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                                            ::tracing::__macro_support::Option::Some(&debug(&dst_tty) as
                                                                                    &dyn Value)),
                                                                        (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                                            ::tracing::__macro_support::Option::Some(&debug(&src_obj) as
                                                                                    &dyn Value)),
                                                                        (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                                            ::tracing::__macro_support::Option::Some(&debug(&dst_obj) as
                                                                                    &dyn Value))])
                                                    });
                                            } else { ; }
                                        };
                                        self.sub_types(src_obj, dst_obj, location.to_locations(),
                                                ConstraintCategory::Cast {
                                                    is_raw_ptr_dyn_type_cast: true,
                                                    is_implicit_coercion: false,
                                                    unsize_to: None,
                                                }).unwrap();
                                    }
                                    (None, None) => {
                                        let src_lt = self.universal_regions.to_region_vid(src_lt);
                                        let dst_lt = self.universal_regions.to_region_vid(dst_lt);
                                        self.constraints.outlives_constraints.push(OutlivesConstraint {
                                                sup: src_lt,
                                                sub: dst_lt,
                                                locations: location.to_locations(),
                                                span: location.to_locations().span(self.body),
                                                category: ConstraintCategory::Cast {
                                                    is_raw_ptr_dyn_type_cast: true,
                                                    is_implicit_coercion: false,
                                                    unsize_to: None,
                                                },
                                                variance_info: ty::VarianceDiagInfo::default(),
                                                from_closure: false,
                                            });
                                    }
                                    (None, Some(_)) =>
                                        ::rustc_middle::util::bug::bug_fmt(format_args!("introducing a principal should have errored in HIR typeck")),
                                    (Some(_), None) => {
                                        ::rustc_middle::util::bug::bug_fmt(format_args!("dropping the principal should have been an unsizing cast"))
                                    }
                                }
                            }
                        }
                        CastKind::Transmute => {
                            let ty_from = op.ty(self.body, tcx);
                            match ty_from.kind() {
                                ty::Pat(base, _) if base == ty => {}
                                _ => {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), rvalue,
                                                        format_args!("Unexpected CastKind::Transmute {0:?} -> {1:?}, which is not permitted in Analysis MIR",
                                                            ty_from, ty)))
                                            }))
                                }
                            }
                        }
                        CastKind::Subtype => {
                            ::rustc_middle::util::bug::bug_fmt(format_args!("CastKind::Subtype shouldn\'t exist in borrowck"))
                        }
                    }
                }
                Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
                    self.add_reborrow_constraint(location, *region,
                        borrowed_place);
                }
                Rvalue::BinaryOp(BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le
                    | BinOp::Gt | BinOp::Ge, box (left, right)) => {
                    let ty_left = left.ty(self.body, tcx);
                    match ty_left.kind() {
                        ty::RawPtr(_, _) | ty::FnPtr(..) => {
                            let ty_right = right.ty(self.body, tcx);
                            let common_ty =
                                self.infcx.next_ty_var(self.body.source_info(location).span);
                            self.sub_types(ty_left, common_ty, location.to_locations(),
                                    ConstraintCategory::CallArgument(None)).unwrap_or_else(|err|
                                    {
                                        ::rustc_middle::util::bug::bug_fmt(format_args!("Could not equate type variable with {0:?}: {1:?}",
                                                ty_left, err))
                                    });
                            if let Err(terr) =
                                    self.sub_types(ty_right, common_ty, location.to_locations(),
                                        ConstraintCategory::CallArgument(None)) {
                                {
                                    crate::type_check::mirbug(self.tcx(), self.last_span,
                                        ::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                        self.body().source.def_id(), rvalue,
                                                        format_args!("unexpected comparison types {0:?} and {1:?} yields {2:?}",
                                                            ty_left, ty_right, terr)))
                                            }))
                                }
                            }
                        }
                        ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char |
                            ty::Float(_) if ty_left == right.ty(self.body, tcx) => {}
                        _ => {
                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                self.body().source.def_id(), rvalue,
                                                format_args!("unexpected comparison types {0:?} and {1:?}",
                                                    ty_left, right.ty(self.body, tcx))))
                                    }))
                        }
                    }
                }
                Rvalue::WrapUnsafeBinder(op, ty) => {
                    let operand_ty = op.ty(self.body, self.tcx());
                    let ty::UnsafeBinder(binder_ty) =
                        *ty.kind() else {
                            ::core::panicking::panic("internal error: entered unreachable code");
                        };
                    let expected_ty =
                        self.infcx.instantiate_binder_with_fresh_vars(self.body().source_info(location).span,
                            BoundRegionConversionTime::HigherRankedType,
                            binder_ty.into());
                    self.sub_types(operand_ty, expected_ty,
                            location.to_locations(),
                            ConstraintCategory::Boring).unwrap();
                }
                Rvalue::Use(_) | Rvalue::UnaryOp(_, _) |
                    Rvalue::CopyForDeref(_) | Rvalue::BinaryOp(..) |
                    Rvalue::RawPtr(..) | Rvalue::ThreadLocalRef(..) |
                    Rvalue::Discriminant(..) => {}
            }
        }
    }
}#[instrument(skip(self), level = "debug")]
962    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
963        self.super_rvalue(rvalue, location);
964        let tcx = self.tcx();
965        let span = self.body.source_info(location).span;
966        match rvalue {
967            Rvalue::Aggregate(ak, ops) => self.check_aggregate_rvalue(rvalue, ak, ops, location),
968
969            Rvalue::Repeat(operand, len) => {
970                let array_ty = rvalue.ty(self.body.local_decls(), tcx);
971                self.prove_predicate(
972                    ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(array_ty.into())),
973                    Locations::Single(location),
974                    ConstraintCategory::Boring,
975                );
976
977                // If the length cannot be evaluated we must assume that the length can be larger
978                // than 1.
979                // If the length is larger than 1, the repeat expression will need to copy the
980                // element, so we require the `Copy` trait.
981                if len.try_to_target_usize(tcx).is_none_or(|len| len > 1) {
982                    match operand {
983                        Operand::Copy(..) | Operand::Constant(..) | Operand::RuntimeChecks(_) => {
984                            // These are always okay: direct use of a const, or a value that can
985                            // evidently be copied.
986                        }
987                        Operand::Move(place) => {
988                            // Make sure that repeated elements implement `Copy`.
989                            let ty = place.ty(self.body, tcx).ty;
990                            let trait_ref = ty::TraitRef::new(
991                                tcx,
992                                tcx.require_lang_item(LangItem::Copy, span),
993                                [ty],
994                            );
995
996                            self.prove_trait_ref(
997                                trait_ref,
998                                Locations::Single(location),
999                                ConstraintCategory::CopyBound,
1000                            );
1001                        }
1002                    }
1003                }
1004            }
1005
1006            Rvalue::Cast(cast_kind, op, ty) => {
1007                match *cast_kind {
1008                    CastKind::PointerCoercion(
1009                        PointerCoercion::ReifyFnPointer(target_safety),
1010                        coercion_source,
1011                    ) => {
1012                        let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
1013                        let src_ty = op.ty(self.body, tcx);
1014                        let mut src_sig = src_ty.fn_sig(tcx);
1015                        if let ty::FnDef(def_id, _) = *src_ty.kind()
1016                            && let ty::FnPtr(_, target_hdr) = *ty.kind()
1017                            && tcx.codegen_fn_attrs(def_id).safe_target_features
1018                            && target_hdr.safety.is_safe()
1019                            && let Some(safe_sig) = tcx.adjust_target_feature_sig(
1020                                def_id,
1021                                src_sig,
1022                                self.body.source.def_id(),
1023                            )
1024                        {
1025                            src_sig = safe_sig;
1026                        }
1027
1028                        if src_sig.safety().is_safe() && target_safety.is_unsafe() {
1029                            src_sig = tcx.safe_to_unsafe_sig(src_sig);
1030                        }
1031
1032                        // HACK: This shouldn't be necessary... We can remove this when we actually
1033                        // get binders with where clauses, then elaborate implied bounds into that
1034                        // binder, and implement a higher-ranked subtyping algorithm that actually
1035                        // respects these implied bounds.
1036                        //
1037                        // This protects against the case where we are casting from a higher-ranked
1038                        // fn item to a non-higher-ranked fn pointer, where the cast throws away
1039                        // implied bounds that would've needed to be checked at the call site. This
1040                        // only works when we're casting to a non-higher-ranked fn ptr, since
1041                        // placeholders in the target signature could have untracked implied
1042                        // bounds, resulting in incorrect errors.
1043                        //
1044                        // We check that this signature is WF before subtyping the signature with
1045                        // the target fn sig.
1046                        if src_sig.has_bound_regions()
1047                            && let ty::FnPtr(target_fn_tys, target_hdr) = *ty.kind()
1048                            && let target_sig = target_fn_tys.with(target_hdr)
1049                            && let Some(target_sig) = target_sig.no_bound_vars()
1050                        {
1051                            let src_sig = self.infcx.instantiate_binder_with_fresh_vars(
1052                                span,
1053                                BoundRegionConversionTime::HigherRankedType,
1054                                src_sig,
1055                            );
1056                            let src_ty = Ty::new_fn_ptr(self.tcx(), ty::Binder::dummy(src_sig));
1057                            self.prove_predicate(
1058                                ty::ClauseKind::WellFormed(src_ty.into()),
1059                                location.to_locations(),
1060                                ConstraintCategory::Cast {
1061                                    is_raw_ptr_dyn_type_cast: false,
1062                                    is_implicit_coercion,
1063                                    unsize_to: None,
1064                                },
1065                            );
1066
1067                            let src_ty = self.normalize(src_ty, location);
1068                            if let Err(terr) = self.sub_types(
1069                                src_ty,
1070                                *ty,
1071                                location.to_locations(),
1072                                ConstraintCategory::Cast {
1073                                    is_raw_ptr_dyn_type_cast: false,
1074                                    is_implicit_coercion,
1075                                    unsize_to: None,
1076                                },
1077                            ) {
1078                                span_mirbug!(
1079                                    self,
1080                                    rvalue,
1081                                    "equating {:?} with {:?} yields {:?}",
1082                                    target_sig,
1083                                    src_sig,
1084                                    terr
1085                                );
1086                            };
1087                        }
1088
1089                        let src_ty = Ty::new_fn_ptr(tcx, src_sig);
1090                        // HACK: We want to assert that the signature of the source fn is
1091                        // well-formed, because we don't enforce that via the WF of FnDef
1092                        // types normally. This should be removed when we improve the tracking
1093                        // of implied bounds of fn signatures.
1094                        self.prove_predicate(
1095                            ty::ClauseKind::WellFormed(src_ty.into()),
1096                            location.to_locations(),
1097                            ConstraintCategory::Cast {
1098                                is_raw_ptr_dyn_type_cast: false,
1099                                is_implicit_coercion,
1100                                unsize_to: None,
1101                            },
1102                        );
1103
1104                        // The type that we see in the fcx is like
1105                        // `foo::<'a, 'b>`, where `foo` is the path to a
1106                        // function definition. When we extract the
1107                        // signature, it comes from the `fn_sig` query,
1108                        // and hence may contain unnormalized results.
1109                        let src_ty = self.normalize(src_ty, location);
1110                        if let Err(terr) = self.sub_types(
1111                            src_ty,
1112                            *ty,
1113                            location.to_locations(),
1114                            ConstraintCategory::Cast {
1115                                is_raw_ptr_dyn_type_cast: false,
1116                                is_implicit_coercion,
1117                                unsize_to: None,
1118                            },
1119                        ) {
1120                            span_mirbug!(
1121                                self,
1122                                rvalue,
1123                                "equating {:?} with {:?} yields {:?}",
1124                                src_ty,
1125                                ty,
1126                                terr
1127                            );
1128                        }
1129                    }
1130
1131                    CastKind::PointerCoercion(
1132                        PointerCoercion::ClosureFnPointer(safety),
1133                        coercion_source,
1134                    ) => {
1135                        let sig = match op.ty(self.body, tcx).kind() {
1136                            ty::Closure(_, args) => args.as_closure().sig(),
1137                            _ => bug!(),
1138                        };
1139                        let ty_fn_ptr_from =
1140                            Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, safety));
1141
1142                        let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
1143                        if let Err(terr) = self.sub_types(
1144                            ty_fn_ptr_from,
1145                            *ty,
1146                            location.to_locations(),
1147                            ConstraintCategory::Cast {
1148                                is_raw_ptr_dyn_type_cast: false,
1149                                is_implicit_coercion,
1150                                unsize_to: None,
1151                            },
1152                        ) {
1153                            span_mirbug!(
1154                                self,
1155                                rvalue,
1156                                "equating {:?} with {:?} yields {:?}",
1157                                ty_fn_ptr_from,
1158                                ty,
1159                                terr
1160                            );
1161                        }
1162                    }
1163
1164                    CastKind::PointerCoercion(
1165                        PointerCoercion::UnsafeFnPointer,
1166                        coercion_source,
1167                    ) => {
1168                        let fn_sig = op.ty(self.body, tcx).fn_sig(tcx);
1169
1170                        // The type that we see in the fcx is like
1171                        // `foo::<'a, 'b>`, where `foo` is the path to a
1172                        // function definition. When we extract the
1173                        // signature, it comes from the `fn_sig` query,
1174                        // and hence may contain unnormalized results.
1175                        let fn_sig = self.normalize(fn_sig, location);
1176
1177                        let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
1178
1179                        let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
1180                        if let Err(terr) = self.sub_types(
1181                            ty_fn_ptr_from,
1182                            *ty,
1183                            location.to_locations(),
1184                            ConstraintCategory::Cast {
1185                                is_raw_ptr_dyn_type_cast: false,
1186                                is_implicit_coercion,
1187                                unsize_to: None,
1188                            },
1189                        ) {
1190                            span_mirbug!(
1191                                self,
1192                                rvalue,
1193                                "equating {:?} with {:?} yields {:?}",
1194                                ty_fn_ptr_from,
1195                                ty,
1196                                terr
1197                            );
1198                        }
1199                    }
1200
1201                    CastKind::PointerCoercion(PointerCoercion::Unsize, coercion_source) => {
1202                        let &ty = ty;
1203                        let trait_ref = ty::TraitRef::new(
1204                            tcx,
1205                            tcx.require_lang_item(LangItem::CoerceUnsized, span),
1206                            [op.ty(self.body, tcx), ty],
1207                        );
1208
1209                        let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
1210                        let unsize_to = fold_regions(tcx, ty, |r, _| {
1211                            if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased } else { r }
1212                        });
1213                        self.prove_trait_ref(
1214                            trait_ref,
1215                            location.to_locations(),
1216                            ConstraintCategory::Cast {
1217                                is_raw_ptr_dyn_type_cast: false,
1218                                is_implicit_coercion,
1219                                unsize_to: Some(unsize_to),
1220                            },
1221                        );
1222                    }
1223
1224                    CastKind::PointerCoercion(
1225                        PointerCoercion::MutToConstPointer,
1226                        coercion_source,
1227                    ) => {
1228                        let ty::RawPtr(ty_from, hir::Mutability::Mut) =
1229                            op.ty(self.body, tcx).kind()
1230                        else {
1231                            span_mirbug!(self, rvalue, "unexpected base type for cast {:?}", ty,);
1232                            return;
1233                        };
1234                        let ty::RawPtr(ty_to, hir::Mutability::Not) = ty.kind() else {
1235                            span_mirbug!(self, rvalue, "unexpected target type for cast {:?}", ty,);
1236                            return;
1237                        };
1238                        let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
1239                        if let Err(terr) = self.sub_types(
1240                            *ty_from,
1241                            *ty_to,
1242                            location.to_locations(),
1243                            ConstraintCategory::Cast {
1244                                is_raw_ptr_dyn_type_cast: false,
1245                                is_implicit_coercion,
1246                                unsize_to: None,
1247                            },
1248                        ) {
1249                            span_mirbug!(
1250                                self,
1251                                rvalue,
1252                                "relating {:?} with {:?} yields {:?}",
1253                                ty_from,
1254                                ty_to,
1255                                terr
1256                            );
1257                        }
1258                    }
1259
1260                    CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, coercion_source) => {
1261                        let ty_from = op.ty(self.body, tcx);
1262
1263                        let opt_ty_elem_mut = match ty_from.kind() {
1264                            ty::RawPtr(array_ty, array_mut) => match array_ty.kind() {
1265                                ty::Array(ty_elem, _) => Some((ty_elem, *array_mut)),
1266                                _ => None,
1267                            },
1268                            _ => None,
1269                        };
1270
1271                        let Some((ty_elem, ty_mut)) = opt_ty_elem_mut else {
1272                            span_mirbug!(
1273                                self,
1274                                rvalue,
1275                                "ArrayToPointer cast from unexpected type {:?}",
1276                                ty_from,
1277                            );
1278                            return;
1279                        };
1280
1281                        let (ty_to, ty_to_mut) = match ty.kind() {
1282                            ty::RawPtr(ty_to, ty_to_mut) => (ty_to, *ty_to_mut),
1283                            _ => {
1284                                span_mirbug!(
1285                                    self,
1286                                    rvalue,
1287                                    "ArrayToPointer cast to unexpected type {:?}",
1288                                    ty,
1289                                );
1290                                return;
1291                            }
1292                        };
1293
1294                        if ty_to_mut.is_mut() && ty_mut.is_not() {
1295                            span_mirbug!(
1296                                self,
1297                                rvalue,
1298                                "ArrayToPointer cast from const {:?} to mut {:?}",
1299                                ty,
1300                                ty_to
1301                            );
1302                            return;
1303                        }
1304
1305                        let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
1306                        if let Err(terr) = self.sub_types(
1307                            *ty_elem,
1308                            *ty_to,
1309                            location.to_locations(),
1310                            ConstraintCategory::Cast {
1311                                is_raw_ptr_dyn_type_cast: false,
1312                                is_implicit_coercion,
1313                                unsize_to: None,
1314                            },
1315                        ) {
1316                            span_mirbug!(
1317                                self,
1318                                rvalue,
1319                                "relating {:?} with {:?} yields {:?}",
1320                                ty_elem,
1321                                ty_to,
1322                                terr
1323                            )
1324                        }
1325                    }
1326
1327                    CastKind::PointerExposeProvenance => {
1328                        let ty_from = op.ty(self.body, tcx);
1329                        let cast_ty_from = CastTy::from_ty(ty_from);
1330                        let cast_ty_to = CastTy::from_ty(*ty);
1331                        match (cast_ty_from, cast_ty_to) {
1332                            (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => (),
1333                            _ => {
1334                                span_mirbug!(
1335                                    self,
1336                                    rvalue,
1337                                    "Invalid PointerExposeProvenance cast {:?} -> {:?}",
1338                                    ty_from,
1339                                    ty
1340                                )
1341                            }
1342                        }
1343                    }
1344
1345                    CastKind::PointerWithExposedProvenance => {
1346                        let ty_from = op.ty(self.body, tcx);
1347                        let cast_ty_from = CastTy::from_ty(ty_from);
1348                        let cast_ty_to = CastTy::from_ty(*ty);
1349                        match (cast_ty_from, cast_ty_to) {
1350                            (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => (),
1351                            _ => {
1352                                span_mirbug!(
1353                                    self,
1354                                    rvalue,
1355                                    "Invalid PointerWithExposedProvenance cast {:?} -> {:?}",
1356                                    ty_from,
1357                                    ty
1358                                )
1359                            }
1360                        }
1361                    }
1362                    CastKind::IntToInt => {
1363                        let ty_from = op.ty(self.body, tcx);
1364                        let cast_ty_from = CastTy::from_ty(ty_from);
1365                        let cast_ty_to = CastTy::from_ty(*ty);
1366                        match (cast_ty_from, cast_ty_to) {
1367                            (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => (),
1368                            _ => {
1369                                span_mirbug!(
1370                                    self,
1371                                    rvalue,
1372                                    "Invalid IntToInt cast {:?} -> {:?}",
1373                                    ty_from,
1374                                    ty
1375                                )
1376                            }
1377                        }
1378                    }
1379                    CastKind::IntToFloat => {
1380                        let ty_from = op.ty(self.body, tcx);
1381                        let cast_ty_from = CastTy::from_ty(ty_from);
1382                        let cast_ty_to = CastTy::from_ty(*ty);
1383                        match (cast_ty_from, cast_ty_to) {
1384                            (Some(CastTy::Int(_)), Some(CastTy::Float)) => (),
1385                            _ => {
1386                                span_mirbug!(
1387                                    self,
1388                                    rvalue,
1389                                    "Invalid IntToFloat cast {:?} -> {:?}",
1390                                    ty_from,
1391                                    ty
1392                                )
1393                            }
1394                        }
1395                    }
1396                    CastKind::FloatToInt => {
1397                        let ty_from = op.ty(self.body, tcx);
1398                        let cast_ty_from = CastTy::from_ty(ty_from);
1399                        let cast_ty_to = CastTy::from_ty(*ty);
1400                        match (cast_ty_from, cast_ty_to) {
1401                            (Some(CastTy::Float), Some(CastTy::Int(_))) => (),
1402                            _ => {
1403                                span_mirbug!(
1404                                    self,
1405                                    rvalue,
1406                                    "Invalid FloatToInt cast {:?} -> {:?}",
1407                                    ty_from,
1408                                    ty
1409                                )
1410                            }
1411                        }
1412                    }
1413                    CastKind::FloatToFloat => {
1414                        let ty_from = op.ty(self.body, tcx);
1415                        let cast_ty_from = CastTy::from_ty(ty_from);
1416                        let cast_ty_to = CastTy::from_ty(*ty);
1417                        match (cast_ty_from, cast_ty_to) {
1418                            (Some(CastTy::Float), Some(CastTy::Float)) => (),
1419                            _ => {
1420                                span_mirbug!(
1421                                    self,
1422                                    rvalue,
1423                                    "Invalid FloatToFloat cast {:?} -> {:?}",
1424                                    ty_from,
1425                                    ty
1426                                )
1427                            }
1428                        }
1429                    }
1430                    CastKind::FnPtrToPtr => {
1431                        let ty_from = op.ty(self.body, tcx);
1432                        let cast_ty_from = CastTy::from_ty(ty_from);
1433                        let cast_ty_to = CastTy::from_ty(*ty);
1434                        match (cast_ty_from, cast_ty_to) {
1435                            (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => (),
1436                            _ => {
1437                                span_mirbug!(
1438                                    self,
1439                                    rvalue,
1440                                    "Invalid FnPtrToPtr cast {:?} -> {:?}",
1441                                    ty_from,
1442                                    ty
1443                                )
1444                            }
1445                        }
1446                    }
1447                    CastKind::PtrToPtr => {
1448                        let ty_from = op.ty(self.body, tcx);
1449                        let Some(CastTy::Ptr(src)) = CastTy::from_ty(ty_from) else {
1450                            unreachable!();
1451                        };
1452                        let Some(CastTy::Ptr(dst)) = CastTy::from_ty(*ty) else {
1453                            unreachable!();
1454                        };
1455
1456                        if self.infcx.type_is_sized_modulo_regions(self.infcx.param_env, dst.ty) {
1457                            // Wide to thin ptr cast. This may even occur in an env with
1458                            // impossible predicates, such as `where dyn Trait: Sized`.
1459                            // In this case, we don't want to fall into the case below,
1460                            // since the types may not actually be equatable, but it's
1461                            // fine to perform this operation in an impossible env.
1462                            let trait_ref = ty::TraitRef::new(
1463                                tcx,
1464                                tcx.require_lang_item(LangItem::Sized, self.last_span),
1465                                [dst.ty],
1466                            );
1467                            self.prove_trait_ref(
1468                                trait_ref,
1469                                location.to_locations(),
1470                                ConstraintCategory::Cast {
1471                                    is_raw_ptr_dyn_type_cast: false,
1472                                    is_implicit_coercion: true,
1473                                    unsize_to: None,
1474                                },
1475                            );
1476                        } else if let ty::Dynamic(src_tty, src_lt) =
1477                            *self.struct_tail(src.ty, location).kind()
1478                            && let ty::Dynamic(dst_tty, dst_lt) =
1479                                *self.struct_tail(dst.ty, location).kind()
1480                        {
1481                            match (src_tty.principal(), dst_tty.principal()) {
1482                                (Some(_), Some(_)) => {
1483                                    // This checks (lifetime part of) vtable validity for pointer casts,
1484                                    // which is irrelevant when there are aren't principal traits on
1485                                    // both sides (aka only auto traits).
1486                                    //
1487                                    // Note that other checks (such as denying `dyn Send` -> `dyn
1488                                    // Debug`) are in `rustc_hir_typeck`.
1489
1490                                    // Remove auto traits.
1491                                    // Auto trait checks are handled in `rustc_hir_typeck`.
1492                                    let src_obj = Ty::new_dynamic(
1493                                        tcx,
1494                                        tcx.mk_poly_existential_predicates(
1495                                            &src_tty.without_auto_traits().collect::<Vec<_>>(),
1496                                        ),
1497                                        src_lt,
1498                                    );
1499                                    let dst_obj = Ty::new_dynamic(
1500                                        tcx,
1501                                        tcx.mk_poly_existential_predicates(
1502                                            &dst_tty.without_auto_traits().collect::<Vec<_>>(),
1503                                        ),
1504                                        dst_lt,
1505                                    );
1506
1507                                    debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
1508
1509                                    // Trait parameters are invariant, the only part that actually has
1510                                    // subtyping here is the lifetime bound of the dyn-type.
1511                                    //
1512                                    // For example in `dyn Trait<'a> + 'b <: dyn Trait<'c> + 'd`  we would
1513                                    // require that `'a == 'c` but only that `'b: 'd`.
1514                                    //
1515                                    // We must not allow freely casting lifetime bounds of dyn-types as it
1516                                    // may allow for inaccessible VTable methods being callable: #136702
1517                                    self.sub_types(
1518                                        src_obj,
1519                                        dst_obj,
1520                                        location.to_locations(),
1521                                        ConstraintCategory::Cast {
1522                                            is_raw_ptr_dyn_type_cast: true,
1523                                            is_implicit_coercion: false,
1524                                            unsize_to: None,
1525                                        },
1526                                    )
1527                                    .unwrap();
1528                                }
1529                                (None, None) => {
1530                                    // `struct_tail` returns regions which haven't been mapped
1531                                    // to nll vars yet so we do it here as `outlives_constraints`
1532                                    // expects nll vars.
1533                                    let src_lt = self.universal_regions.to_region_vid(src_lt);
1534                                    let dst_lt = self.universal_regions.to_region_vid(dst_lt);
1535
1536                                    // The principalless (no non-auto traits) case:
1537                                    // You can only cast `dyn Send + 'long` to `dyn Send + 'short`.
1538                                    self.constraints.outlives_constraints.push(
1539                                        OutlivesConstraint {
1540                                            sup: src_lt,
1541                                            sub: dst_lt,
1542                                            locations: location.to_locations(),
1543                                            span: location.to_locations().span(self.body),
1544                                            category: ConstraintCategory::Cast {
1545                                                is_raw_ptr_dyn_type_cast: true,
1546                                                is_implicit_coercion: false,
1547                                                unsize_to: None,
1548                                            },
1549                                            variance_info: ty::VarianceDiagInfo::default(),
1550                                            from_closure: false,
1551                                        },
1552                                    );
1553                                }
1554                                (None, Some(_)) => bug!(
1555                                    "introducing a principal should have errored in HIR typeck"
1556                                ),
1557                                (Some(_), None) => {
1558                                    bug!("dropping the principal should have been an unsizing cast")
1559                                }
1560                            }
1561                        }
1562                    }
1563                    CastKind::Transmute => {
1564                        let ty_from = op.ty(self.body, tcx);
1565                        match ty_from.kind() {
1566                            ty::Pat(base, _) if base == ty => {}
1567                            _ => span_mirbug!(
1568                                self,
1569                                rvalue,
1570                                "Unexpected CastKind::Transmute {ty_from:?} -> {ty:?}, which is not permitted in Analysis MIR",
1571                            ),
1572                        }
1573                    }
1574                    CastKind::Subtype => {
1575                        bug!("CastKind::Subtype shouldn't exist in borrowck")
1576                    }
1577                }
1578            }
1579
1580            Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
1581                self.add_reborrow_constraint(location, *region, borrowed_place);
1582            }
1583
1584            Rvalue::BinaryOp(
1585                BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge,
1586                box (left, right),
1587            ) => {
1588                let ty_left = left.ty(self.body, tcx);
1589                match ty_left.kind() {
1590                    // Types with regions are comparable if they have a common super-type.
1591                    ty::RawPtr(_, _) | ty::FnPtr(..) => {
1592                        let ty_right = right.ty(self.body, tcx);
1593                        let common_ty =
1594                            self.infcx.next_ty_var(self.body.source_info(location).span);
1595                        self.sub_types(
1596                            ty_left,
1597                            common_ty,
1598                            location.to_locations(),
1599                            ConstraintCategory::CallArgument(None),
1600                        )
1601                        .unwrap_or_else(|err| {
1602                            bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
1603                        });
1604                        if let Err(terr) = self.sub_types(
1605                            ty_right,
1606                            common_ty,
1607                            location.to_locations(),
1608                            ConstraintCategory::CallArgument(None),
1609                        ) {
1610                            span_mirbug!(
1611                                self,
1612                                rvalue,
1613                                "unexpected comparison types {:?} and {:?} yields {:?}",
1614                                ty_left,
1615                                ty_right,
1616                                terr
1617                            )
1618                        }
1619                    }
1620                    // For types with no regions we can just check that the
1621                    // both operands have the same type.
1622                    ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_)
1623                        if ty_left == right.ty(self.body, tcx) => {}
1624                    // Other types are compared by trait methods, not by
1625                    // `Rvalue::BinaryOp`.
1626                    _ => span_mirbug!(
1627                        self,
1628                        rvalue,
1629                        "unexpected comparison types {:?} and {:?}",
1630                        ty_left,
1631                        right.ty(self.body, tcx)
1632                    ),
1633                }
1634            }
1635
1636            Rvalue::WrapUnsafeBinder(op, ty) => {
1637                let operand_ty = op.ty(self.body, self.tcx());
1638                let ty::UnsafeBinder(binder_ty) = *ty.kind() else {
1639                    unreachable!();
1640                };
1641                let expected_ty = self.infcx.instantiate_binder_with_fresh_vars(
1642                    self.body().source_info(location).span,
1643                    BoundRegionConversionTime::HigherRankedType,
1644                    binder_ty.into(),
1645                );
1646                self.sub_types(
1647                    operand_ty,
1648                    expected_ty,
1649                    location.to_locations(),
1650                    ConstraintCategory::Boring,
1651                )
1652                .unwrap();
1653            }
1654
1655            Rvalue::Use(_)
1656            | Rvalue::UnaryOp(_, _)
1657            | Rvalue::CopyForDeref(_)
1658            | Rvalue::BinaryOp(..)
1659            | Rvalue::RawPtr(..)
1660            | Rvalue::ThreadLocalRef(..)
1661            | Rvalue::Discriminant(..) => {}
1662        }
1663    }
1664
1665    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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_operand",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1665u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["op", "location"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&op)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
                                                            as &dyn 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;
        }
        {
            self.super_operand(op, location);
            if let Operand::Constant(constant) = op {
                let maybe_uneval =
                    match constant.const_ {
                        Const::Val(..) | Const::Ty(_, _) => None,
                        Const::Unevaluated(uv, _) => Some(uv),
                    };
                if let Some(uv) = maybe_uneval {
                    if uv.promoted.is_none() {
                        let tcx = self.tcx();
                        let def_id = uv.def;
                        if tcx.def_kind(def_id) == DefKind::InlineConst {
                            let def_id = def_id.expect_local();
                            let predicates =
                                self.prove_closure_bounds(tcx, def_id, uv.args, location);
                            self.normalize_and_prove_instantiated_predicates(def_id.to_def_id(),
                                predicates, location.to_locations());
                        }
                    }
                }
            }
        }
    }
}#[instrument(level = "debug", skip(self))]
1666    fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) {
1667        self.super_operand(op, location);
1668        if let Operand::Constant(constant) = op {
1669            let maybe_uneval = match constant.const_ {
1670                Const::Val(..) | Const::Ty(_, _) => None,
1671                Const::Unevaluated(uv, _) => Some(uv),
1672            };
1673
1674            if let Some(uv) = maybe_uneval {
1675                if uv.promoted.is_none() {
1676                    let tcx = self.tcx();
1677                    let def_id = uv.def;
1678                    if tcx.def_kind(def_id) == DefKind::InlineConst {
1679                        let def_id = def_id.expect_local();
1680                        let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location);
1681                        self.normalize_and_prove_instantiated_predicates(
1682                            def_id.to_def_id(),
1683                            predicates,
1684                            location.to_locations(),
1685                        );
1686                    }
1687                }
1688            }
1689        }
1690    }
1691
1692    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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_const_operand",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1692u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["constant",
                                                    "location"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&constant)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
                                                            as &dyn 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;
        }
        {
            self.super_const_operand(constant, location);
            let ty = constant.const_.ty();
            self.infcx.tcx.for_each_free_region(&ty,
                |live_region|
                    {
                        let live_region_vid =
                            self.universal_regions.to_region_vid(live_region);
                        self.constraints.liveness_constraints.add_location(live_region_vid,
                            location);
                    });
            let locations = location.to_locations();
            if let Some(annotation_index) = constant.user_ty {
                if let Err(terr) =
                        self.relate_type_and_user_type(constant.const_.ty(),
                            ty::Invariant,
                            &UserTypeProjection {
                                    base: annotation_index,
                                    projs: ::alloc::vec::Vec::new(),
                                }, locations,
                            ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg))
                    {
                    let annotation =
                        &self.user_type_annotations[annotation_index];
                    {
                        crate::type_check::mirbug(self.tcx(), self.last_span,
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                            self.body().source.def_id(), constant,
                                            format_args!("bad constant user type {0:?} vs {1:?}: {2:?}",
                                                annotation, constant.const_.ty(), terr)))
                                }))
                    };
                }
            } else {
                let tcx = self.tcx();
                let maybe_uneval =
                    match constant.const_ {
                        Const::Ty(_, ct) =>
                            match ct.kind() {
                                ty::ConstKind::Unevaluated(uv) => {
                                    Some(UnevaluatedConst {
                                            def: uv.def,
                                            args: uv.args,
                                            promoted: None,
                                        })
                                }
                                _ => None,
                            },
                        Const::Unevaluated(uv, _) => Some(uv),
                        _ => None,
                    };
                if let Some(uv) = maybe_uneval {
                    if let Some(promoted) = uv.promoted {
                        let promoted_body = &self.promoted[promoted];
                        self.check_promoted(promoted_body, location);
                        let promoted_ty = promoted_body.return_ty();
                        if let Err(terr) =
                                self.eq_types(ty, promoted_ty, locations,
                                    ConstraintCategory::Boring) {
                            {
                                crate::type_check::mirbug(self.tcx(), self.last_span,
                                    ::alloc::__export::must_use({
                                            ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                    self.body().source.def_id(), promoted,
                                                    format_args!("bad promoted type ({0:?}: {1:?}): {2:?}", ty,
                                                        promoted_ty, terr)))
                                        }))
                            };
                        };
                    } else {
                        self.ascribe_user_type(constant.const_.ty(),
                            ty::UserType::new(ty::UserTypeKind::TypeOf(uv.def,
                                    UserArgs { args: uv.args, user_self_ty: None })),
                            locations.span(self.body));
                    }
                } else if let Some(static_def_id) =
                        constant.check_static_ptr(tcx) {
                    let unnormalized_ty =
                        tcx.type_of(static_def_id).instantiate_identity();
                    let normalized_ty =
                        self.normalize(unnormalized_ty, locations);
                    let literal_ty =
                        constant.const_.ty().builtin_deref(true).unwrap();
                    if let Err(terr) =
                            self.eq_types(literal_ty, normalized_ty, locations,
                                ConstraintCategory::Boring) {
                        {
                            crate::type_check::mirbug(self.tcx(), self.last_span,
                                ::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                                self.body().source.def_id(), constant,
                                                format_args!("bad static type {0:?} ({1:?})", constant,
                                                    terr)))
                                    }))
                        };
                    }
                } else if let Const::Ty(_, ct) = constant.const_ &&
                        let ty::ConstKind::Param(p) = ct.kind() {
                    let body_def_id =
                        self.universal_regions.defining_ty.def_id();
                    let const_param =
                        tcx.generics_of(body_def_id).const_param(p, tcx);
                    self.ascribe_user_type(constant.const_.ty(),
                        ty::UserType::new(ty::UserTypeKind::TypeOf(const_param.def_id,
                                UserArgs {
                                    args: self.universal_regions.defining_ty.args(),
                                    user_self_ty: None,
                                })), locations.span(self.body));
                }
                if let ty::FnDef(def_id, args) = *constant.const_.ty().kind()
                    {
                    let instantiated_predicates =
                        tcx.predicates_of(def_id).instantiate(tcx, args);
                    self.normalize_and_prove_instantiated_predicates(def_id,
                        instantiated_predicates, locations);
                    match (&tcx.trait_impl_of_assoc(def_id), &None) {
                        (left_val, right_val) => {
                            if !(*left_val == *right_val) {
                                let kind = ::core::panicking::AssertKind::Eq;
                                ::core::panicking::assert_failed(kind, &*left_val,
                                    &*right_val, ::core::option::Option::None);
                            }
                        }
                    };
                    self.prove_predicates(args.types().map(|ty|
                                ty::ClauseKind::WellFormed(ty.into())), locations,
                        ConstraintCategory::Boring);
                }
            }
        }
    }
}#[instrument(level = "debug", skip(self))]
1693    fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) {
1694        self.super_const_operand(constant, location);
1695        let ty = constant.const_.ty();
1696
1697        self.infcx.tcx.for_each_free_region(&ty, |live_region| {
1698            let live_region_vid = self.universal_regions.to_region_vid(live_region);
1699            self.constraints.liveness_constraints.add_location(live_region_vid, location);
1700        });
1701
1702        let locations = location.to_locations();
1703        if let Some(annotation_index) = constant.user_ty {
1704            if let Err(terr) = self.relate_type_and_user_type(
1705                constant.const_.ty(),
1706                ty::Invariant,
1707                &UserTypeProjection { base: annotation_index, projs: vec![] },
1708                locations,
1709                ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg),
1710            ) {
1711                let annotation = &self.user_type_annotations[annotation_index];
1712                span_mirbug!(
1713                    self,
1714                    constant,
1715                    "bad constant user type {:?} vs {:?}: {:?}",
1716                    annotation,
1717                    constant.const_.ty(),
1718                    terr,
1719                );
1720            }
1721        } else {
1722            let tcx = self.tcx();
1723            let maybe_uneval = match constant.const_ {
1724                Const::Ty(_, ct) => match ct.kind() {
1725                    ty::ConstKind::Unevaluated(uv) => {
1726                        Some(UnevaluatedConst { def: uv.def, args: uv.args, promoted: None })
1727                    }
1728                    _ => None,
1729                },
1730                Const::Unevaluated(uv, _) => Some(uv),
1731                _ => None,
1732            };
1733
1734            if let Some(uv) = maybe_uneval {
1735                if let Some(promoted) = uv.promoted {
1736                    let promoted_body = &self.promoted[promoted];
1737                    self.check_promoted(promoted_body, location);
1738                    let promoted_ty = promoted_body.return_ty();
1739                    if let Err(terr) =
1740                        self.eq_types(ty, promoted_ty, locations, ConstraintCategory::Boring)
1741                    {
1742                        span_mirbug!(
1743                            self,
1744                            promoted,
1745                            "bad promoted type ({:?}: {:?}): {:?}",
1746                            ty,
1747                            promoted_ty,
1748                            terr
1749                        );
1750                    };
1751                } else {
1752                    self.ascribe_user_type(
1753                        constant.const_.ty(),
1754                        ty::UserType::new(ty::UserTypeKind::TypeOf(
1755                            uv.def,
1756                            UserArgs { args: uv.args, user_self_ty: None },
1757                        )),
1758                        locations.span(self.body),
1759                    );
1760                }
1761            } else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
1762                let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
1763                let normalized_ty = self.normalize(unnormalized_ty, locations);
1764                let literal_ty = constant.const_.ty().builtin_deref(true).unwrap();
1765
1766                if let Err(terr) =
1767                    self.eq_types(literal_ty, normalized_ty, locations, ConstraintCategory::Boring)
1768                {
1769                    span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
1770                }
1771            } else if let Const::Ty(_, ct) = constant.const_
1772                && let ty::ConstKind::Param(p) = ct.kind()
1773            {
1774                let body_def_id = self.universal_regions.defining_ty.def_id();
1775                let const_param = tcx.generics_of(body_def_id).const_param(p, tcx);
1776                self.ascribe_user_type(
1777                    constant.const_.ty(),
1778                    ty::UserType::new(ty::UserTypeKind::TypeOf(
1779                        const_param.def_id,
1780                        UserArgs {
1781                            args: self.universal_regions.defining_ty.args(),
1782                            user_self_ty: None,
1783                        },
1784                    )),
1785                    locations.span(self.body),
1786                );
1787            }
1788
1789            if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() {
1790                let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
1791                self.normalize_and_prove_instantiated_predicates(
1792                    def_id,
1793                    instantiated_predicates,
1794                    locations,
1795                );
1796
1797                assert_eq!(tcx.trait_impl_of_assoc(def_id), None);
1798                self.prove_predicates(
1799                    args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())),
1800                    locations,
1801                    ConstraintCategory::Boring,
1802                );
1803            }
1804        }
1805    }
1806
1807    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
1808        self.super_place(place, context, location);
1809        let tcx = self.tcx();
1810        let place_ty = place.ty(self.body, tcx);
1811        if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
1812            let trait_ref = ty::TraitRef::new(
1813                tcx,
1814                tcx.require_lang_item(LangItem::Copy, self.last_span),
1815                [place_ty.ty],
1816            );
1817
1818            // To have a `Copy` operand, the type `T` of the
1819            // value must be `Copy`. Note that we prove that `T: Copy`,
1820            // rather than using the `is_copy_modulo_regions`
1821            // test. This is important because
1822            // `is_copy_modulo_regions` ignores the resulting region
1823            // obligations and assumes they pass. This can result in
1824            // bounds from `Copy` impls being unsoundly ignored (e.g.,
1825            // #29149). Note that we decide to use `Copy` before knowing
1826            // whether the bounds fully apply: in effect, the rule is
1827            // that if a value of some type could implement `Copy`, then
1828            // it must.
1829            self.prove_trait_ref(trait_ref, location.to_locations(), ConstraintCategory::CopyBound);
1830        }
1831    }
1832
1833    fn visit_projection_elem(
1834        &mut self,
1835        place: PlaceRef<'tcx>,
1836        elem: PlaceElem<'tcx>,
1837        context: PlaceContext,
1838        location: Location,
1839    ) {
1840        let tcx = self.tcx();
1841        let base_ty = place.ty(self.body(), tcx);
1842        match elem {
1843            // All these projections don't add any constraints, so there's nothing to
1844            // do here. We check their invariants in the MIR validator after all.
1845            ProjectionElem::Deref
1846            | ProjectionElem::Index(_)
1847            | ProjectionElem::ConstantIndex { .. }
1848            | ProjectionElem::Subslice { .. }
1849            | ProjectionElem::Downcast(..) => {}
1850            ProjectionElem::Field(field, fty) => {
1851                let fty = self.normalize(fty, location);
1852                let ty = PlaceTy::field_ty(tcx, base_ty.ty, base_ty.variant_index, field);
1853                let ty = self.normalize(ty, location);
1854                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:1854",
                        "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(1854u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                        ::tracing_core::field::FieldSet::new(&["fty", "ty"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&fty) as
                                            &dyn Value)),
                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&ty) as
                                            &dyn Value))])
            });
    } else { ; }
};debug!(?fty, ?ty);
1855
1856                if let Err(terr) = self.relate_types(
1857                    ty,
1858                    context.ambient_variance(),
1859                    fty,
1860                    location.to_locations(),
1861                    ConstraintCategory::Boring,
1862                ) {
1863                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), place,
                        format_args!("bad field access ({0:?}: {1:?}): {2:?}", ty,
                            fty, terr)))
            }))
};span_mirbug!(self, place, "bad field access ({:?}: {:?}): {:?}", ty, fty, terr);
1864                }
1865            }
1866            ProjectionElem::OpaqueCast(ty) => {
1867                let ty = self.normalize(ty, location);
1868                self.relate_types(
1869                    ty,
1870                    context.ambient_variance(),
1871                    base_ty.ty,
1872                    location.to_locations(),
1873                    ConstraintCategory::TypeAnnotation(AnnotationSource::OpaqueCast),
1874                )
1875                .unwrap();
1876            }
1877            ProjectionElem::UnwrapUnsafeBinder(ty) => {
1878                let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else {
1879                    ::core::panicking::panic("internal error: entered unreachable code");unreachable!();
1880                };
1881                let found_ty = self.infcx.instantiate_binder_with_fresh_vars(
1882                    self.body.source_info(location).span,
1883                    BoundRegionConversionTime::HigherRankedType,
1884                    binder_ty.into(),
1885                );
1886                self.relate_types(
1887                    ty,
1888                    context.ambient_variance(),
1889                    found_ty,
1890                    location.to_locations(),
1891                    ConstraintCategory::Boring,
1892                )
1893                .unwrap();
1894            }
1895        }
1896    }
1897}
1898
1899impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1900    fn check_call_dest(
1901        &mut self,
1902        term: &Terminator<'tcx>,
1903        sig: &ty::FnSig<'tcx>,
1904        destination: Place<'tcx>,
1905        is_diverging: bool,
1906        term_location: Location,
1907    ) {
1908        let tcx = self.tcx();
1909        if is_diverging {
1910            // The signature in this call can reference region variables,
1911            // so erase them before calling a query.
1912            let output_ty = self.tcx().erase_and_anonymize_regions(sig.output());
1913            if !output_ty
1914                .is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.infcx.param_env))
1915            {
1916                {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), term,
                        format_args!("call to non-diverging function {0:?} w/o dest",
                            sig)))
            }))
};span_mirbug!(self, term, "call to non-diverging function {:?} w/o dest", sig);
1917            }
1918        } else {
1919            let dest_ty = destination.ty(self.body, tcx).ty;
1920            let dest_ty = self.normalize(dest_ty, term_location);
1921            let category = match destination.as_local() {
1922                Some(RETURN_PLACE) => {
1923                    if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) =
1924                        self.universal_regions.defining_ty
1925                    {
1926                        if tcx.is_static(def_id) {
1927                            ConstraintCategory::UseAsStatic
1928                        } else {
1929                            ConstraintCategory::UseAsConst
1930                        }
1931                    } else {
1932                        ConstraintCategory::Return(ReturnConstraint::Normal)
1933                    }
1934                }
1935                Some(l) if !self.body.local_decls[l].is_user_variable() => {
1936                    ConstraintCategory::Boring
1937                }
1938                // The return type of a call is interesting for diagnostics.
1939                _ => ConstraintCategory::Assignment,
1940            };
1941
1942            let locations = term_location.to_locations();
1943
1944            if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) {
1945                {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), term,
                        format_args!("call dest mismatch ({0:?} <- {1:?}): {2:?}",
                            dest_ty, sig.output(), terr)))
            }))
};span_mirbug!(
1946                    self,
1947                    term,
1948                    "call dest mismatch ({:?} <- {:?}): {:?}",
1949                    dest_ty,
1950                    sig.output(),
1951                    terr
1952                );
1953            }
1954
1955            // When `unsized_fn_params` is not enabled,
1956            // this check is done at `visit_local_decl`.
1957            if self.tcx().features().unsized_fn_params() {
1958                let span = term.source_info.span;
1959                self.ensure_place_sized(dest_ty, span);
1960            }
1961        }
1962    }
1963
1964    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("check_call_inputs",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1964u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["sig", "args"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sig)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&args)
                                                            as &dyn 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 args.len() < sig.inputs().len() ||
                    (args.len() > sig.inputs().len() && !sig.c_variadic) {
                {
                    crate::type_check::mirbug(self.tcx(), self.last_span,
                        ::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                        self.body().source.def_id(), term,
                                        format_args!("call to {0:?} with wrong # of args", sig)))
                            }))
                };
            }
            let func_ty = func.ty(self.body, self.infcx.tcx);
            if let ty::FnDef(def_id, _) = *func_ty.kind() {
                if let Some(name @
                        (sym::simd_shuffle | sym::simd_insert | sym::simd_extract))
                        = self.tcx().intrinsic(def_id).map(|i| i.name) {
                    let idx = match name { sym::simd_shuffle => 2, _ => 1, };
                    if !#[allow(non_exhaustive_omitted_patterns)] match args[idx]
                                {
                                Spanned { node: Operand::Constant(_), .. } => true,
                                _ => false,
                            } {
                        self.tcx().dcx().emit_err(SimdIntrinsicArgConst {
                                span: term.source_info.span,
                                arg: idx + 1,
                                intrinsic: name.to_string(),
                            });
                    }
                }
            }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:1999",
                                    "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1999u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                                    ::tracing_core::field::FieldSet::new(&["func_ty"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&func_ty) as
                                                        &dyn Value))])
                        });
                } else { ; }
            };
            for (n, (fn_arg, op_arg)) in
                iter::zip(sig.inputs(), args).enumerate() {
                let op_arg_ty = op_arg.node.ty(self.body, self.tcx());
                let op_arg_ty = self.normalize(op_arg_ty, term_location);
                let category =
                    if call_source.from_hir_call() {
                        ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_and_anonymize_regions(func_ty)))
                    } else { ConstraintCategory::Boring };
                if let Err(terr) =
                        self.sub_types(op_arg_ty, *fn_arg,
                            term_location.to_locations(), category) {
                    {
                        crate::type_check::mirbug(self.tcx(), self.last_span,
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                                            self.body().source.def_id(), term,
                                            format_args!("bad arg #{0:?} ({1:?} <- {2:?}): {3:?}", n,
                                                fn_arg, op_arg_ty, terr)))
                                }))
                    };
                }
            }
        }
    }
}#[instrument(level = "debug", skip(self, term, func, term_location, call_source))]
1965    fn check_call_inputs(
1966        &mut self,
1967        term: &Terminator<'tcx>,
1968        func: &Operand<'tcx>,
1969        sig: &ty::FnSig<'tcx>,
1970        args: &[Spanned<Operand<'tcx>>],
1971        term_location: Location,
1972        call_source: CallSource,
1973    ) {
1974        if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) {
1975            span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
1976        }
1977
1978        let func_ty = func.ty(self.body, self.infcx.tcx);
1979        if let ty::FnDef(def_id, _) = *func_ty.kind() {
1980            // Some of the SIMD intrinsics are special: they need a particular argument to be a
1981            // constant. (Eventually this should use const-generics, but those are not up for the
1982            // task yet: https://github.com/rust-lang/rust/issues/85229.)
1983            if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) =
1984                self.tcx().intrinsic(def_id).map(|i| i.name)
1985            {
1986                let idx = match name {
1987                    sym::simd_shuffle => 2,
1988                    _ => 1,
1989                };
1990                if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) {
1991                    self.tcx().dcx().emit_err(SimdIntrinsicArgConst {
1992                        span: term.source_info.span,
1993                        arg: idx + 1,
1994                        intrinsic: name.to_string(),
1995                    });
1996                }
1997            }
1998        }
1999        debug!(?func_ty);
2000
2001        for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() {
2002            let op_arg_ty = op_arg.node.ty(self.body, self.tcx());
2003
2004            let op_arg_ty = self.normalize(op_arg_ty, term_location);
2005            let category = if call_source.from_hir_call() {
2006                ConstraintCategory::CallArgument(Some(
2007                    self.infcx.tcx.erase_and_anonymize_regions(func_ty),
2008                ))
2009            } else {
2010                ConstraintCategory::Boring
2011            };
2012            if let Err(terr) =
2013                self.sub_types(op_arg_ty, *fn_arg, term_location.to_locations(), category)
2014            {
2015                span_mirbug!(
2016                    self,
2017                    term,
2018                    "bad arg #{:?} ({:?} <- {:?}): {:?}",
2019                    n,
2020                    fn_arg,
2021                    op_arg_ty,
2022                    terr
2023                );
2024            }
2025        }
2026    }
2027
2028    fn check_iscleanup(&mut self, block_data: &BasicBlockData<'tcx>) {
2029        let is_cleanup = block_data.is_cleanup;
2030        match block_data.terminator().kind {
2031            TerminatorKind::Goto { target } => {
2032                self.assert_iscleanup(block_data, target, is_cleanup)
2033            }
2034            TerminatorKind::SwitchInt { ref targets, .. } => {
2035                for target in targets.all_targets() {
2036                    self.assert_iscleanup(block_data, *target, is_cleanup);
2037                }
2038            }
2039            TerminatorKind::UnwindResume => {
2040                if !is_cleanup {
2041                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), block_data,
                        format_args!("resume on non-cleanup block!")))
            }))
}span_mirbug!(self, block_data, "resume on non-cleanup block!")
2042                }
2043            }
2044            TerminatorKind::UnwindTerminate(_) => {
2045                if !is_cleanup {
2046                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), block_data,
                        format_args!("terminate on non-cleanup block!")))
            }))
}span_mirbug!(self, block_data, "terminate on non-cleanup block!")
2047                }
2048            }
2049            TerminatorKind::Return => {
2050                if is_cleanup {
2051                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), block_data,
                        format_args!("return on cleanup block")))
            }))
}span_mirbug!(self, block_data, "return on cleanup block")
2052                }
2053            }
2054            TerminatorKind::TailCall { .. } => {
2055                if is_cleanup {
2056                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), block_data,
                        format_args!("tailcall on cleanup block")))
            }))
}span_mirbug!(self, block_data, "tailcall on cleanup block")
2057                }
2058            }
2059            TerminatorKind::CoroutineDrop { .. } => {
2060                if is_cleanup {
2061                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), block_data,
                        format_args!("coroutine_drop in cleanup block")))
            }))
}span_mirbug!(self, block_data, "coroutine_drop in cleanup block")
2062                }
2063            }
2064            TerminatorKind::Yield { resume, drop, .. } => {
2065                if is_cleanup {
2066                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), block_data,
                        format_args!("yield in cleanup block")))
            }))
}span_mirbug!(self, block_data, "yield in cleanup block")
2067                }
2068                self.assert_iscleanup(block_data, resume, is_cleanup);
2069                if let Some(drop) = drop {
2070                    self.assert_iscleanup(block_data, drop, is_cleanup);
2071                }
2072            }
2073            TerminatorKind::Unreachable => {}
2074            TerminatorKind::Drop { target, unwind, drop, .. } => {
2075                self.assert_iscleanup(block_data, target, is_cleanup);
2076                self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
2077                if let Some(drop) = drop {
2078                    self.assert_iscleanup(block_data, drop, is_cleanup);
2079                }
2080            }
2081            TerminatorKind::Assert { target, unwind, .. } => {
2082                self.assert_iscleanup(block_data, target, is_cleanup);
2083                self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
2084            }
2085            TerminatorKind::Call { ref target, unwind, .. } => {
2086                if let &Some(target) = target {
2087                    self.assert_iscleanup(block_data, target, is_cleanup);
2088                }
2089                self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
2090            }
2091            TerminatorKind::FalseEdge { real_target, imaginary_target } => {
2092                self.assert_iscleanup(block_data, real_target, is_cleanup);
2093                self.assert_iscleanup(block_data, imaginary_target, is_cleanup);
2094            }
2095            TerminatorKind::FalseUnwind { real_target, unwind } => {
2096                self.assert_iscleanup(block_data, real_target, is_cleanup);
2097                self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
2098            }
2099            TerminatorKind::InlineAsm { ref targets, unwind, .. } => {
2100                for &target in targets {
2101                    self.assert_iscleanup(block_data, target, is_cleanup);
2102                }
2103                self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
2104            }
2105        }
2106    }
2107
2108    fn assert_iscleanup(&mut self, ctxt: &dyn fmt::Debug, bb: BasicBlock, iscleanuppad: bool) {
2109        if self.body[bb].is_cleanup != iscleanuppad {
2110            {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), ctxt,
                        format_args!("cleanuppad mismatch: {0:?} should be {1:?}",
                            bb, iscleanuppad)))
            }))
};span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad);
2111        }
2112    }
2113
2114    fn assert_iscleanup_unwind(
2115        &mut self,
2116        ctxt: &dyn fmt::Debug,
2117        unwind: UnwindAction,
2118        is_cleanup: bool,
2119    ) {
2120        match unwind {
2121            UnwindAction::Cleanup(unwind) => {
2122                if is_cleanup {
2123                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), ctxt,
                        format_args!("unwind on cleanup block")))
            }))
}span_mirbug!(self, ctxt, "unwind on cleanup block")
2124                }
2125                self.assert_iscleanup(ctxt, unwind, true);
2126            }
2127            UnwindAction::Continue => {
2128                if is_cleanup {
2129                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), ctxt,
                        format_args!("unwind on cleanup block")))
            }))
}span_mirbug!(self, ctxt, "unwind on cleanup block")
2130                }
2131            }
2132            UnwindAction::Unreachable | UnwindAction::Terminate(_) => (),
2133        }
2134    }
2135
2136    fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
2137        let tcx = self.tcx();
2138
2139        // Erase the regions from `ty` to get a global type. The
2140        // `Sized` bound in no way depends on precise regions, so this
2141        // shouldn't affect `is_sized`.
2142        let erased_ty = tcx.erase_and_anonymize_regions(ty);
2143        // FIXME(#132279): Using `Ty::is_sized` causes us to incorrectly handle opaques here.
2144        if !erased_ty.is_sized(tcx, self.infcx.typing_env(self.infcx.param_env)) {
2145            // in current MIR construction, all non-control-flow rvalue
2146            // expressions evaluate through `as_temp` or `into` a return
2147            // slot or local, so to find all unsized rvalues it is enough
2148            // to check all temps, return slots and locals.
2149            if self.reported_errors.replace((ty, span)).is_none() {
2150                // While this is located in `nll::typeck` this error is not
2151                // an NLL error, it's a required check to prevent creation
2152                // of unsized rvalues in a call expression.
2153                self.tcx().dcx().emit_err(MoveUnsized { ty, span });
2154            }
2155        }
2156    }
2157
2158    fn aggregate_field_ty(
2159        &mut self,
2160        ak: &AggregateKind<'tcx>,
2161        field_index: FieldIdx,
2162        location: Location,
2163    ) -> Result<Ty<'tcx>, FieldAccessError> {
2164        let tcx = self.tcx();
2165
2166        match *ak {
2167            AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => {
2168                let def = tcx.adt_def(adt_did);
2169                let variant = &def.variant(variant_index);
2170                let adj_field_index = active_field_index.unwrap_or(field_index);
2171                if let Some(field) = variant.fields.get(adj_field_index) {
2172                    Ok(self.normalize(field.ty(tcx, args), location))
2173                } else {
2174                    Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
2175                }
2176            }
2177            AggregateKind::Closure(_, args) => {
2178                match args.as_closure().upvar_tys().get(field_index.as_usize()) {
2179                    Some(ty) => Ok(*ty),
2180                    None => Err(FieldAccessError::OutOfRange {
2181                        field_count: args.as_closure().upvar_tys().len(),
2182                    }),
2183                }
2184            }
2185            AggregateKind::Coroutine(_, args) => {
2186                // It doesn't make sense to look at a field beyond the prefix;
2187                // these require a variant index, and are not initialized in
2188                // aggregate rvalues.
2189                match args.as_coroutine().prefix_tys().get(field_index.as_usize()) {
2190                    Some(ty) => Ok(*ty),
2191                    None => Err(FieldAccessError::OutOfRange {
2192                        field_count: args.as_coroutine().prefix_tys().len(),
2193                    }),
2194                }
2195            }
2196            AggregateKind::CoroutineClosure(_, args) => {
2197                match args.as_coroutine_closure().upvar_tys().get(field_index.as_usize()) {
2198                    Some(ty) => Ok(*ty),
2199                    None => Err(FieldAccessError::OutOfRange {
2200                        field_count: args.as_coroutine_closure().upvar_tys().len(),
2201                    }),
2202                }
2203            }
2204            AggregateKind::Array(ty) => Ok(ty),
2205            AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
2206                {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("This should have been covered in check_rvalues")));
};unreachable!("This should have been covered in check_rvalues");
2207            }
2208        }
2209    }
2210
2211    /// If this rvalue supports a user-given type annotation, then
2212    /// extract and return it. This represents the final type of the
2213    /// rvalue and will be unified with the inferred type.
2214    fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotationIndex> {
2215        match rvalue {
2216            Rvalue::Use(_)
2217            | Rvalue::ThreadLocalRef(_)
2218            | Rvalue::Repeat(..)
2219            | Rvalue::Ref(..)
2220            | Rvalue::RawPtr(..)
2221            | Rvalue::Cast(..)
2222            | Rvalue::BinaryOp(..)
2223            | Rvalue::CopyForDeref(..)
2224            | Rvalue::UnaryOp(..)
2225            | Rvalue::Discriminant(..)
2226            | Rvalue::WrapUnsafeBinder(..) => None,
2227
2228            Rvalue::Aggregate(aggregate, _) => match **aggregate {
2229                AggregateKind::Adt(_, _, _, user_ty, _) => user_ty,
2230                AggregateKind::Array(_) => None,
2231                AggregateKind::Tuple => None,
2232                AggregateKind::Closure(_, _) => None,
2233                AggregateKind::Coroutine(_, _) => None,
2234                AggregateKind::CoroutineClosure(_, _) => None,
2235                AggregateKind::RawPtr(_, _) => None,
2236            },
2237        }
2238    }
2239
2240    fn check_aggregate_rvalue(
2241        &mut self,
2242        rvalue: &Rvalue<'tcx>,
2243        aggregate_kind: &AggregateKind<'tcx>,
2244        operands: &IndexSlice<FieldIdx, Operand<'tcx>>,
2245        location: Location,
2246    ) {
2247        let tcx = self.tcx();
2248
2249        self.prove_aggregate_predicates(aggregate_kind, location);
2250
2251        if *aggregate_kind == AggregateKind::Tuple {
2252            // tuple rvalue field type is always the type of the op. Nothing to check here.
2253            return;
2254        }
2255
2256        if let AggregateKind::RawPtr(..) = aggregate_kind {
2257            ::rustc_middle::util::bug::bug_fmt(format_args!("RawPtr should only be in runtime MIR"));bug!("RawPtr should only be in runtime MIR");
2258        }
2259
2260        for (i, operand) in operands.iter_enumerated() {
2261            let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
2262                Ok(field_ty) => field_ty,
2263                Err(FieldAccessError::OutOfRange { field_count }) => {
2264                    {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), rvalue,
                        format_args!("accessed field #{0} but variant only has {1}",
                            i.as_u32(), field_count)))
            }))
};span_mirbug!(
2265                        self,
2266                        rvalue,
2267                        "accessed field #{} but variant only has {}",
2268                        i.as_u32(),
2269                        field_count,
2270                    );
2271                    continue;
2272                }
2273            };
2274            let operand_ty = operand.ty(self.body, tcx);
2275            let operand_ty = self.normalize(operand_ty, location);
2276
2277            if let Err(terr) = self.sub_types(
2278                operand_ty,
2279                field_ty,
2280                location.to_locations(),
2281                ConstraintCategory::Boring,
2282            ) {
2283                {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), rvalue,
                        format_args!("{0:?} is not a subtype of {1:?}: {2:?}",
                            operand_ty, field_ty, terr)))
            }))
};span_mirbug!(
2284                    self,
2285                    rvalue,
2286                    "{:?} is not a subtype of {:?}: {:?}",
2287                    operand_ty,
2288                    field_ty,
2289                    terr
2290                );
2291            }
2292        }
2293    }
2294
2295    /// Adds the constraints that arise from a borrow expression `&'a P` at the location `L`.
2296    ///
2297    /// # Parameters
2298    ///
2299    /// - `location`: the location `L` where the borrow expression occurs
2300    /// - `borrow_region`: the region `'a` associated with the borrow
2301    /// - `borrowed_place`: the place `P` being borrowed
2302    fn add_reborrow_constraint(
2303        &mut self,
2304        location: Location,
2305        borrow_region: ty::Region<'tcx>,
2306        borrowed_place: &Place<'tcx>,
2307    ) {
2308        // These constraints are only meaningful during borrowck:
2309        let Self { borrow_set, location_table, polonius_facts, constraints, .. } = self;
2310
2311        // In Polonius mode, we also push a `loan_issued_at` fact
2312        // linking the loan to the region (in some cases, though,
2313        // there is no loan associated with this borrow expression --
2314        // that occurs when we are borrowing an unsafe place, for
2315        // example).
2316        if let Some(polonius_facts) = polonius_facts {
2317            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
2318            if let Some(borrow_index) = borrow_set.get_index_of(&location) {
2319                let region_vid = borrow_region.as_var();
2320                polonius_facts.loan_issued_at.push((
2321                    region_vid.into(),
2322                    borrow_index,
2323                    location_table.mid_index(location),
2324                ));
2325            }
2326        }
2327
2328        // If we are reborrowing the referent of another reference, we
2329        // need to add outlives relationships. In a case like `&mut
2330        // *p`, where the `p` has type `&'b mut Foo`, for example, we
2331        // need to ensure that `'b: 'a`.
2332
2333        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:2333",
                        "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(2333u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("add_reborrow_constraint({0:?}, {1:?}, {2:?})",
                                                    location, borrow_region, borrowed_place) as &dyn Value))])
            });
    } else { ; }
};debug!(
2334            "add_reborrow_constraint({:?}, {:?}, {:?})",
2335            location, borrow_region, borrowed_place
2336        );
2337
2338        let tcx = self.infcx.tcx;
2339        let def = self.body.source.def_id().expect_local();
2340        let upvars = tcx.closure_captures(def);
2341        let field =
2342            path_utils::is_upvar_field_projection(tcx, upvars, borrowed_place.as_ref(), self.body);
2343        let category = if let Some(field) = field {
2344            ConstraintCategory::ClosureUpvar(field)
2345        } else {
2346            ConstraintCategory::Boring
2347        };
2348
2349        for (base, elem) in borrowed_place.as_ref().iter_projections().rev() {
2350            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:2350",
                        "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(2350u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("add_reborrow_constraint - iteration {0:?}",
                                                    elem) as &dyn Value))])
            });
    } else { ; }
};debug!("add_reborrow_constraint - iteration {:?}", elem);
2351
2352            match elem {
2353                ProjectionElem::Deref => {
2354                    let base_ty = base.ty(self.body, tcx).ty;
2355
2356                    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:2356",
                        "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(2356u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("add_reborrow_constraint - base_ty = {0:?}",
                                                    base_ty) as &dyn Value))])
            });
    } else { ; }
};debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
2357                    match base_ty.kind() {
2358                        ty::Ref(ref_region, _, mutbl) => {
2359                            constraints.outlives_constraints.push(OutlivesConstraint {
2360                                sup: ref_region.as_var(),
2361                                sub: borrow_region.as_var(),
2362                                locations: location.to_locations(),
2363                                span: location.to_locations().span(self.body),
2364                                category,
2365                                variance_info: ty::VarianceDiagInfo::default(),
2366                                from_closure: false,
2367                            });
2368
2369                            match mutbl {
2370                                hir::Mutability::Not => {
2371                                    // Immutable reference. We don't need the base
2372                                    // to be valid for the entire lifetime of
2373                                    // the borrow.
2374                                    break;
2375                                }
2376                                hir::Mutability::Mut => {
2377                                    // Mutable reference. We *do* need the base
2378                                    // to be valid, because after the base becomes
2379                                    // invalid, someone else can use our mutable deref.
2380
2381                                    // This is in order to make the following function
2382                                    // illegal:
2383                                    // ```
2384                                    // fn unsafe_deref<'a, 'b>(x: &'a &'b mut T) -> &'b mut T {
2385                                    //     &mut *x
2386                                    // }
2387                                    // ```
2388                                    //
2389                                    // As otherwise you could clone `&mut T` using the
2390                                    // following function:
2391                                    // ```
2392                                    // fn bad(x: &mut T) -> (&mut T, &mut T) {
2393                                    //     let my_clone = unsafe_deref(&'a x);
2394                                    //     ENDREGION 'a;
2395                                    //     (my_clone, x)
2396                                    // }
2397                                    // ```
2398                                }
2399                            }
2400                        }
2401                        ty::RawPtr(..) => {
2402                            // deref of raw pointer, guaranteed to be valid
2403                            break;
2404                        }
2405                        ty::Adt(def, _) if def.is_box() => {
2406                            // deref of `Box`, need the base to be valid - propagate
2407                        }
2408                        _ => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected deref ty {0:?} in {1:?}",
        base_ty, borrowed_place))bug!("unexpected deref ty {:?} in {:?}", base_ty, borrowed_place),
2409                    }
2410                }
2411                ProjectionElem::Field(..)
2412                | ProjectionElem::Downcast(..)
2413                | ProjectionElem::OpaqueCast(..)
2414                | ProjectionElem::Index(..)
2415                | ProjectionElem::ConstantIndex { .. }
2416                | ProjectionElem::Subslice { .. }
2417                | ProjectionElem::UnwrapUnsafeBinder(_) => {
2418                    // other field access
2419                }
2420            }
2421        }
2422    }
2423
2424    fn prove_aggregate_predicates(
2425        &mut self,
2426        aggregate_kind: &AggregateKind<'tcx>,
2427        location: Location,
2428    ) {
2429        let tcx = self.tcx();
2430
2431        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/type_check/mod.rs:2431",
                        "rustc_borrowck::type_check", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/type_check/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(2431u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::type_check"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("prove_aggregate_predicates(aggregate_kind={0:?}, location={1:?})",
                                                    aggregate_kind, location) as &dyn Value))])
            });
    } else { ; }
};debug!(
2432            "prove_aggregate_predicates(aggregate_kind={:?}, location={:?})",
2433            aggregate_kind, location
2434        );
2435
2436        let (def_id, instantiated_predicates) = match *aggregate_kind {
2437            AggregateKind::Adt(adt_did, _, args, _, _) => {
2438                (adt_did, tcx.predicates_of(adt_did).instantiate(tcx, args))
2439            }
2440
2441            // For closures, we have some **extra requirements** we
2442            // have to check. In particular, in their upvars and
2443            // signatures, closures often reference various regions
2444            // from the surrounding function -- we call those the
2445            // closure's free regions. When we borrow-check (and hence
2446            // region-check) closures, we may find that the closure
2447            // requires certain relationships between those free
2448            // regions. However, because those free regions refer to
2449            // portions of the CFG of their caller, the closure is not
2450            // in a position to verify those relationships. In that
2451            // case, the requirements get "propagated" to us, and so
2452            // we have to solve them here where we instantiate the
2453            // closure.
2454            //
2455            // Despite the opacity of the previous paragraph, this is
2456            // actually relatively easy to understand in terms of the
2457            // desugaring. A closure gets desugared to a struct, and
2458            // these extra requirements are basically like where
2459            // clauses on the struct.
2460            AggregateKind::Closure(def_id, args)
2461            | AggregateKind::CoroutineClosure(def_id, args)
2462            | AggregateKind::Coroutine(def_id, args) => {
2463                (def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
2464            }
2465
2466            AggregateKind::Array(_) | AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
2467                (CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty())
2468            }
2469        };
2470
2471        self.normalize_and_prove_instantiated_predicates(
2472            def_id,
2473            instantiated_predicates,
2474            location.to_locations(),
2475        );
2476    }
2477
2478    fn prove_closure_bounds(
2479        &mut self,
2480        tcx: TyCtxt<'tcx>,
2481        def_id: LocalDefId,
2482        args: GenericArgsRef<'tcx>,
2483        location: Location,
2484    ) -> ty::InstantiatedPredicates<'tcx> {
2485        let root_def_id = self.root_cx.root_def_id();
2486        // We will have to handle propagated closure requirements for this closure,
2487        // but need to defer this until the nested body has been fully borrow checked.
2488        self.deferred_closure_requirements.push((def_id, args, location.to_locations()));
2489
2490        // Equate closure args to regions inherited from `root_def_id`. Fixes #98589.
2491        let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, root_def_id);
2492
2493        let parent_args = match tcx.def_kind(def_id) {
2494            // We don't want to dispatch on 3 different kind of closures here, so take
2495            // advantage of the fact that the `parent_args` is the same length as the
2496            // `typeck_root_args`.
2497            DefKind::Closure => {
2498                // FIXME(async_closures): It may be useful to add a debug assert here
2499                // to actually call `type_of` and check the `parent_args` are the same
2500                // length as the `typeck_root_args`.
2501                &args[..typeck_root_args.len()]
2502            }
2503            DefKind::InlineConst => args.as_inline_const().parent_args(),
2504            other => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected item {0:?}",
        other))bug!("unexpected item {:?}", other),
2505        };
2506        let parent_args = tcx.mk_args(parent_args);
2507
2508        match (&typeck_root_args.len(), &parent_args.len()) {
    (left_val, right_val) => {
        if !(*left_val == *right_val) {
            let kind = ::core::panicking::AssertKind::Eq;
            ::core::panicking::assert_failed(kind, &*left_val, &*right_val,
                ::core::option::Option::None);
        }
    }
};assert_eq!(typeck_root_args.len(), parent_args.len());
2509        if let Err(_) = self.eq_args(
2510            typeck_root_args,
2511            parent_args,
2512            location.to_locations(),
2513            ConstraintCategory::BoringNoLocation,
2514        ) {
2515            {
    crate::type_check::mirbug(self.tcx(), self.last_span,
        ::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("broken MIR in {0:?} ({1:?}): {2}",
                        self.body().source.def_id(), def_id,
                        format_args!("could not relate closure to parent {0:?} != {1:?}",
                            typeck_root_args, parent_args)))
            }))
};span_mirbug!(
2516                self,
2517                def_id,
2518                "could not relate closure to parent {:?} != {:?}",
2519                typeck_root_args,
2520                parent_args
2521            );
2522        }
2523
2524        tcx.predicates_of(def_id).instantiate(tcx, args)
2525    }
2526}
2527
2528trait NormalizeLocation: fmt::Debug + Copy {
2529    fn to_locations(self) -> Locations;
2530}
2531
2532impl NormalizeLocation for Locations {
2533    fn to_locations(self) -> Locations {
2534        self
2535    }
2536}
2537
2538impl NormalizeLocation for Location {
2539    fn to_locations(self) -> Locations {
2540        Locations::Single(self)
2541    }
2542}
2543
2544/// Runs `infcx.instantiate_opaque_types`. Unlike other `TypeOp`s,
2545/// this is not canonicalized - it directly affects the main `InferCtxt`
2546/// that we use during MIR borrowchecking.
2547#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InstantiateOpaqueType<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "InstantiateOpaqueType", "base_universe", &self.base_universe,
            "region_constraints", &self.region_constraints, "obligations",
            &&self.obligations)
    }
}Debug)]
2548pub(super) struct InstantiateOpaqueType<'tcx> {
2549    pub base_universe: Option<ty::UniverseIndex>,
2550    pub region_constraints: Option<RegionConstraintData<'tcx>>,
2551    pub obligations: PredicateObligations<'tcx>,
2552}
2553
2554impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
2555    type Output = ();
2556    /// We use this type itself to store the information used
2557    /// when reporting errors. Since this is not a query, we don't
2558    /// re-run anything during error reporting - we just use the information
2559    /// we saved to help extract an error from the already-existing region
2560    /// constraints in our `InferCtxt`
2561    type ErrorInfo = InstantiateOpaqueType<'tcx>;
2562
2563    fn fully_perform(
2564        mut self,
2565        infcx: &InferCtxt<'tcx>,
2566        root_def_id: LocalDefId,
2567        span: Span,
2568    ) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
2569        let (mut output, region_constraints) =
2570            scrape_region_constraints(infcx, root_def_id, "InstantiateOpaqueType", span, |ocx| {
2571                ocx.register_obligations(self.obligations.clone());
2572                Ok(())
2573            })?;
2574        self.region_constraints = Some(region_constraints);
2575        output.error_info = Some(self);
2576        Ok(output)
2577    }
2578}