@@ -13,6 +13,7 @@ use constrained_type_params::{identify_constrained_type_params, Parameter};
13
13
use CrateCtxt ;
14
14
use hir:: def_id:: DefId ;
15
15
use middle:: region:: { CodeExtent } ;
16
+ use rustc:: infer:: TypeOrigin ;
16
17
use rustc:: ty:: subst:: { self , TypeSpace , FnSpace , ParamSpace , SelfSpace } ;
17
18
use rustc:: traits;
18
19
use rustc:: ty:: { self , Ty , TyCtxt } ;
@@ -157,7 +158,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
157
158
}
158
159
}
159
160
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 > ) {
161
165
let code = self . code . clone ( ) ;
162
166
self . for_id ( item_id, span) . with_fcx ( |fcx, this| {
163
167
let free_substs = & fcx. parameter_environment . free_substs ;
@@ -182,7 +186,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
182
186
let predicates = fcx. instantiate_bounds ( span, free_substs, & method. predicates ) ;
183
187
this. check_fn_or_method ( fcx, span, & method_ty, & predicates,
184
188
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,
186
191
free_id_outlive, self_ty) ;
187
192
}
188
193
ty:: TypeTraitItem ( assoc_type) => {
@@ -405,20 +410,15 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
405
410
406
411
fn check_method_receiver < ' fcx , ' tcx > ( & mut self ,
407
412
fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
408
- span : Span ,
413
+ method_sig : & hir :: MethodSig ,
409
414
method : & ty:: Method < ' tcx > ,
410
415
free_id_outlive : CodeExtent ,
411
416
self_ty : ty:: Ty < ' tcx > )
412
417
{
413
418
// check that the type of the method's receiver matches the
414
419
// 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) ;
422
422
423
423
let rcvr_ty = match method. explicit_self {
424
424
ty:: ExplicitSelfCategory :: Static => return ,
@@ -431,13 +431,23 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
431
431
}
432
432
ty:: ExplicitSelfCategory :: ByBox => fcx. tcx . mk_box ( self_ty)
433
433
} ;
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
+
434
443
let rcvr_ty = fcx. instantiate_type_scheme ( span, free_substs, & rcvr_ty) ;
435
444
let rcvr_ty = fcx. tcx . liberate_late_bound_regions ( free_id_outlive,
436
445
& ty:: Binder ( rcvr_ty) ) ;
437
446
438
447
debug ! ( "check_method_receiver: receiver ty = {:?}" , rcvr_ty) ;
439
448
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 ] ) ;
441
451
}
442
452
443
453
fn check_variances_for_type_defn ( & self ,
@@ -552,13 +562,21 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
552
562
553
563
fn visit_trait_item ( & mut self , trait_item : & ' v hir:: TraitItem ) {
554
564
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) ;
556
570
intravisit:: walk_trait_item ( self , trait_item)
557
571
}
558
572
559
573
fn visit_impl_item ( & mut self , impl_item : & ' v hir:: ImplItem ) {
560
574
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) ;
562
580
intravisit:: walk_impl_item ( self , impl_item)
563
581
}
564
582
}
0 commit comments