fn add_reborrow_constraint(
        &mut self,
        body: &Body<'tcx>,
        location: Location,
        borrow_region: ty::Region<'tcx>,
        borrowed_place: &Place<'tcx>,
    ) {
        // These constraints are only meaningful during borrowck:
        let BorrowCheckContext { borrow_set, location_table, all_facts, constraints, .. } =
            self.borrowck_context;

        // In Polonius mode, we also push a `loan_issued_at` fact
        // linking the loan to the region (in some cases, though,
        // there is no loan associated with this borrow expression --
        // that occurs when we are borrowing an unsafe place, for
        // example).
        if let Some(all_facts) = all_facts {
            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
            if let Some(borrow_index) = borrow_set.get_index_of(&location) {
                let region_vid = borrow_region.to_region_vid();
                all_facts.loan_issued_at.push((
                    region_vid,
                    borrow_index,
                    location_table.mid_index(location),
                ));
            }
        }

        // If we are reborrowing the referent of another reference, we
        // need to add outlives relationships. In a case like `&mut
        // *p`, where the `p` has type `&'b mut Foo`, for example, we
        // need to ensure that `'b: 'a`.

        debug!(
            "add_reborrow_constraint({:?}, {:?}, {:?})",
            location, borrow_region, borrowed_place
        );

        let mut cursor = borrowed_place.projection.as_ref();
        let tcx = self.infcx.tcx;
        let field = path_utils::is_upvar_field_projection(
            tcx,
            &self.borrowck_context.upvars,
            borrowed_place.as_ref(),
            body,
        );
        let category = if let Some(field) = field {
            ConstraintCategory::ClosureUpvar(field)
        } else {
            ConstraintCategory::Boring
        };

        while let [proj_base @ .., elem] = cursor {
            cursor = proj_base;

            debug!("add_reborrow_constraint - iteration {:?}", elem);

            match elem {
                ProjectionElem::Deref => {
                    let base_ty = Place::ty_from(borrowed_place.local, proj_base, body, tcx).ty;

                    debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
                    match base_ty.kind() {
                        ty::Ref(ref_region, _, mutbl) => {
                            constraints.outlives_constraints.push(OutlivesConstraint {
                                sup: ref_region.to_region_vid(),
                                sub: borrow_region.to_region_vid(),
                                locations: location.to_locations(),
                                category,
                                variance_info: ty::VarianceDiagInfo::default(),
                            });

                            match mutbl {
                                hir::Mutability::Not => {
                                    // Immutable reference. We don't need the base
                                    // to be valid for the entire lifetime of
                                    // the borrow.
                                    break;
                                }
                                hir::Mutability::Mut => {
                                    // Mutable reference. We *do* need the base
                                    // to be valid, because after the base becomes
                                    // invalid, someone else can use our mutable deref.

                                    // This is in order to make the following function
                                    // illegal:
                                    // ```
                                    // fn unsafe_deref<'a, 'b>(x: &'a &'b mut T) -> &'b mut T {
                                    //     &mut *x
                                    // }
                                    // ```
                                    //
                                    // As otherwise you could clone `&mut T` using the
                                    // following function:
                                    // ```
                                    // fn bad(x: &mut T) -> (&mut T, &mut T) {
                                    //     let my_clone = unsafe_deref(&'a x);
                                    //     ENDREGION 'a;
                                    //     (my_clone, x)
                                    // }
                                    // ```
                                }
                            }
                        }
                        ty::RawPtr(..) => {
                            // deref of raw pointer, guaranteed to be valid
                            break;
                        }
                        ty::Adt(def, _) if def.is_box() => {
                            // deref of `Box`, need the base to be valid - propagate
                        }
                        _ => bug!("unexpected deref ty {:?} in {:?}", base_ty, borrowed_place),
                    }
                }
                ProjectionElem::Field(..)
                | ProjectionElem::Downcast(..)
                | ProjectionElem::Index(..)
                | ProjectionElem::ConstantIndex { .. }
                | ProjectionElem::Subslice { .. } => {
                    // other field access
                }
            }
        }
    }
