@@ -2522,6 +2522,11 @@ pub struct TraitDef<'tcx> {
25222522 /// for resolving `X::Foo` type markers.
25232523 pub associated_type_names : Vec < ast:: Name > ,
25242524
2525+ // Impls of this trait. To allow for quicker lookup, the impls are indexed
2526+ // by a simplified version of their Self type: impls with a simplifiable
2527+ // Self are stored in nonblanket_impls keyed by it, while all other impls
2528+ // are stored in blanket_impls.
2529+
25252530 /// Impls of the trait.
25262531 pub nonblanket_impls : RefCell <
25272532 FnvHashMap < fast_reject:: SimplifiedType , Vec < DefId > >
@@ -2530,6 +2535,7 @@ pub struct TraitDef<'tcx> {
25302535 /// Blanket impls associated with the trait.
25312536 pub blanket_impls : RefCell < Vec < DefId > > ,
25322537
2538+ /// Various flags
25332539 pub flags : Cell < TraitFlags >
25342540}
25352541
@@ -2544,6 +2550,7 @@ impl<'tcx> TraitDef<'tcx> {
25442550 }
25452551
25462552 pub fn set_object_safety ( & self , is_safe : bool ) {
2553+ assert ! ( self . object_safety( ) . map( |cs| cs == is_safe) . unwrap_or( true ) ) ;
25472554 self . flags . set (
25482555 self . flags . get ( ) | if is_safe {
25492556 TraitFlags :: OBJECT_SAFETY_VALID | TraitFlags :: IS_OBJECT_SAFE
@@ -2563,14 +2570,18 @@ impl<'tcx> TraitDef<'tcx> {
25632570
25642571 if let Some ( sty) = fast_reject:: simplify_type ( tcx,
25652572 impl_trait_ref. self_ty ( ) , false ) {
2566- if !self . nonblanket_impls . borrow ( ) . get ( & sty) . map (
2567- |s| s. contains ( & impl_def_id) ) . unwrap_or ( false ) {
2568- self . nonblanket_impls . borrow_mut ( ) . entry ( sty) . or_insert ( vec ! [ ] ) . push ( impl_def_id)
2573+ if let Some ( is) = self . nonblanket_impls . borrow ( ) . get ( & sty) {
2574+ if is. contains ( & impl_def_id) {
2575+ return // duplicate - skip
2576+ }
25692577 }
2578+
2579+ self . nonblanket_impls . borrow_mut ( ) . entry ( sty) . or_insert ( vec ! [ ] ) . push ( impl_def_id)
25702580 } else {
2571- if ! self . blanket_impls . borrow ( ) . contains ( & impl_def_id) {
2572- self . blanket_impls . borrow_mut ( ) . push ( impl_def_id )
2581+ if self . blanket_impls . borrow ( ) . contains ( & impl_def_id) {
2582+ return // duplicate - skip
25732583 }
2584+ self . blanket_impls . borrow_mut ( ) . push ( impl_def_id)
25742585 }
25752586 }
25762587
@@ -2591,7 +2602,7 @@ impl<'tcx> TraitDef<'tcx> {
25912602
25922603 pub fn for_each_relevant_impl < F : FnMut ( DefId ) > ( & self ,
25932604 tcx : & ctxt < ' tcx > ,
2594- trait_ref : TraitRef < ' tcx > ,
2605+ self_ty : Ty < ' tcx > ,
25952606 mut f : F )
25962607 {
25972608 ty:: populate_implementations_for_trait_if_necessary ( tcx, self . trait_ref . def_id ) ;
@@ -2600,14 +2611,12 @@ impl<'tcx> TraitDef<'tcx> {
26002611 f ( impl_def_id) ;
26012612 }
26022613
2603- if let Some ( self_ty) = trait_ref. substs . self_ty ( ) {
2604- if let Some ( simp) = fast_reject:: simplify_type ( tcx, self_ty, false ) {
2605- if let Some ( impls) = self . nonblanket_impls . borrow ( ) . get ( & simp) {
2606- for & impl_def_id in impls {
2607- f ( impl_def_id) ;
2608- }
2614+ if let Some ( simp) = fast_reject:: simplify_type ( tcx, self_ty, false ) {
2615+ if let Some ( impls) = self . nonblanket_impls . borrow ( ) . get ( & simp) {
2616+ for & impl_def_id in impls {
2617+ f ( impl_def_id) ;
26092618 }
2610- return ; // don't process all non-blanket impls
2619+ return ; // we don't need to process the other non-blanket impls
26112620 }
26122621 }
26132622
0 commit comments