@@ -2522,6 +2522,11 @@ pub struct TraitDef<'tcx> {
2522
2522
/// for resolving `X::Foo` type markers.
2523
2523
pub associated_type_names : Vec < ast:: Name > ,
2524
2524
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
+
2525
2530
/// Impls of the trait.
2526
2531
pub nonblanket_impls : RefCell <
2527
2532
FnvHashMap < fast_reject:: SimplifiedType , Vec < DefId > >
@@ -2530,6 +2535,7 @@ pub struct TraitDef<'tcx> {
2530
2535
/// Blanket impls associated with the trait.
2531
2536
pub blanket_impls : RefCell < Vec < DefId > > ,
2532
2537
2538
+ /// Various flags
2533
2539
pub flags : Cell < TraitFlags >
2534
2540
}
2535
2541
@@ -2544,6 +2550,7 @@ impl<'tcx> TraitDef<'tcx> {
2544
2550
}
2545
2551
2546
2552
pub fn set_object_safety ( & self , is_safe : bool ) {
2553
+ assert ! ( self . object_safety( ) . map( |cs| cs == is_safe) . unwrap_or( true ) ) ;
2547
2554
self . flags . set (
2548
2555
self . flags . get ( ) | if is_safe {
2549
2556
TraitFlags :: OBJECT_SAFETY_VALID | TraitFlags :: IS_OBJECT_SAFE
@@ -2563,14 +2570,18 @@ impl<'tcx> TraitDef<'tcx> {
2563
2570
2564
2571
if let Some ( sty) = fast_reject:: simplify_type ( tcx,
2565
2572
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
+ }
2569
2577
}
2578
+
2579
+ self . nonblanket_impls . borrow_mut ( ) . entry ( sty) . or_insert ( vec ! [ ] ) . push ( impl_def_id)
2570
2580
} 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
2573
2583
}
2584
+ self . blanket_impls . borrow_mut ( ) . push ( impl_def_id)
2574
2585
}
2575
2586
}
2576
2587
@@ -2591,7 +2602,7 @@ impl<'tcx> TraitDef<'tcx> {
2591
2602
2592
2603
pub fn for_each_relevant_impl < F : FnMut ( DefId ) > ( & self ,
2593
2604
tcx : & ctxt < ' tcx > ,
2594
- trait_ref : TraitRef < ' tcx > ,
2605
+ self_ty : Ty < ' tcx > ,
2595
2606
mut f : F )
2596
2607
{
2597
2608
ty:: populate_implementations_for_trait_if_necessary ( tcx, self . trait_ref . def_id ) ;
@@ -2600,14 +2611,12 @@ impl<'tcx> TraitDef<'tcx> {
2600
2611
f ( impl_def_id) ;
2601
2612
}
2602
2613
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) ;
2609
2618
}
2610
- return ; // don't process all non-blanket impls
2619
+ return ; // we don't need to process the other non-blanket impls
2611
2620
}
2612
2621
}
2613
2622
0 commit comments