/// Adds the constraints that arise from a borrow expression `&'a P` at the location `L`.
///
/// # Parameters
///
/// - `location`: the location `L` where the borrow expression occurs
/// - `borrow_region`: the region `'a` associated with the borrow
/// - `borrowed_place`: the place `P` being borrowed
Adds the constraints that arise from a borrow expression `&'a P` at the location `L`.
Adds the constraints that arise from a borrow expression ` & ' a P ` at the location ` L ` .
fn add_reborrow_constraint(
        &mut self,
        body: &Body<'tcx>,
        location: Location,
        borrow_region: ty::Region<'tcx>,
        borrowed_place: &Place<'tcx>,
    ) {
        // These constraints are only meaningful during borrowck:
        let BorrowCheckContext { borrow_set, location_table, all_facts, constraints, .. } =
            self.borrowck_context;
        // In Polonius mode, we also push a `loan_issued_at` fact
        // linking the loan to the region (in some cases, though,
        // there is no loan associated with this borrow expression --
        // that occurs when we are borrowing an unsafe place, for
        // example).
        if let Some(all_facts) = all_facts {
            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
            if let Some(borrow_index) = borrow_set.get_index_of(&location) {
                let region_vid = borrow_region.to_region_vid();
                all_facts.loan_issued_at.push((
                    region_vid,
                    borrow_index,
                    location_table.mid_index(location),
                ));
            }
        }
        // If we are reborrowing the referent of another reference, we
        // need to add outlives relationships. In a case like `&mut
        // *p`, where the `p` has type `&'b mut Foo`, for example, we
        // need to ensure that `'b: 'a`.
        debug!(
            "add_reborrow_constraint({:?}, {:?}, {:?})",
            location, borrow_region, borrowed_place
        );
        let mut cursor = borrowed_place.projection.as_ref();
        let tcx = self.infcx.tcx;
        let field = path_utils::is_upvar_field_projection(
            tcx,
            &self.borrowck_context.upvars,
            borrowed_place.as_ref(),
            body,
        );
        let category = if let Some(field) = field {
            ConstraintCategory::ClosureUpvar(field)
        } else {
            ConstraintCategory::Boring
        };
        while let [proj_base @ .., elem] = cursor {
            cursor = proj_base;
            debug!("add_reborrow_constraint - iteration {:?}", elem);
            match elem {
                ProjectionElem::Deref => {
                    let base_ty = Place::ty_from(borrowed_place.local, proj_base, body, tcx).ty;
                    debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
                    match base_ty.kind() {
                        ty::Ref(ref_region, _, mutbl) => {
                            constraints.outlives_constraints.push(OutlivesConstraint {
                                sup: ref_region.to_region_vid(),
                                sub: borrow_region.to_region_vid(),
                                locations: location.to_locations(),
                                category,
                                variance_info: ty::VarianceDiagInfo::default(),
                            });
                            match mutbl {
                                hir::Mutability::Not => {
                                    // Immutable reference. We don't need the base
                                    // to be valid for the entire lifetime of
                                    // the borrow.
                                    break;
                                }
                                hir::Mutability::Mut => {
                                    // Mutable reference. We *do* need the base
                                    // to be valid, because after the base becomes
                                    // invalid, someone else can use our mutable deref.
                                    // This is in order to make the following function
                                    // illegal:
                                    // ```
                                    // fn unsafe_deref<'a, 'b>(x: &'a &'b mut T) -> &'b mut T {
                                    //     &mut *x
                                    // }
                                    // ```
                                    //
                                    // As otherwise you could clone `&mut T` using the
                                    // following function:
                                    // ```
                                    // fn bad(x: &mut T) -> (&mut T, &mut T) {
                                    //     let my_clone = unsafe_deref(&'a x);
                                    //     ENDREGION 'a;
                                    //     (my_clone, x)
                                    // }
                                    // ```
                                }
                            }
                        }
                        ty::RawPtr(..) => {
                            // deref of raw pointer, guaranteed to be valid
                            break;
                        }
                        ty::Adt(def, _) if def.is_box() => {
                            // deref of `Box`, need the base to be valid - propagate
                        }
                        _ => bug!("unexpected deref ty {:?} in {:?}", base_ty, borrowed_place),
                    }
                }
                ProjectionElem::Field(..)
                | ProjectionElem::Downcast(..)
                | ProjectionElem::Index(..)
                | ProjectionElem::ConstantIndex { .. }
                | ProjectionElem::Subslice { .. } => {
                    // other field access
                }
            }
        }
    }
