pub fn lookup_method_in_trait(&self,
                                  span: Span,
                                  m_name: ast::Ident,
                                  trait_def_id: DefId,
                                  self_ty: Ty<'tcx>,
                                  opt_input_types: Option<&[Ty<'tcx>]>)
                                  -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
        debug!("lookup_in_trait_adjusted(self_ty={:?}, \
                m_name={}, trait_def_id={:?})",
               self_ty,
               m_name,
               trait_def_id);

        // Construct a trait-reference `self_ty : Trait<input_tys>`
        let substs = Substs::for_item(self.tcx, trait_def_id, |param, _| {
            match param.kind {
                GenericParamDefKind::Lifetime => {}
                GenericParamDefKind::Type {..} => {
                    if param.index == 0 {
                        return self_ty.into();
                    } else if let Some(ref input_types) = opt_input_types {
                        return input_types[param.index as usize - 1].into();
                    }
                }
            }
            self.var_for_def(span, param)
        });

        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,
                                     self.param_env,
                                     poly_trait_ref.to_predicate());

        // Now we want to know if this can be matched
        if !self.predicate_may_hold(&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 = match self.associated_item(trait_def_id, m_name, Namespace::Value) {
            Some(method_item) => method_item,
            None => {
                tcx.sess.delay_span_bug(span,
                    "operator trait does not have corresponding operator method");
                return None;
            }
        };
        let def_id = method_item.def_id;
        let generics = tcx.generics_of(def_id);
        assert_eq!(generics.params.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.
        //
        // N.B., instantiate late-bound regions first so that
        // `instantiate_type_scheme` can normalize associated types that
        // may reference those regions.
        let fn_sig = tcx.fn_sig(def_id);
        let fn_sig = self.replace_bound_vars_with_fresh_vars(
            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
            }
        };

        // 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_bound_vars());

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

        // Also add an obligation for the method type being well-formed.
        let method_ty = tcx.mk_fn_ptr(ty::Binder::bind(fn_sig));
        debug!("lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}",
               method_ty,
               obligation);
        obligations.push(traits::Obligation::new(cause,
                                                 self.param_env,
                                                 ty::Predicate::WellFormed(method_ty)));

        let callee = MethodCallee {
            def_id,
            substs: trait_ref.substs,
            sig: fn_sig,
        };

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

        Some(InferOk {
            obligations,
            value: callee
        })
    }
/// `lookup_method_in_trait` 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 a particular 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, the second half
/// of this method is basically the same as confirmation.
`lookup_method_in_trait` 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 a particular trait with the given self-type and checks
whether that trait is implemented.


` lookup_method_in_trait ` 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 a particular trait with the given self - type and checks whether that trait is implemented .
pub fn lookup_method_in_trait(&self,
                                  span: Span,
                                  m_name: ast::Ident,
                                  trait_def_id: DefId,
                                  self_ty: Ty<'tcx>,
                                  opt_input_types: Option<&[Ty<'tcx>]>)
                                  -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
        debug!("lookup_in_trait_adjusted(self_ty={:?}, \
                m_name={}, trait_def_id={:?})",
               self_ty,
               m_name,
               trait_def_id);
        // Construct a trait-reference `self_ty : Trait<input_tys>`
        let substs = Substs::for_item(self.tcx, trait_def_id, |param, _| {
            match param.kind {
                GenericParamDefKind::Lifetime => {}
                GenericParamDefKind::Type {..} => {
                    if param.index == 0 {
                        return self_ty.into();
                    } else if let Some(ref input_types) = opt_input_types {
                        return input_types[param.index as usize - 1].into();
                    }
                }
            }
            self.var_for_def(span, param)
        });
        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,
                                     self.param_env,
                                     poly_trait_ref.to_predicate());
        // Now we want to know if this can be matched
        if !self.predicate_may_hold(&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 = match self.associated_item(trait_def_id, m_name, Namespace::Value) {
            Some(method_item) => method_item,
            None => {
                tcx.sess.delay_span_bug(span,
                    "operator trait does not have corresponding operator method");
                return None;
            }
        };
        let def_id = method_item.def_id;
        let generics = tcx.generics_of(def_id);
        assert_eq!(generics.params.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.
        //
        // N.B., instantiate late-bound regions first so that
        // `instantiate_type_scheme` can normalize associated types that
        // may reference those regions.
        let fn_sig = tcx.fn_sig(def_id);
        let fn_sig = self.replace_bound_vars_with_fresh_vars(
            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
            }
        };
        // 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_bound_vars());
        let cause = traits::ObligationCause::misc(span, self.body_id);
        obligations.extend(traits::predicates_for_generics(cause.clone(),
                                                           self.param_env,
                                                           &bounds));
        // Also add an obligation for the method type being well-formed.
        let method_ty = tcx.mk_fn_ptr(ty::Binder::bind(fn_sig));
        debug!("lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}",
               method_ty,
               obligation);
        obligations.push(traits::Obligation::new(cause,
                                                 self.param_env,
                                                 ty::Predicate::WellFormed(method_ty)));
        let callee = MethodCallee {
            def_id,
            substs: trait_ref.substs,
            sig: fn_sig,
        };
        debug!("callee = {:?}", callee);
        Some(InferOk {
            obligations,
            value: callee
        })
    }
pub fn lookup_method_in_trait ( & self , span : Span , m_name : ast :: Ident , trait_def_id : DefId , self_ty : Ty < ' tcx > , opt_input_types : Option < & [ Ty < ' tcx > ] > ) -> Option < InferOk < ' tcx , MethodCallee < ' tcx > > > { debug ! ( " \
 " self_ty m_name trait_def_id ) ; // Construct a trait-reference `self_ty : Trait<input_tys>` let substs = Substs :: for_item ( self . tcx , trait_def_id , | param , _ | { match param . kind { GenericParamDefKind :: Lifetime => { } GenericParamDefKind :: Type { .. } => { if param . index == 0 { return self_ty . into ( ) ; } else if let Some ( ref input_types ) = opt_input_types { return input_types [ param . index as usize - 1 ] . into ( ) ; } } } self . var_for_def ( span , param ) } ) ; 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 , self . param_env , poly_trait_ref . to_predicate ( ) ) ; // Now we want to know if this can be matched if ! self . predicate_may_hold ( & 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 = match self . associated_item ( trait_def_id , m_name , Namespace :: Value ) { Some ( method_item ) => method_item , None => { tcx . sess . delay_span_bug ( span , " " ) ; return None ; } } ; let def_id = method_item . def_id ; let generics = tcx . generics_of ( def_id ) ; assert_eq ! ( generics params 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. // // N.B., instantiate late-bound regions first so that // `instantiate_type_scheme` can normalize associated types that // may reference those regions. let fn_sig = tcx . fn_sig ( def_id ) ; let fn_sig = self . replace_bound_vars_with_fresh_vars ( 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 } } ; // 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_bound_vars ( ) ) ; let cause = traits :: ObligationCause :: misc ( span , self . body_id ) ; obligations . extend ( traits :: predicates_for_generics ( cause . clone ( ) , self . param_env , & bounds ) ) ; // Also add an obligation for the method type being well-formed. let method_ty = tcx . mk_fn_ptr ( ty :: Binder :: bind ( fn_sig ) ) ; debug ! ( " " method_ty obligation ) ; obligations . push ( traits :: Obligation :: new ( cause , self . param_env , ty :: Predicate :: WellFormed ( method_ty ) ) ) ; let callee = MethodCallee { def_id , substs : trait_ref . substs , sig : fn_sig , } ; debug ! ( " " callee ) ; Some ( InferOk { obligations , value : callee } ) }
`lookup_method_in_trait` is used for overloaded operators.
` lookup_method_in_trait ` is used for overloaded operators .
&self
span
Span
m_name
ast::Ident
trait_def_id
DefId
self_ty
Ty<'tcx>
opt_input_types
Option<&[Ty<'tcx>]>
&self
span
Span
m_name
ast::Ident
trait_def_id
DefId
self_ty
Ty<'tcx>
opt_input_types
Option<&[Ty<'tcx>]>