@@ -716,26 +716,68 @@ static jl_function_t *cache_method(jl_methtable_t *mt, jl_tuple_t *type,
716716    return  newmeth ;
717717}
718718
719+ static  jl_value_t  * lookup_match (jl_value_t  * a , jl_value_t  * b , jl_tuple_t  * * penv ,
720+                                 jl_tuple_t  * tvars , int  bind_all )
721+ {
722+     jl_value_t  * ti  =  jl_type_intersection_matching (a , b , penv , tvars );
723+     if  (ti  ==  (jl_value_t * )jl_bottom_type )
724+         return  ti ;
725+     jl_value_t  * * ee  =  alloca (sizeof (void * )* (* penv )-> length );
726+     int  n = 0 ;
727+     // only keep vars in tvars list 
728+     jl_value_t  * * tvs ;
729+     int  tvarslen ;
730+     if  (jl_is_typevar (tvars )) {
731+         tvs  =  (jl_value_t * * )& tvars ;
732+         tvarslen  =  1 ;
733+     }
734+     else  {
735+         tvs  =  & jl_t0 (tvars );
736+         tvarslen  =  tvars -> length ;
737+     }
738+     for (int  i = 0 ; i  <  (* penv )-> length ; i += 2 ) {
739+         jl_value_t  * v  =  jl_tupleref (* penv ,i );
740+         jl_value_t  * val  =  jl_tupleref (* penv ,i + 1 );
741+         if  (bind_all  ||  v  !=  val ) {
742+             for (int  j = 0 ; j  <  tvarslen ; j ++ ) {
743+                 if  (v  ==  tvs [j ]) {
744+                     ee [n ++ ] =  v ;
745+                     ee [n ++ ] =  val ;
746+                 }
747+             }
748+         }
749+     }
750+     if  (n  !=  (* penv )-> length ) {
751+         jl_tuple_t  * en  =  jl_alloc_tuple_uninit (n );
752+         memcpy (en -> data , ee , n * sizeof (void * ));
753+         * penv  =  en ;
754+     }
755+     return  ti ;
756+ }
757+ 
719758static  jl_function_t  * jl_mt_assoc_by_type (jl_methtable_t  * mt , jl_tuple_t  * tt , int  cache )
720759{
721760    jl_methlist_t  * m  =  mt -> defs ;
722761    size_t  nargs  =  tt -> length ;
723762    size_t  i ;
724-     jl_value_t  * env  =  jl_false ;
763+     jl_value_t  * ti = (jl_value_t * )jl_bottom_type ;
764+     jl_tuple_t  * newsig = NULL , * env  =  jl_null ;
765+     JL_GC_PUSH (& env , & newsig );
725766
726767    while  (m  !=  NULL ) {
727768        if  (m -> tvars != jl_null ) {
728-             env  =  jl_type_match ((jl_value_t * )tt , (jl_value_t * )m -> sig );
729-             if  (env  !=  jl_false ) {
769+             ti  =  lookup_match ((jl_value_t * )tt , (jl_value_t * )m -> sig ,
770+                               & env , m -> tvars , 0 );
771+             if  (ti  !=  (jl_value_t * )jl_bottom_type ) {
730772                // parametric methods only match if all typevars are matched by 
731773                // non-typevars. 
732-                 for (i = 1 ; i  <  (( jl_tuple_t * ) env ) -> length ; i += 2 ) {
774+                 for (i = 1 ; i  <  env -> length ; i += 2 ) {
733775                    if  (jl_is_typevar (jl_tupleref (env ,i )))
734776                        break ;
735777                }
736-                 if  (i  >= (( jl_tuple_t * ) env ) -> length )
778+                 if  (i  >= env -> length )
737779                    break ;
738-                 env  =  jl_false ;
780+                 ti  =  ( jl_value_t * ) jl_bottom_type ;
739781            }
740782        }
741783        else  if  (jl_tuple_subtype (& jl_tupleref (tt ,0 ), nargs ,
@@ -746,30 +788,26 @@ static jl_function_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_tuple_t *tt, in
746788        m  =  m -> next ;
747789    }
748790
749-     if  (env  ==  (jl_value_t * )jl_false ) {
791+     if  (ti  ==  (jl_value_t * )jl_bottom_type ) {
792+         JL_GC_POP ();
750793        if  (m  !=  NULL ) {
751-             if  (!cache ) { 
794+             if  (!cache )
752795                return  m -> func ;
753-             }
754796            return  cache_method (mt , tt , m -> func , (jl_tuple_t * )m -> sig , jl_null );
755797        }
756798        return  NULL ;
757799    }
758800
759-     jl_tuple_t  * newsig = NULL ;
760-     JL_GC_PUSH (& env , & newsig );
761- 
762801    assert (jl_is_tuple (env ));
763-     jl_tuple_t  * tpenv  =  (jl_tuple_t * )env ;
764802    // don't bother computing this if no arguments are tuples 
765803    for (i = 0 ; i  <  tt -> length ; i ++ ) {
766804        if  (jl_is_tuple (jl_tupleref (tt ,i )))
767805            break ;
768806    }
769807    if  (i  <  tt -> length ) {
770808        newsig  =  (jl_tuple_t * )jl_instantiate_type_with ((jl_type_t * )m -> sig ,
771-                                                        & jl_tupleref (tpenv ,0 ),
772-                                                        tpenv -> length /2 );
809+                                                        & jl_tupleref (env ,0 ),
810+                                                        env -> length /2 );
773811    }
774812    else  {
775813        newsig  =  (jl_tuple_t * )m -> sig ;
@@ -779,7 +817,7 @@ static jl_function_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_tuple_t *tt, in
779817    if  (!cache )
780818        nf  =  m -> func ;
781819    else 
782-         nf  =  cache_method (mt , tt , m -> func , newsig , tpenv );
820+         nf  =  cache_method (mt , tt , m -> func , newsig , env );
783821    JL_GC_POP ();
784822    return  nf ;
785823}
@@ -799,15 +837,16 @@ int jl_args_morespecific(jl_value_t *a, jl_value_t *b)
799837    int  msp  =  jl_type_morespecific (a ,b ,0 );
800838    if  (jl_has_typevars (b )) {
801839        if  (jl_type_match_morespecific (a ,b ) ==  (jl_value_t * )jl_false ) {
802-             if  (jl_has_typevars (a )) { 
840+             if  (jl_has_typevars (a ))
803841                return  0 ;
804-             }
805842            return  msp ;
806843        }
807844        if  (jl_has_typevars (a )) {
808-             if  (jl_type_match_morespecific (b ,a ) ==  (jl_value_t * )jl_false ) {
845+             //if (jl_type_match_morespecific(b,a) == (jl_value_t*)jl_false) 
846+             //    return 1; 
847+             // this rule seems to work better: 
848+             if  (jl_type_match (b ,a ) ==  (jl_value_t * )jl_false )
809849                return  1 ;
810-             }
811850        }
812851        int  nmsp  =  jl_type_morespecific (b ,a ,0 );
813852        if  (nmsp  ==  msp )
@@ -1361,7 +1400,7 @@ DLLEXPORT jl_tuple_t *jl_match_method(jl_value_t *type, jl_value_t *sig,
13611400    jl_tuple_t  * env  =  jl_null ;
13621401    jl_value_t  * ti = NULL ;
13631402    JL_GC_PUSH (& env , & ti );
1364-     ti  =  jl_type_intersection_matching (type , (jl_value_t * )sig , & env , tvars );
1403+     ti  =  lookup_match (type , (jl_value_t * )sig , & env , tvars ,  1 );
13651404    jl_tuple_t  * result  =  jl_tuple2 (ti , env );
13661405    JL_GC_POP ();
13671406    return  result ;
@@ -1375,7 +1414,7 @@ static jl_tuple_t *match_method(jl_value_t *type, jl_function_t *func,
13751414    jl_value_t  * ti = NULL ;
13761415    JL_GC_PUSH (& env , & ti , & temp );
13771416
1378-     ti  =  jl_type_intersection_matching (type , (jl_value_t * )sig , & env , tvars );
1417+     ti  =  lookup_match (type , (jl_value_t * )sig , & env , tvars ,  1 );
13791418    jl_tuple_t  * result  =  NULL ;
13801419    if  (ti  !=  (jl_value_t * )jl_bottom_type ) {
13811420        assert (func -> linfo );  // no builtin methods 
0 commit comments