pub fn lookup_method_in_trait_adjusted(&self,
                                           span: Span,
                                           self_info: Option<AdjustedRcvr>,
                                           m_name: ast::Name,
                                           trait_def_id: DefId,
                                           self_ty: ty::Ty<'tcx>,
                                           opt_input_types: Option<Vec<ty::Ty<'tcx>>>)
                                           -> Option<InferOk<'tcx, ty::MethodCallee<'tcx>>> {
        debug!("lookup_in_trait_adjusted(self_ty={:?}, self_info={:?}, \
                m_name={}, trait_def_id={:?})",
               self_ty,
               self_info,
               m_name,
               trait_def_id);

        // Construct a trait-reference `self_ty : Trait<input_tys>`
        let substs = Substs::for_item(self.tcx,
                                      trait_def_id,
                                      |def, _| self.region_var_for_def(span, def),
                                      |def, substs| {
            if def.index == 0 {
                self_ty
            } else if let Some(ref input_types) = opt_input_types {
                input_types[def.index as usize - 1]
            } else {
                self.type_var_for_def(span, def, substs)
            }
        });

        let trait_ref = ty::TraitRef::new(trait_def_id, substs);

        // Construct an obligation
        let poly_trait_ref = trait_ref.to_poly_trait_ref();
        let obligation =
            traits::Obligation::misc(span, self.body_id, poly_trait_ref.to_predicate());

        // Now we want to know if this can be matched
        let mut selcx = traits::SelectionContext::new(self);
        if !selcx.evaluate_obligation(&obligation) {
            debug!("--> Cannot match obligation");
            return None; // Cannot be matched, no such method resolution is possible.
        }

        // Trait must have a method named `m_name` and it should not have
        // type parameters or early-bound regions.
        let tcx = self.tcx;
        let method_item = self.associated_item(trait_def_id, m_name).unwrap();
        let def_id = method_item.def_id;
        let generics = tcx.generics_of(def_id);
        assert_eq!(generics.types.len(), 0);
        assert_eq!(generics.regions.len(), 0);

        debug!("lookup_in_trait_adjusted: method_item={:?}", method_item);
        let mut obligations = vec![];

        // Instantiate late-bound regions and substitute the trait
        // parameters into the method type to get the actual method type.
        //
        // NB: Instantiate late-bound regions first so that
        // `instantiate_type_scheme` can normalize associated types that
        // may reference those regions.
        let original_method_ty = tcx.type_of(def_id);
        let fn_sig = original_method_ty.fn_sig();
        let fn_sig = self.replace_late_bound_regions_with_fresh_var(span,
                                                                    infer::FnCall,
                                                                    &fn_sig).0;
        let fn_sig = fn_sig.subst(self.tcx, substs);
        let fn_sig = match self.normalize_associated_types_in_as_infer_ok(span, &fn_sig) {
            InferOk { value, obligations: o } => {
                obligations.extend(o);
                value
            }
        };
        let transformed_self_ty = fn_sig.inputs()[0];
        let method_ty = tcx.mk_fn_def(def_id, substs, ty::Binder(fn_sig));

        debug!("lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}",
               method_ty,
               obligation);

        // Register obligations for the parameters.  This will include the
        // `Self` parameter, which in turn has a bound of the main trait,
        // so this also effectively registers `obligation` as well.  (We
        // used to register `obligation` explicitly, but that resulted in
        // double error messages being reported.)
        //
        // Note that as the method comes from a trait, it should not have
        // any late-bound regions appearing in its bounds.
        let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs);
        let bounds = match self.normalize_associated_types_in_as_infer_ok(span, &bounds) {
            InferOk { value, obligations: o } => {
                obligations.extend(o);
                value
            }
        };
        assert!(!bounds.has_escaping_regions());

        let cause = traits::ObligationCause::misc(span, self.body_id);
        obligations.extend(traits::predicates_for_generics(cause.clone(), &bounds));

        // Also add an obligation for the method type being well-formed.
        obligations.push(traits::Obligation::new(cause, ty::Predicate::WellFormed(method_ty)));

        // Insert any adjustments needed (always an autoref of some mutability).
        if let Some(AdjustedRcvr { rcvr_expr, autoderefs, unsize }) = self_info {
            debug!("lookup_in_trait_adjusted: inserting adjustment if needed \
                    (self-id={}, autoderefs={}, unsize={}, fty={:?})",
                    rcvr_expr.id, autoderefs, unsize, original_method_ty);

            let original_sig = original_method_ty.fn_sig();
            let autoref = match (&original_sig.input(0).skip_binder().sty,
                                 &transformed_self_ty.sty) {
                (&ty::TyRef(..), &ty::TyRef(region, ty::TypeAndMut { mutbl, ty: _ })) => {
                    // Trait method is fn(&self) or fn(&mut self), need an
                    // autoref. Pull the region etc out of the type of first argument.
                    Some(AutoBorrow::Ref(region, mutbl))
                }
                _ => {
                    // Trait method is fn(self), no transformation needed.
                    assert!(!unsize);
                    None
                }
            };

            self.apply_adjustment(rcvr_expr.id, Adjustment {
                kind: Adjust::DerefRef {
                    autoderefs: autoderefs,
                    autoref: autoref,
                    unsize: unsize
                },
                target: transformed_self_ty
            });
        }

        let callee = ty::MethodCallee {
            def_id: def_id,
            ty: method_ty,
            substs: trait_ref.substs,
        };

        debug!("callee = {:?}", callee);

        Some(InferOk {
            obligations,
            value: callee
        })
    }
