@@ -198,7 +198,7 @@ enum TypeRootFilter {
198
198
pub ( crate ) struct TraitMap {
199
199
trait_impls : TraitImpls ,
200
200
satisfied_cache : im:: HashSet < u64 > ,
201
- insert_for_type_cache : im:: HashSet < TypeId > ,
201
+ insert_for_type_cache : im:: HashMap < TypeRootFilter , im :: Vector < TypeId > > ,
202
202
}
203
203
204
204
pub ( crate ) enum IsImplSelf {
@@ -247,8 +247,9 @@ impl TraitMap {
247
247
. filter ( |t| t. type_id == type_id_type_parameter. type_id )
248
248
. last ( ) ;
249
249
if let Some ( impl_type_parameter) = impl_type_parameter {
250
- type_id_type_parameter. trait_constraints =
251
- impl_type_parameter. trait_constraints . clone ( ) ;
250
+ type_id_type_parameter
251
+ . trait_constraints
252
+ . clone_from ( & impl_type_parameter. trait_constraints ) ;
252
253
}
253
254
}
254
255
handler. scope ( |handler| {
@@ -383,7 +384,7 @@ impl TraitMap {
383
384
if type_id_type_parameter
384
385
. type_id
385
386
. is_concrete ( engines, crate :: TreatNumericAs :: Abstract )
386
- && ! self
387
+ && self
387
388
. check_if_trait_constraints_are_satisfied_for_type (
388
389
& Handler :: default ( ) ,
389
390
type_id_type_parameter. type_id ,
@@ -393,7 +394,7 @@ impl TraitMap {
393
394
TryInsertingTraitImplOnFailure :: Yes ,
394
395
CodeBlockFirstPass :: No ,
395
396
)
396
- . is_ok ( )
397
+ . is_err ( )
397
398
{
398
399
trait_constraints_safified = false ;
399
400
}
@@ -508,6 +509,7 @@ impl TraitMap {
508
509
} )
509
510
}
510
511
512
+ #[ allow( clippy:: too_many_arguments) ]
511
513
fn insert_inner (
512
514
& mut self ,
513
515
trait_name : TraitName ,
@@ -519,15 +521,16 @@ impl TraitMap {
519
521
engines : & Engines ,
520
522
) {
521
523
let key = TraitKey {
522
- name : trait_name,
524
+ name : trait_name. clone ( ) ,
523
525
type_id,
524
526
type_id_type_parameters,
525
527
trait_decl_span,
526
528
} ;
527
529
let value = TraitValue {
528
- trait_items : trait_methods,
530
+ trait_items : trait_methods. clone ( ) ,
529
531
impl_span,
530
532
} ;
533
+
531
534
let entry = TraitEntry { key, value } ;
532
535
let mut trait_impls: TraitImpls =
533
536
im:: HashMap :: < TypeRootFilter , im:: Vector < TraitEntry > > :: new ( ) ;
@@ -539,7 +542,7 @@ impl TraitMap {
539
542
let trait_map = TraitMap {
540
543
trait_impls,
541
544
satisfied_cache : im:: HashSet :: default ( ) ,
542
- insert_for_type_cache : im:: HashSet :: default ( ) ,
545
+ insert_for_type_cache : im:: HashMap :: < TypeRootFilter , im :: Vector < TypeId > > :: new ( ) ,
543
546
} ;
544
547
545
548
self . extend ( trait_map, engines) ;
@@ -637,10 +640,18 @@ impl TraitMap {
637
640
type_id : TypeId ,
638
641
code_block_first_pass : CodeBlockFirstPass ,
639
642
) {
640
- if self . insert_for_type_cache . contains ( & type_id) {
641
- return ;
643
+ let root_filter = TraitMap :: get_type_root_filter ( engines, type_id) ;
644
+ if let Some ( values) = self . insert_for_type_cache . get_mut ( & root_filter) {
645
+ let unify_checker = UnifyCheck :: non_dynamic_equality ( engines) . with_unify_ref_mut ( false ) ;
646
+ if values. iter ( ) . any ( |v| unify_checker. check ( type_id, * v) ) {
647
+ return ;
648
+ } else {
649
+ values. push_back ( type_id) ;
650
+ }
651
+ } else {
652
+ self . insert_for_type_cache
653
+ . insert ( root_filter, vec ! [ type_id] . into ( ) ) ;
642
654
}
643
- self . insert_for_type_cache . insert ( type_id) ;
644
655
645
656
self . extend (
646
657
self . filter_by_type ( type_id, engines, code_block_first_pass) ,
@@ -666,10 +677,44 @@ impl TraitMap {
666
677
} ) ;
667
678
668
679
match pos {
669
- Ok ( pos) => self_vec[ pos]
670
- . value
671
- . trait_items
672
- . extend ( oe. value . trait_items . clone ( ) ) ,
680
+ Ok ( pos) => {
681
+ let mut skip_insert = false ;
682
+
683
+ // If we have the same method in: impl<T> FromBytes for T
684
+ // and: impl FromBytes for DataPoint
685
+ // We keep the second implementation.
686
+ for ( name, item) in oe. value . trait_items . iter ( ) {
687
+ for ( existing_name, existing_item) in
688
+ self_vec[ pos] . value . trait_items . iter ( )
689
+ {
690
+ if name == existing_name {
691
+ if let (
692
+ TyTraitItem :: Fn ( fn_ref) ,
693
+ TyTraitItem :: Fn ( existing_fn_ref) ,
694
+ ) = (
695
+ item. clone ( ) . expect_typed ( ) ,
696
+ existing_item. clone ( ) . expect_typed ( ) ,
697
+ ) {
698
+ let method = engines. de ( ) . get_function ( fn_ref. id ( ) ) ;
699
+ let existing_method =
700
+ engines. de ( ) . get_function ( existing_fn_ref. id ( ) ) ;
701
+ if !existing_method. is_from_blanket_impl ( engines)
702
+ && method. is_from_blanket_impl ( engines)
703
+ {
704
+ skip_insert = true ;
705
+ }
706
+ }
707
+ }
708
+ }
709
+ }
710
+
711
+ if !skip_insert {
712
+ self_vec[ pos]
713
+ . value
714
+ . trait_items
715
+ . extend ( oe. value . trait_items . clone ( ) )
716
+ }
717
+ }
673
718
Err ( pos) => self_vec. insert ( pos, oe. clone ( ) ) ,
674
719
}
675
720
}
0 commit comments