fn add_reborrow_constraint ( & mut self , body : & Body < ' tcx > , location : Location , borrow_region : ty :: Region < ' tcx > , borrowed_place : & Place < ' tcx > , ) { // These constraints are only meaningful during borrowck: let BorrowCheckContext { borrow_set , location_table , all_facts , constraints , .. } = self . borrowck_context ; // In Polonius mode, we also push a `loan_issued_at` fact // linking the loan to the region (in some cases, though, // there is no loan associated with this borrow expression -- // that occurs when we are borrowing an unsafe place, for // example). if let Some ( all_facts ) = all_facts { let _prof_timer = self . infcx . tcx . prof . generic_activity ( " " ) ; if let Some ( borrow_index ) = borrow_set . get_index_of ( & location ) { let region_vid = borrow_region . to_region_vid ( ) ; all_facts . loan_issued_at . push ( ( region_vid , borrow_index , location_table . mid_index ( location ) , ) ) ; } } // If we are reborrowing the referent of another reference, we // need to add outlives relationships. In a case like `&mut // *p`, where the `p` has type `&'b mut Foo`, for example, we // need to ensure that `'b: 'a`. debug ! ( " " location borrow_region borrowed_place ) ; let mut cursor = borrowed_place . projection . as_ref ( ) ; let tcx = self . infcx . tcx ; let field = path_utils :: is_upvar_field_projection ( tcx , & self . borrowck_context . upvars , borrowed_place . as_ref ( ) , body , ) ; let category = if let Some ( field ) = field { ConstraintCategory :: ClosureUpvar ( field ) } else { ConstraintCategory :: Boring } ; while let [ proj_base @ .. , elem ] = cursor { cursor = proj_base ; debug ! ( " " elem ) ; match elem { ProjectionElem :: Deref => { let base_ty = Place :: ty_from ( borrowed_place . local , proj_base , body , tcx ) . ty ; debug ! ( " " base_ty ) ; match base_ty . kind ( ) { ty :: Ref ( ref_region , _ , mutbl ) => { constraints . outlives_constraints . push ( OutlivesConstraint { sup : ref_region . to_region_vid ( ) , sub : borrow_region . to_region_vid ( ) , locations : location . to_locations ( ) , category , variance_info : ty :: VarianceDiagInfo :: default ( ) , } ) ; match mutbl { hir :: Mutability :: Not => { // Immutable reference. We don't need the base // to be valid for the entire lifetime of // the borrow. break ; } hir :: Mutability :: Mut => { // Mutable reference. We *do* need the base // to be valid, because after the base becomes // invalid, someone else can use our mutable deref. // This is in order to make the following function // illegal: // ``` // fn unsafe_deref<'a, 'b>(x: &'a &'b mut T) -> &'b mut T { //     &mut *x // } // ``` // // As otherwise you could clone `&mut T` using the // following function: // ``` // fn bad(x: &mut T) -> (&mut T, &mut T) { //     let my_clone = unsafe_deref(&'a x); //     ENDREGION 'a; //     (my_clone, x) // } // ``` } } } ty :: RawPtr ( .. ) => { // deref of raw pointer, guaranteed to be valid break ; } ty :: Adt ( def , _ ) if def . is_box ( ) => { // deref of `Box`, need the base to be valid - propagate } _ => bug ! ( " " base_ty borrowed_place ) , } } ProjectionElem :: Field ( .. ) | ProjectionElem :: Downcast ( .. ) | ProjectionElem :: Index ( .. ) | ProjectionElem :: ConstantIndex { .. } | ProjectionElem :: Subslice { .. } => { // other field access } } } }
Adds the constraints that arise from a borrow expression `&'a P` at the location `L`.
Adds the constraints that arise from a borrow expression ` & ' a P ` at the location ` L ` .
&mut self
body
&Body<'tcx>
location
Location
the location `L` where the borrow expression occurs
the location ` L ` where the borrow expression occurs
borrow_region
ty::Region<'tcx>
the region `'a` associated with the borrow
the region ` ' a ` associated with the borrow
borrowed_place
&Place<'tcx>
the place `P` being borrowed
the place ` P ` being borrowed