@@ -586,6 +586,11 @@ pub struct ctxt<'tcx> {
586586
587587 /// Caches the representation hints for struct definitions.
588588 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 > ,
589594}
590595
591596pub enum tbox_flag {
@@ -1537,6 +1542,8 @@ pub fn mk_ctxt<'tcx>(s: Session,
15371542 trait_associated_types : RefCell :: new ( DefIdMap :: new ( ) ) ,
15381543 selection_cache : traits:: SelectionCache :: new ( ) ,
15391544 repr_hint_cache : RefCell :: new ( DefIdMap :: new ( ) ) ,
1545+ overloaded_operator_filter : RefCell :: new ( HashMap :: new ( ) ) ,
1546+ smart_pointers : RefCell :: new ( DefIdSet :: new ( ) ) ,
15401547 }
15411548}
15421549
@@ -5598,3 +5605,186 @@ pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T)
55985605 Some ( d) => f ( d. as_slice ( ) )
55995606 }
56005607}
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