/// `lookup_in_trait_adjusted` is used for overloaded operators.
/// It does a very narrow slice of what the normal probe/confirm path does.
/// In particular, it doesn't really do any probing: it simply constructs
/// an obligation for aparticular trait with the given self-type and checks
/// whether that trait is implemented.
///
/// FIXME(#18741) -- It seems likely that we can consolidate some of this
/// code with the other method-lookup code. In particular, autoderef on
/// index is basically identical to autoderef with normal probes, except
/// that the test also looks for built-in indexing. Also, the second half of
/// this method is basically the same as confirmation.
`lookup_in_trait_adjusted` is used for overloaded operators.
It does a very narrow slice of what the normal probe/confirm path does.
In particular, it doesn't really do any probing: it simply constructs
an obligation for aparticular trait with the given self-type and checks
whether that trait is implemented.


` lookup_in_trait_adjusted ` is used for overloaded operators . It does a very narrow slice of what the normal probe / confirm path does . In particular it doesn ' t really do any probing : it simply constructs an obligation for aparticular trait with the given self - type and checks whether that trait is implemented .
pub fn lookup_method_in_trait_adjusted(&self,
                                           span: Span,
                                           self_info: Option<AdjustedRcvr>,
                                           m_name: ast::Name,
                                           trait_def_id: DefId,
                                           self_ty: ty::Ty<'tcx>,
                                           opt_input_types: Option<Vec<ty::Ty<'tcx>>>)
                                           -> Option<InferOk<'tcx, ty::MethodCallee<'tcx>>> {
        debug!("lookup_in_trait_adjusted(self_ty={:?}, self_info={:?}, \
                m_name={}, trait_def_id={:?})",
               self_ty,
               self_info,
               m_name,
               trait_def_id);
        // Construct a trait-reference `self_ty : Trait<input_tys>`
        let substs = Substs::for_item(self.tcx,
                                      trait_def_id,
                                      |def, _| self.region_var_for_def(span, def),
                                      |def, substs| {
            if def.index == 0 {
                self_ty
            } else if let Some(ref input_types) = opt_input_types {
                input_types[def.index as usize - 1]
            } else {
                self.type_var_for_def(span, def, substs)
            }
        });
        let trait_ref = ty::TraitRef::new(trait_def_id, substs);
        // Construct an obligation
        let poly_trait_ref = trait_ref.to_poly_trait_ref();
        let obligation =
            traits::Obligation::misc(span, self.body_id, poly_trait_ref.to_predicate());
        // Now we want to know if this can be matched
        let mut selcx = traits::SelectionContext::new(self);
        if !selcx.evaluate_obligation(&obligation) {
            debug!("--> Cannot match obligation");
            return None; // Cannot be matched, no such method resolution is possible.
        }
        // Trait must have a method named `m_name` and it should not have
        // type parameters or early-bound regions.
        let tcx = self.tcx;
        let method_item = self.associated_item(trait_def_id, m_name).unwrap();
        let def_id = method_item.def_id;
        let generics = tcx.generics_of(def_id);
        assert_eq!(generics.types.len(), 0);
        assert_eq!(generics.regions.len(), 0);
        debug!("lookup_in_trait_adjusted: method_item={:?}", method_item);
        let mut obligations = vec![];
        // Instantiate late-bound regions and substitute the trait
        // parameters into the method type to get the actual method type.
        //
        // NB: Instantiate late-bound regions first so that
        // `instantiate_type_scheme` can normalize associated types that
        // may reference those regions.
        let original_method_ty = tcx.type_of(def_id);
        let fn_sig = original_method_ty.fn_sig();
        let fn_sig = self.replace_late_bound_regions_with_fresh_var(span,
                                                                    infer::FnCall,
                                                                    &fn_sig).0;
        let fn_sig = fn_sig.subst(self.tcx, substs);
        let fn_sig = match self.normalize_associated_types_in_as_infer_ok(span, &fn_sig) {
            InferOk { value, obligations: o } => {
                obligations.extend(o);
                value
            }
        };
        let transformed_self_ty = fn_sig.inputs()[0];
        let method_ty = tcx.mk_fn_def(def_id, substs, ty::Binder(fn_sig));
        debug!("lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}",
               method_ty,
               obligation);
        // Register obligations for the parameters.  This will include the
        // `Self` parameter, which in turn has a bound of the main trait,
        // so this also effectively registers `obligation` as well.  (We
        // used to register `obligation` explicitly, but that resulted in
        // double error messages being reported.)
        //
        // Note that as the method comes from a trait, it should not have
        // any late-bound regions appearing in its bounds.
        let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs);
        let bounds = match self.normalize_associated_types_in_as_infer_ok(span, &bounds) {
            InferOk { value, obligations: o } => {
                obligations.extend(o);
                value
            }
        };
        assert!(!bounds.has_escaping_regions());
        let cause = traits::ObligationCause::misc(span, self.body_id);
        obligations.extend(traits::predicates_for_generics(cause.clone(), &bounds));
        // Also add an obligation for the method type being well-formed.
        obligations.push(traits::Obligation::new(cause, ty::Predicate::WellFormed(method_ty)));
        // Insert any adjustments needed (always an autoref of some mutability).
        if let Some(AdjustedRcvr { rcvr_expr, autoderefs, unsize }) = self_info {
            debug!("lookup_in_trait_adjusted: inserting adjustment if needed \
                    (self-id={}, autoderefs={}, unsize={}, fty={:?})",
                    rcvr_expr.id, autoderefs, unsize, original_method_ty);
            let original_sig = original_method_ty.fn_sig();
            let autoref = match (&original_sig.input(0).skip_binder().sty,
                                 &transformed_self_ty.sty) {
                (&ty::TyRef(..), &ty::TyRef(region, ty::TypeAndMut { mutbl, ty: _ })) => {
                    // Trait method is fn(&self) or fn(&mut self), need an
                    // autoref. Pull the region etc out of the type of first argument.
                    Some(AutoBorrow::Ref(region, mutbl))
                }
                _ => {
                    // Trait method is fn(self), no transformation needed.
                    assert!(!unsize);
                    None
                }
            };
            self.apply_adjustment(rcvr_expr.id, Adjustment {
                kind: Adjust::DerefRef {
                    autoderefs: autoderefs,
                    autoref: autoref,
                    unsize: unsize
                },
                target: transformed_self_ty
            });
        }
        let callee = ty::MethodCallee {
            def_id: def_id,
            ty: method_ty,
            substs: trait_ref.substs,
        };
        debug!("callee = {:?}", callee);
        Some(InferOk {
            obligations,
            value: callee
        })
    }
