@@ -2777,6 +2777,21 @@ static int type_eqv_with_ANY(jl_value_t *a, jl_value_t *b)
2777
2777
2778
2778
static int jl_type_morespecific_ (jl_value_t * a , jl_value_t * b , int invariant );
2779
2779
2780
+ jl_datatype_t * jl_fix_vararg_bound (jl_datatype_t * tt , int nfix )
2781
+ {
2782
+ assert (jl_is_va_tuple (tt ));
2783
+ assert (nfix >= 0 );
2784
+ jl_svec_t * tp = tt -> parameters ;
2785
+ size_t ntp = jl_svec_len (tp );
2786
+ jl_value_t * env [2 ] = {NULL , NULL };
2787
+ JL_GC_PUSH2 (& env [0 ], & env [1 ]);
2788
+ env [0 ] = jl_tparam1 (jl_tparam (tt , ntp - 1 ));
2789
+ env [1 ] = jl_box_long (nfix );
2790
+ jl_datatype_t * ret = (jl_datatype_t * )jl_instantiate_type_with ((jl_value_t * )tt , env , 2 );
2791
+ JL_GC_POP ();
2792
+ return ret ;
2793
+ }
2794
+
2780
2795
static int jl_tuple_morespecific (jl_datatype_t * cdt , jl_datatype_t * pdt , int invariant )
2781
2796
{
2782
2797
size_t clenr = jl_nparams (cdt );
@@ -2999,6 +3014,93 @@ JL_DLLEXPORT int jl_type_morespecific(jl_value_t *a, jl_value_t *b)
2999
3014
return jl_type_morespecific_ (a , b , 0 );
3000
3015
}
3001
3016
3017
+ int jl_args_morespecific_ (jl_value_t * a , jl_value_t * b )
3018
+ {
3019
+ int msp = jl_type_morespecific (a ,b );
3020
+ int btv = jl_has_typevars (b );
3021
+ if (btv ) {
3022
+ if (jl_type_match_morespecific (a ,b ) == (jl_value_t * )jl_false ) {
3023
+ if (jl_has_typevars (a ))
3024
+ return 0 ;
3025
+ return msp ;
3026
+ }
3027
+ if (jl_has_typevars (a )) {
3028
+ type_match_invariance_mask = 0 ;
3029
+ //int result = jl_type_match_morespecific(b,a) == (jl_value_t*)jl_false);
3030
+ // this rule seems to work better:
3031
+ int result = jl_type_match (b ,a ) == (jl_value_t * )jl_false ;
3032
+ type_match_invariance_mask = 1 ;
3033
+ if (result )
3034
+ return 1 ;
3035
+ }
3036
+ int nmsp = jl_type_morespecific (b ,a );
3037
+ if (nmsp == msp )
3038
+ return 0 ;
3039
+ }
3040
+ if (jl_has_typevars ((jl_value_t * )a )) {
3041
+ int nmsp = jl_type_morespecific (b ,a );
3042
+ if (nmsp && msp )
3043
+ return 1 ;
3044
+ if (!btv && jl_types_equal (a ,b ))
3045
+ return 1 ;
3046
+ if (jl_type_match_morespecific (b ,a ) != (jl_value_t * )jl_false )
3047
+ return 0 ;
3048
+ }
3049
+ return msp ;
3050
+ }
3051
+
3052
+ // Called when a is a bound-vararg and b is not a vararg. Sets the
3053
+ // vararg length in a to match b, as long as this makes some earlier
3054
+ // argument more specific.
3055
+ int jl_args_morespecific_fix1 (jl_value_t * a , jl_value_t * b , int swap )
3056
+ {
3057
+ jl_datatype_t * tta = (jl_datatype_t * )a ;
3058
+ jl_datatype_t * ttb = (jl_datatype_t * )b ;
3059
+ size_t n = jl_nparams (tta );
3060
+ jl_datatype_t * newtta = jl_fix_vararg_bound (tta , jl_nparams (ttb )- n + 1 );
3061
+ int changed = 0 ;
3062
+ for (size_t i = 0 ; i < n - 1 ; i ++ ) {
3063
+ if (jl_tparam (tta , i ) != jl_tparam (newtta , i )) {
3064
+ changed = 1 ;
3065
+ break ;
3066
+ }
3067
+ }
3068
+ if (changed ) {
3069
+ JL_GC_PUSH1 (& newtta );
3070
+ int ret ;
3071
+ if (swap )
3072
+ ret = jl_args_morespecific_ (b , (jl_value_t * )newtta );
3073
+ else
3074
+ ret = jl_args_morespecific_ ((jl_value_t * )newtta , b );
3075
+ JL_GC_POP ();
3076
+ return ret ;
3077
+ }
3078
+ if (swap )
3079
+ return jl_args_morespecific_ (b , a );
3080
+ return jl_args_morespecific_ (a , b );
3081
+ }
3082
+
3083
+ JL_DLLEXPORT int jl_args_morespecific (jl_value_t * a , jl_value_t * b )
3084
+ {
3085
+ if (jl_is_tuple_type (a ) && jl_is_tuple_type (b )) {
3086
+ jl_datatype_t * tta = (jl_datatype_t * )a ;
3087
+ jl_datatype_t * ttb = (jl_datatype_t * )b ;
3088
+ size_t alenf , blenf ;
3089
+ jl_vararg_kind_t akind , bkind ;
3090
+ jl_tuple_lenkind_t alenkind , blenkind ;
3091
+ alenf = tuple_vararg_params (tta -> parameters , NULL , & akind , & alenkind );
3092
+ blenf = tuple_vararg_params (ttb -> parameters , NULL , & bkind , & blenkind );
3093
+ // When one is JL_VARARG_BOUND and the other has fixed length,
3094
+ // allow the argument length to fix the tvar
3095
+ if (akind == JL_VARARG_BOUND && blenkind == JL_TUPLE_FIXED && blenf >= alenf ) {
3096
+ return jl_args_morespecific_fix1 (a , b , 0 );
3097
+ }
3098
+ if (bkind == JL_VARARG_BOUND && alenkind == JL_TUPLE_FIXED && alenf >= blenf ) {
3099
+ return jl_args_morespecific_fix1 (b , a , 1 );
3100
+ }
3101
+ }
3102
+ return jl_args_morespecific_ (a , b );
3103
+ }
3002
3104
3003
3105
// ----------------------------------------------------------------------------
3004
3106
0 commit comments