@@ -113,8 +113,8 @@ use rustc::mir::interpret::{ConstValue, GlobalId};
113
113
use rustc:: ty:: subst:: { CanonicalUserSubsts , UnpackedKind , Subst , Substs ,
114
114
UserSelfTy , UserSubsts } ;
115
115
use rustc:: traits:: { self , ObligationCause , ObligationCauseCode , TraitEngine } ;
116
- use rustc:: ty:: { self , AdtKind , Ty , TyCtxt , GenericParamDefKind , Visibility , ToPredicate ,
117
- RegionKind } ;
116
+ use rustc:: ty:: { self , AdtKind , Ty , TyCtxt , GenericParamDefKind , RegionKind , Visibility ,
117
+ ToPolyTraitRef , ToPredicate } ;
118
118
use rustc:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability } ;
119
119
use rustc:: ty:: fold:: TypeFoldable ;
120
120
use rustc:: ty:: query:: Providers ;
@@ -134,6 +134,7 @@ use std::collections::hash_map::Entry;
134
134
use std:: cmp;
135
135
use std:: fmt:: Display ;
136
136
use std:: iter;
137
+ use std:: vec;
137
138
use std:: mem:: replace;
138
139
use std:: ops:: { self , Deref } ;
139
140
use std:: slice;
@@ -2731,6 +2732,97 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2731
2732
method. sig . output ( )
2732
2733
}
2733
2734
2735
+ fn self_type_matches_expected_vid (
2736
+ & self ,
2737
+ trait_ref : ty:: PolyTraitRef < ' tcx > ,
2738
+ expected_vid : ty:: TyVid ,
2739
+ ) -> bool {
2740
+ let self_ty = self . shallow_resolve ( trait_ref. self_ty ( ) ) ;
2741
+ debug ! (
2742
+ "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})" ,
2743
+ trait_ref, self_ty, expected_vid
2744
+ ) ;
2745
+ match self_ty. sty {
2746
+ ty:: Infer ( ty:: TyVar ( v) ) => {
2747
+ let root_vid = self . root_var ( v) ;
2748
+ debug ! ( "self_type_matches_expected_vid - root_vid={:?}" , root_vid) ;
2749
+ if root_vid == expected_vid {
2750
+ true
2751
+ } else {
2752
+ false
2753
+ }
2754
+ }
2755
+ _ => false
2756
+ }
2757
+ }
2758
+ }
2759
+
2760
+ /// FIXME: impl Trait why u give me lifetime errors?
2761
+ pub struct ObligationMapper < ' a , ' gcx , ' tcx > ( & ' a FnCtxt < ' a , ' gcx , ' tcx > , ty:: TyVid ) ;
2762
+
2763
+ impl < ' a , ' gcx , ' tcx > FnOnce < ( traits:: PredicateObligation < ' tcx > , ) >
2764
+ for ObligationMapper < ' a , ' gcx , ' tcx >
2765
+ {
2766
+ type Output = Option < ty:: PolyTraitRef < ' tcx > > ;
2767
+
2768
+ extern "rust-call" fn call_once ( mut self , args : ( traits:: PredicateObligation < ' tcx > , ) )
2769
+ -> Self :: Output {
2770
+ self . call_mut ( args)
2771
+ }
2772
+ }
2773
+
2774
+ impl < ' a , ' gcx , ' tcx > FnMut < ( traits:: PredicateObligation < ' tcx > , ) >
2775
+ for ObligationMapper < ' a , ' gcx , ' tcx >
2776
+ {
2777
+ extern "rust-call" fn call_mut ( & mut self , args : ( traits:: PredicateObligation < ' tcx > , ) )
2778
+ -> Self :: Output {
2779
+ match args. 0 . predicate {
2780
+ ty:: Predicate :: Projection ( ref data) => Some ( data. to_poly_trait_ref ( self . 0 . tcx ) ) ,
2781
+ ty:: Predicate :: Trait ( ref data) => Some ( data. to_poly_trait_ref ( ) ) ,
2782
+ ty:: Predicate :: Subtype ( ..) => None ,
2783
+ ty:: Predicate :: RegionOutlives ( ..) => None ,
2784
+ ty:: Predicate :: TypeOutlives ( ..) => None ,
2785
+ ty:: Predicate :: WellFormed ( ..) => None ,
2786
+ ty:: Predicate :: ObjectSafe ( ..) => None ,
2787
+ ty:: Predicate :: ConstEvaluatable ( ..) => None ,
2788
+ // N.B., this predicate is created by breaking down a
2789
+ // `ClosureType: FnFoo()` predicate, where
2790
+ // `ClosureType` represents some `Closure`. It can't
2791
+ // possibly be referring to the current closure,
2792
+ // because we haven't produced the `Closure` for
2793
+ // this closure yet; this is exactly why the other
2794
+ // code is looking for a self type of a unresolved
2795
+ // inference variable.
2796
+ ty:: Predicate :: ClosureKind ( ..) => None ,
2797
+ } . filter ( |tr| {
2798
+ self . 0 . self_type_matches_expected_vid ( * tr, self . 1 )
2799
+ } )
2800
+ }
2801
+ }
2802
+
2803
+ impl < ' a , ' gcx , ' tcx > FnCtxt < ' a , ' gcx , ' tcx > {
2804
+ fn obligations_for_self_ty < ' b > ( & ' b self , self_ty : ty:: TyVid )
2805
+ -> iter:: FilterMap < vec:: IntoIter < traits:: PredicateObligation < ' tcx > > ,
2806
+ ObligationMapper < ' b , ' gcx , ' tcx > >
2807
+ {
2808
+ let ty_var_root = self . root_var ( self_ty) ;
2809
+ debug ! ( "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}" ,
2810
+ self_ty, ty_var_root,
2811
+ self . fulfillment_cx. borrow( ) . pending_obligations( ) ) ;
2812
+
2813
+ self . fulfillment_cx
2814
+ . borrow ( )
2815
+ . pending_obligations ( )
2816
+ . into_iter ( )
2817
+ . filter_map ( ObligationMapper ( self , ty_var_root) )
2818
+ }
2819
+
2820
+ fn type_var_is_sized ( & self , self_ty : ty:: TyVid ) -> bool {
2821
+ self . obligations_for_self_ty ( self_ty) . any ( |tr| {
2822
+ Some ( tr. def_id ( ) ) == self . tcx . lang_items ( ) . sized_trait ( )
2823
+ } )
2824
+ }
2825
+
2734
2826
/// Generic function that factors out common logic from function calls,
2735
2827
/// method calls and overloaded operators.
2736
2828
fn check_argument_types ( & self ,
0 commit comments