pub fn lookup_method_in_trait_adjusted ( & self , span : Span , self_info : Option < AdjustedRcvr > , m_name : ast :: Name , trait_def_id : DefId , self_ty : ty :: Ty < ' tcx > , opt_input_types : Option < Vec < ty :: Ty < ' tcx > > > ) -> Option < InferOk < ' tcx , ty :: MethodCallee < ' tcx > > > { debug ! ( " \
 " self_ty self_info m_name trait_def_id ) ; // Construct a trait-reference `self_ty : Trait<input_tys>` let substs = Substs :: for_item ( self . tcx , trait_def_id , | def , _ | self . region_var_for_def ( span , def ) , | def , substs | { if def . index == 0 { self_ty } else if let Some ( ref input_types ) = opt_input_types { input_types [ def . index as usize - 1 ] } else { self . type_var_for_def ( span , def , substs ) } } ) ; let trait_ref = ty :: TraitRef :: new ( trait_def_id , substs ) ; // Construct an obligation let poly_trait_ref = trait_ref . to_poly_trait_ref ( ) ; let obligation = traits :: Obligation :: misc ( span , self . body_id , poly_trait_ref . to_predicate ( ) ) ; // Now we want to know if this can be matched let mut selcx = traits :: SelectionContext :: new ( self ) ; if ! selcx . evaluate_obligation ( & obligation ) { debug ! ( " " ) ; return None ; // Cannot be matched, no such method resolution is possible. } // Trait must have a method named `m_name` and it should not have // type parameters or early-bound regions. let tcx = self . tcx ; let method_item = self . associated_item ( trait_def_id , m_name ) . unwrap ( ) ; let def_id = method_item . def_id ; let generics = tcx . generics_of ( def_id ) ; assert_eq ! ( generics types len ( ) 0 ) ; assert_eq ! ( generics regions len ( ) 0 ) ; debug ! ( " " method_item ) ; let mut obligations = vec ! [ ] ; // Instantiate late-bound regions and substitute the trait // parameters into the method type to get the actual method type. // // NB: Instantiate late-bound regions first so that // `instantiate_type_scheme` can normalize associated types that // may reference those regions. let original_method_ty = tcx . type_of ( def_id ) ; let fn_sig = original_method_ty . fn_sig ( ) ; let fn_sig = self . replace_late_bound_regions_with_fresh_var ( span , infer :: FnCall , & fn_sig ) . 0 ; let fn_sig = fn_sig . subst ( self . tcx , substs ) ; let fn_sig = match self . normalize_associated_types_in_as_infer_ok ( span , & fn_sig ) { InferOk { value , obligations : o } => { obligations . extend ( o ) ; value } } ; let transformed_self_ty = fn_sig . inputs ( ) [ 0 ] ; let method_ty = tcx . mk_fn_def ( def_id , substs , ty :: Binder ( fn_sig ) ) ; debug ! ( " " method_ty obligation ) ; // Register obligations for the parameters.  This will include the // `Self` parameter, which in turn has a bound of the main trait, // so this also effectively registers `obligation` as well.  (We // used to register `obligation` explicitly, but that resulted in // double error messages being reported.) // // Note that as the method comes from a trait, it should not have // any late-bound regions appearing in its bounds. let bounds = self . tcx . predicates_of ( def_id ) . instantiate ( self . tcx , substs ) ; let bounds = match self . normalize_associated_types_in_as_infer_ok ( span , & bounds ) { InferOk { value , obligations : o } => { obligations . extend ( o ) ; value } } ; assert ! ( bounds has_escaping_regions ( ) ) ; let cause = traits :: ObligationCause :: misc ( span , self . body_id ) ; obligations . extend ( traits :: predicates_for_generics ( cause . clone ( ) , & bounds ) ) ; // Also add an obligation for the method type being well-formed. obligations . push ( traits :: Obligation :: new ( cause , ty :: Predicate :: WellFormed ( method_ty ) ) ) ; // Insert any adjustments needed (always an autoref of some mutability). if let Some ( AdjustedRcvr { rcvr_expr , autoderefs , unsize } ) = self_info { debug ! ( " \
 " rcvr_expr id autoderefs unsize original_method_ty ) ; let original_sig = original_method_ty . fn_sig ( ) ; let autoref = match ( & original_sig . input ( 0 ) . skip_binder ( ) . sty , & transformed_self_ty . sty ) { ( & ty :: TyRef ( .. ) , & ty :: TyRef ( region , ty :: TypeAndMut { mutbl , ty : _ } ) ) => { // Trait method is fn(&self) or fn(&mut self), need an // autoref. Pull the region etc out of the type of first argument. Some ( AutoBorrow :: Ref ( region , mutbl ) ) } _ => { // Trait method is fn(self), no transformation needed. assert ! ( unsize ) ; None } } ; self . apply_adjustment ( rcvr_expr . id , Adjustment { kind : Adjust :: DerefRef { autoderefs : autoderefs , autoref : autoref , unsize : unsize } , target : transformed_self_ty } ) ; } let callee = ty :: MethodCallee { def_id : def_id , ty : method_ty , substs : trait_ref . substs , } ; debug ! ( " " callee ) ; Some ( InferOk { obligations , value : callee } ) }
`lookup_in_trait_adjusted` is used for overloaded operators.
` lookup_in_trait_adjusted ` is used for overloaded operators .
&self
span
Span
self_info
Option<AdjustedRcvr>
m_name
ast::Name
trait_def_id
DefId
self_ty
ty::Ty<'tcx>
opt_input_types
Option<Vec<ty::Ty<'tcx>>>
&self
span
Span
self_info
Option<AdjustedRcvr>
m_name
ast::Name
trait_def_id
DefId
self_ty
ty::Ty<'tcx>
opt_input_types
Option<Vec<ty::Ty<'tcx>>>