@@ -586,6 +586,11 @@ pub struct ctxt<'tcx> {
586
586
587
587
/// Caches the representation hints for struct definitions.
588
588
pub repr_hint_cache : RefCell < DefIdMap < Rc < Vec < attr:: ReprAttr > > > > ,
589
+
590
+ pub overloaded_operator_filter :
591
+ RefCell < HashMap < SimplifiedType , OverloadedOperatorFilter > > ,
592
+
593
+ pub smart_pointers : RefCell < DefIdSet > ,
589
594
}
590
595
591
596
pub enum tbox_flag {
@@ -1537,6 +1542,8 @@ pub fn mk_ctxt<'tcx>(s: Session,
1537
1542
trait_associated_types : RefCell :: new ( DefIdMap :: new ( ) ) ,
1538
1543
selection_cache : traits:: SelectionCache :: new ( ) ,
1539
1544
repr_hint_cache : RefCell :: new ( DefIdMap :: new ( ) ) ,
1545
+ overloaded_operator_filter : RefCell :: new ( HashMap :: new ( ) ) ,
1546
+ smart_pointers : RefCell :: new ( DefIdSet :: new ( ) ) ,
1540
1547
}
1541
1548
}
1542
1549
@@ -5598,3 +5605,186 @@ pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T)
5598
5605
Some ( d) => f ( d. as_slice ( ) )
5599
5606
}
5600
5607
}
5608
+
5609
+ pub enum AllowDerefableFlag < ' a > {
5610
+ AllowDerefable ,
5611
+ DisallowDerefable ( & ' a ParameterEnvironment ) ,
5612
+ }
5613
+
5614
+ #[ deriving( Clone , PartialEq , Eq , Hash ) ]
5615
+ pub enum SimplifiedType {
5616
+ NilSimplifiedType ,
5617
+ BoolSimplifiedType ,
5618
+ CharSimplifiedType ,
5619
+ IntSimplifiedType ( ast:: IntTy ) ,
5620
+ UintSimplifiedType ( ast:: UintTy ) ,
5621
+ FloatSimplifiedType ( ast:: FloatTy ) ,
5622
+ EnumSimplifiedType ( DefId ) ,
5623
+ StrSimplifiedType ,
5624
+ VecSimplifiedType ,
5625
+ PtrSimplifiedType ,
5626
+ TupleSimplifiedType ( uint ) ,
5627
+ TraitSimplifiedType ( DefId ) ,
5628
+ StructSimplifiedType ( DefId ) ,
5629
+ UnboxedClosureSimplifiedType ( DefId ) ,
5630
+ FunctionSimplifiedType ( uint ) ,
5631
+ ParameterSimplifiedType ,
5632
+ }
5633
+
5634
+ impl SimplifiedType {
5635
+ pub fn from_type ( tcx : & ctxt ,
5636
+ ty : ty:: t ,
5637
+ can_simplify_params : bool ,
5638
+ allow_derefable : AllowDerefableFlag )
5639
+ -> Option < SimplifiedType > {
5640
+ let simplified_type = match get ( ty) . sty {
5641
+ ty_nil => Some ( NilSimplifiedType ) ,
5642
+ ty_bool => Some ( BoolSimplifiedType ) ,
5643
+ ty_char => Some ( CharSimplifiedType ) ,
5644
+ ty_int( int_type) => Some ( IntSimplifiedType ( int_type) ) ,
5645
+ ty_uint( uint_type) => Some ( UintSimplifiedType ( uint_type) ) ,
5646
+ ty_float( float_type) => Some ( FloatSimplifiedType ( float_type) ) ,
5647
+ ty_enum( def_id, _) => Some ( EnumSimplifiedType ( def_id) ) ,
5648
+ ty_str => Some ( StrSimplifiedType ) ,
5649
+ ty_trait( ref trait_info) => {
5650
+ Some ( TraitSimplifiedType ( trait_info. def_id ) )
5651
+ }
5652
+ ty_struct( def_id, _) => {
5653
+ Some ( StructSimplifiedType ( def_id) )
5654
+ }
5655
+ ty_unboxed_closure( def_id, _) => {
5656
+ Some ( UnboxedClosureSimplifiedType ( def_id) )
5657
+ }
5658
+ ty_vec( ..) => Some ( VecSimplifiedType ) ,
5659
+ ty_ptr( _) => Some ( PtrSimplifiedType ) ,
5660
+ ty_rptr( _, ref mt) => {
5661
+ SimplifiedType :: from_type ( tcx,
5662
+ mt. ty ,
5663
+ can_simplify_params,
5664
+ allow_derefable)
5665
+ }
5666
+ ty_uniq( ref ty) => {
5667
+ SimplifiedType :: from_type ( tcx,
5668
+ * ty,
5669
+ can_simplify_params,
5670
+ allow_derefable)
5671
+ }
5672
+ ty_tup( ref tys) => Some ( TupleSimplifiedType ( tys. len ( ) ) ) ,
5673
+ ty_closure( ref f) => {
5674
+ Some ( FunctionSimplifiedType ( f. sig . inputs . len ( ) ) )
5675
+ }
5676
+ ty_bare_fn( ref f) => {
5677
+ Some ( FunctionSimplifiedType ( f. sig . inputs . len ( ) ) )
5678
+ }
5679
+ ty_param( _) if can_simplify_params => {
5680
+ Some ( ParameterSimplifiedType )
5681
+ }
5682
+ ty_bot | ty_param( _) | ty_open( _) | ty_infer( _) | ty_err => None ,
5683
+ } ;
5684
+
5685
+ let simplified_type = match simplified_type {
5686
+ None => return None ,
5687
+ Some ( simplified_type) => simplified_type,
5688
+ } ;
5689
+
5690
+ match allow_derefable {
5691
+ AllowDerefable => { }
5692
+ DisallowDerefable ( param_env) => {
5693
+ match tcx. overloaded_operator_filter
5694
+ . borrow ( )
5695
+ . find ( & simplified_type) {
5696
+ Some ( ref flags) if flags. contains (
5697
+ DEREF_OVERLOADED_OPERATOR_FILTER ) => {
5698
+ return None
5699
+ }
5700
+ Some ( _) | None => { }
5701
+ }
5702
+
5703
+ match get ( ty) . sty {
5704
+ ty_param( ref param_ty) => {
5705
+ let bounds = & param_env. bounds
5706
+ . get ( param_ty. space ,
5707
+ param_ty. idx )
5708
+ . trait_bounds ;
5709
+ for bound in bounds. iter ( ) {
5710
+ let bad = Some ( bound. def_id ) ==
5711
+ tcx. lang_items . deref_trait ( ) ||
5712
+ Some ( bound. def_id ) ==
5713
+ tcx. lang_items . deref_mut_trait ( ) ;
5714
+ debug ! ( "for param {} bound {} deref {} bad {}" ,
5715
+ param_ty. repr( tcx) ,
5716
+ bound. repr( tcx) ,
5717
+ tcx. lang_items. deref_trait( ) ,
5718
+ bad) ;
5719
+ if bad {
5720
+ return None
5721
+ }
5722
+ }
5723
+ }
5724
+ _ => { }
5725
+ }
5726
+ }
5727
+ }
5728
+
5729
+ Some ( simplified_type)
5730
+ }
5731
+ }
5732
+
5733
+ pub enum MethodLookupKey {
5734
+ SimplifiedTypeLookupKey ( SimplifiedType ) ,
5735
+ SmartPointerLookupKey ( ast:: DefId , SimplifiedType ) ,
5736
+ }
5737
+
5738
+ impl MethodLookupKey {
5739
+ pub fn from_type ( tcx : & ctxt , ty : ty:: t , param_env : & ParameterEnvironment )
5740
+ -> Option < MethodLookupKey > {
5741
+ match get ( ty) . sty {
5742
+ ty_struct( def_id, ref substs) => {
5743
+ if tcx. smart_pointers . borrow ( ) . contains ( & def_id) {
5744
+ let simplified_referent = SimplifiedType :: from_type (
5745
+ tcx,
5746
+ * substs. types . get ( subst:: TypeSpace , 0 ) ,
5747
+ true ,
5748
+ DisallowDerefable ( param_env) ) ;
5749
+ match simplified_referent {
5750
+ None => return None ,
5751
+ Some ( simplified_referent) => {
5752
+ return Some ( SmartPointerLookupKey (
5753
+ def_id,
5754
+ simplified_referent) )
5755
+ }
5756
+ }
5757
+ }
5758
+ }
5759
+ _ => { }
5760
+ }
5761
+
5762
+ match SimplifiedType :: from_type ( tcx,
5763
+ ty,
5764
+ true ,
5765
+ DisallowDerefable ( param_env) ) {
5766
+ None => None ,
5767
+ Some ( simplified_type) => {
5768
+ Some ( SimplifiedTypeLookupKey ( simplified_type) )
5769
+ }
5770
+ }
5771
+ }
5772
+
5773
+ pub fn might_match ( & self , other : & SimplifiedType ) -> bool {
5774
+ match * self {
5775
+ SimplifiedTypeLookupKey ( ref this) => * this == * other,
5776
+ SmartPointerLookupKey ( def_id, ref this) => {
5777
+ * this == * other || StructSimplifiedType ( def_id) == * other
5778
+ }
5779
+ }
5780
+ }
5781
+ }
5782
+
5783
+ bitflags ! {
5784
+ flags OverloadedOperatorFilter : u8 {
5785
+ const INDEX_OVERLOADED_OPERATOR_FILTER = 0x01 ,
5786
+ const DEREF_OVERLOADED_OPERATOR_FILTER = 0x02 ,
5787
+ const CALL_OVERLOADED_OPERATOR_FILTER = 0x04
5788
+ }
5789
+ }
5790
+
0 commit comments