/// Invoked on any auto-dereference that occurs. Checks that if this is a region pointer being
/// dereferenced, the lifetime of the pointer includes the deref expr.
Invoked on any auto-dereference that occurs. Checks that if this is a region pointer being
dereferenced, the lifetime of the pointer includes the deref expr.
Invoked on any auto - dereference that occurs . Checks that if this is a region pointer being dereferenced the lifetime of the pointer includes the deref expr .
fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                                  deref_expr: &hir::Expr,
                                  derefs: usize,
                                  mut derefd_ty: Ty<'tcx>)
{
    debug!("constrain_autoderefs(deref_expr={:?}, derefs={}, derefd_ty={:?})",
           deref_expr,
           derefs,
           derefd_ty);
    let s_deref_expr = rcx.tcx().region_maps.node_extent(deref_expr.id);
    let r_deref_expr = ty::ReScope(s_deref_expr);
    for i in 0..derefs {
        let method_call = MethodCall::autoderef(deref_expr.id, i as u32);
        debug!("constrain_autoderefs: method_call={:?} (of {:?} total)", method_call, derefs);
        let method = rcx.fcx.inh.tables.borrow().method_map.get(&method_call).map(|m| m.clone());
        derefd_ty = match method {
            Some(method) => {
                debug!("constrain_autoderefs: #{} is overloaded, method={:?}",
                       i, method);
                let origin = infer::ParameterOrigin::OverloadedDeref;
                substs_wf_in_scope(rcx, origin, method.substs, deref_expr.span, r_deref_expr);
                // Treat overloaded autoderefs as if an AutoRef adjustment
                // was applied on the base type, as that is always the case.
                let fn_sig = method.ty.fn_sig();
                let fn_sig = // late-bound regions should have been instantiated
                    rcx.tcx().no_late_bound_regions(fn_sig).unwrap();
                let self_ty = fn_sig.inputs[0];
                let (m, r) = match self_ty.sty {
                    ty::TyRef(r, ref m) => (m.mutbl, r),
                    _ => {
                        rcx.tcx().sess.span_bug(
                            deref_expr.span,
                            &format!("bad overloaded deref type {:?}",
                                     method.ty))
                    }
                };
                debug!("constrain_autoderefs: receiver r={:?} m={:?}",
                       r, m);
                {
                    let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx());
                    let self_cmt = ignore_err!(mc.cat_expr_autoderefd(deref_expr, i));
                    debug!("constrain_autoderefs: self_cmt={:?}",
                           self_cmt);
                    link_region(rcx, deref_expr.span, r,
                                ty::BorrowKind::from_mutbl(m), self_cmt);
                }
                // Specialized version of constrain_call.
                type_must_outlive(rcx, infer::CallRcvr(deref_expr.span),
                                  self_ty, r_deref_expr);
                match fn_sig.output {
                    ty::FnConverging(return_type) => {
                        type_must_outlive(rcx, infer::CallReturn(deref_expr.span),
                                          return_type, r_deref_expr);
                        return_type
                    }
                    ty::FnDiverging => unreachable!()
                }
            }
            None => derefd_ty
        };
        if let ty::TyRef(r_ptr, _) =  derefd_ty.sty {
            mk_subregion_due_to_dereference(rcx, deref_expr.span,
                                            r_deref_expr, *r_ptr);
        }
        match derefd_ty.builtin_deref(true, ty::NoPreference) {
            Some(mt) => derefd_ty = mt.ty,
            /* if this type can't be dereferenced, then there's already an error
               in the session saying so. Just bail out for now */
            None => break
        }
    }
}
fn constrain_autoderefs < ' a , ' tcx > ( rcx : & mut Rcx < ' a , ' tcx > , deref_expr : & hir :: Expr , derefs : usize , mut derefd_ty : Ty < ' tcx > ) { debug ! ( " " deref_expr derefs derefd_ty ) ; let s_deref_expr = rcx . tcx ( ) . region_maps . node_extent ( deref_expr . id ) ; let r_deref_expr = ty :: ReScope ( s_deref_expr ) ; for i in 0 .. derefs { let method_call = MethodCall :: autoderef ( deref_expr . id , i as u32 ) ; debug ! ( " " method_call derefs ) ; let method = rcx . fcx . inh . tables . borrow ( ) . method_map . get ( & method_call ) . map ( | m | m . clone ( ) ) ; derefd_ty = match method { Some ( method ) => { debug ! ( " " i method ) ; let origin = infer :: ParameterOrigin :: OverloadedDeref ; substs_wf_in_scope ( rcx , origin , method . substs , deref_expr . span , r_deref_expr ) ; // Treat overloaded autoderefs as if an AutoRef adjustment // was applied on the base type, as that is always the case. let fn_sig = method . ty . fn_sig ( ) ; let fn_sig = // late-bound regions should have been instantiated rcx . tcx ( ) . no_late_bound_regions ( fn_sig ) . unwrap ( ) ; let self_ty = fn_sig . inputs [ 0 ] ; let ( m , r ) = match self_ty . sty { ty :: TyRef ( r , ref m ) => ( m . mutbl , r ) , _ => { rcx . tcx ( ) . sess . span_bug ( deref_expr . span , & format ! ( " " method ty ) ) } } ; debug ! ( " " r m ) ; { let mc = mc :: MemCategorizationContext :: new ( rcx . fcx . infcx ( ) ) ; let self_cmt = ignore_err ! ( mc cat_expr_autoderefd ( deref_expr i ) ) ; debug ! ( " " self_cmt ) ; link_region ( rcx , deref_expr . span , r , ty :: BorrowKind :: from_mutbl ( m ) , self_cmt ) ; } // Specialized version of constrain_call. type_must_outlive ( rcx , infer :: CallRcvr ( deref_expr . span ) , self_ty , r_deref_expr ) ; match fn_sig . output { ty :: FnConverging ( return_type ) => { type_must_outlive ( rcx , infer :: CallReturn ( deref_expr . span ) , return_type , r_deref_expr ) ; return_type } ty :: FnDiverging => unreachable ! ( ) } } None => derefd_ty } ; if let ty :: TyRef ( r_ptr , _ ) = derefd_ty . sty { mk_subregion_due_to_dereference ( rcx , deref_expr . span , r_deref_expr , * r_ptr ) ; } match derefd_ty . builtin_deref ( true , ty :: NoPreference ) { Some ( mt ) => derefd_ty = mt . ty , /* if this type can't be dereferenced, then there's already an error
               in the session saying so. Just bail out for now */ None => break } } }
Invoked on any auto-dereference that occurs.
Invoked on any auto - dereference that occurs .
rcx
&mut Rcx<'a, 'tcx>
deref_expr
&hir::Expr
derefs
usize
derefd_ty
Ty<'tcx>