@@ -13,6 +13,7 @@ use constrained_type_params::{identify_constrained_type_params, Parameter};
1313use CrateCtxt ;
1414use hir:: def_id:: DefId ;
1515use middle:: region:: { CodeExtent } ;
16+ use rustc:: infer:: TypeOrigin ;
1617use rustc:: ty:: subst:: { self , TypeSpace , FnSpace , ParamSpace , SelfSpace } ;
1718use rustc:: traits;
1819use rustc:: ty:: { self , Ty , TyCtxt } ;
@@ -157,7 +158,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
157158 }
158159 }
159160
160- fn check_trait_or_impl_item ( & mut self , item_id : ast:: NodeId , span : Span ) {
161+ fn check_trait_or_impl_item ( & mut self ,
162+ item_id : ast:: NodeId ,
163+ span : Span ,
164+ sig_if_method : Option < & hir:: MethodSig > ) {
161165 let code = self . code . clone ( ) ;
162166 self . for_id ( item_id, span) . with_fcx ( |fcx, this| {
163167 let free_substs = & fcx. parameter_environment . free_substs ;
@@ -182,7 +186,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
182186 let predicates = fcx. instantiate_bounds ( span, free_substs, & method. predicates ) ;
183187 this. check_fn_or_method ( fcx, span, & method_ty, & predicates,
184188 free_id_outlive, & mut implied_bounds) ;
185- this. check_method_receiver ( fcx, span, & method,
189+ let sig_if_method = sig_if_method. expect ( "bad signature for method" ) ;
190+ this. check_method_receiver ( fcx, sig_if_method, & method,
186191 free_id_outlive, self_ty) ;
187192 }
188193 ty:: TypeTraitItem ( assoc_type) => {
@@ -405,20 +410,15 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
405410
406411 fn check_method_receiver < ' fcx , ' tcx > ( & mut self ,
407412 fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
408- span : Span ,
413+ method_sig : & hir :: MethodSig ,
409414 method : & ty:: Method < ' tcx > ,
410415 free_id_outlive : CodeExtent ,
411416 self_ty : ty:: Ty < ' tcx > )
412417 {
413418 // check that the type of the method's receiver matches the
414419 // method's first parameter.
415-
416- let free_substs = & fcx. parameter_environment . free_substs ;
417- let fty = fcx. instantiate_type_scheme ( span, free_substs, & method. fty ) ;
418- let sig = fcx. tcx . liberate_late_bound_regions ( free_id_outlive, & fty. sig ) ;
419-
420- debug ! ( "check_method_receiver({:?},cat={:?},self_ty={:?},sig={:?})" ,
421- method. name, method. explicit_self, self_ty, sig) ;
420+ debug ! ( "check_method_receiver({:?},cat={:?},self_ty={:?})" ,
421+ method. name, method. explicit_self, self_ty) ;
422422
423423 let rcvr_ty = match method. explicit_self {
424424 ty:: ExplicitSelfCategory :: Static => return ,
@@ -431,13 +431,23 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
431431 }
432432 ty:: ExplicitSelfCategory :: ByBox => fcx. tcx . mk_box ( self_ty)
433433 } ;
434+
435+ let span = method_sig. decl . inputs [ 0 ] . pat . span ;
436+
437+ let free_substs = & fcx. parameter_environment . free_substs ;
438+ let fty = fcx. instantiate_type_scheme ( span, free_substs, & method. fty ) ;
439+ let sig = fcx. tcx . liberate_late_bound_regions ( free_id_outlive, & fty. sig ) ;
440+
441+ debug ! ( "check_method_receiver: sig={:?}" , sig) ;
442+
434443 let rcvr_ty = fcx. instantiate_type_scheme ( span, free_substs, & rcvr_ty) ;
435444 let rcvr_ty = fcx. tcx . liberate_late_bound_regions ( free_id_outlive,
436445 & ty:: Binder ( rcvr_ty) ) ;
437446
438447 debug ! ( "check_method_receiver: receiver ty = {:?}" , rcvr_ty) ;
439448
440- fcx. demand_eqtype ( span, rcvr_ty, sig. inputs [ 0 ] ) ;
449+ let origin = TypeOrigin :: MethodReceiver ( span) ;
450+ fcx. demand_eqtype_with_origin ( origin, rcvr_ty, sig. inputs [ 0 ] ) ;
441451 }
442452
443453 fn check_variances_for_type_defn ( & self ,
@@ -552,13 +562,21 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
552562
553563 fn visit_trait_item ( & mut self , trait_item : & ' v hir:: TraitItem ) {
554564 debug ! ( "visit_trait_item: {:?}" , trait_item) ;
555- self . check_trait_or_impl_item ( trait_item. id , trait_item. span ) ;
565+ let method_sig = match trait_item. node {
566+ hir:: TraitItem_ :: MethodTraitItem ( ref sig, _) => Some ( sig) ,
567+ _ => None
568+ } ;
569+ self . check_trait_or_impl_item ( trait_item. id , trait_item. span , method_sig) ;
556570 intravisit:: walk_trait_item ( self , trait_item)
557571 }
558572
559573 fn visit_impl_item ( & mut self , impl_item : & ' v hir:: ImplItem ) {
560574 debug ! ( "visit_impl_item: {:?}" , impl_item) ;
561- self . check_trait_or_impl_item ( impl_item. id , impl_item. span ) ;
575+ let method_sig = match impl_item. node {
576+ hir:: ImplItemKind :: Method ( ref sig, _) => Some ( sig) ,
577+ _ => None
578+ } ;
579+ self . check_trait_or_impl_item ( impl_item. id , impl_item. span , method_sig) ;
562580 intravisit:: walk_impl_item ( self , impl_item)
563581 }
564582}
0 commit comments