@@ -606,6 +606,46 @@ jl_value_t *jl_nth_slot_type(jl_value_t *sig, size_t i) JL_NOTSAFEPOINT
606
606
// return 1;
607
607
//}
608
608
609
+ static jl_value_t * inst_varargp_in_env (jl_value_t * decl , jl_svec_t * sparams )
610
+ {
611
+ jl_value_t * unw = jl_unwrap_unionall (decl );
612
+ jl_value_t * vm = jl_tparam (unw , jl_nparams (unw ) - 1 );
613
+ assert (jl_is_vararg (vm ));
614
+ int nsp = jl_svec_len (sparams );
615
+ if (nsp > 0 && jl_has_free_typevars (vm )) {
616
+ JL_GC_PUSH1 (& vm );
617
+ assert (jl_subtype_env_size (decl ) == nsp );
618
+ vm = jl_instantiate_type_in_env (vm , (jl_unionall_t * )decl , jl_svec_data (sparams ));
619
+ assert (jl_is_vararg (vm ));
620
+ // rewrap_unionall(lastdeclt, sparams) if any sparams isa TypeVar
621
+ // for example, `Tuple{Vararg{Union{Nothing,Int,Val{T}}}} where T`
622
+ // and the user called it with `Tuple{Vararg{Union{Nothing,Int},N}}`, then T is unbound
623
+ jl_value_t * * sp = jl_svec_data (sparams );
624
+ while (jl_is_unionall (decl )) {
625
+ jl_tvar_t * v = (jl_tvar_t * )* sp ;
626
+ if (jl_is_typevar (v )) {
627
+ // must unwrap and re-wrap Vararg object explicitly here since jl_type_unionall handles it differently
628
+ jl_value_t * T = ((jl_vararg_t * )vm )-> T ;
629
+ jl_value_t * N = ((jl_vararg_t * )vm )-> N ;
630
+ int T_has_tv = T && jl_has_typevar (T , v );
631
+ int N_has_tv = N && jl_has_typevar (N , v ); // n.b. JL_VARARG_UNBOUND check means this should be false
632
+ assert (!N_has_tv || N == (jl_value_t * )v );
633
+ if (T_has_tv )
634
+ vm = jl_type_unionall (v , T );
635
+ if (N_has_tv )
636
+ N = NULL ;
637
+ vm = (jl_value_t * )jl_wrap_vararg (vm , N ); // this cannot throw for these inputs
638
+ }
639
+ sp ++ ;
640
+ decl = ((jl_unionall_t * )decl )-> body ;
641
+ nsp -- ;
642
+ }
643
+ assert (nsp == 0 );
644
+ JL_GC_POP ();
645
+ }
646
+ return vm ;
647
+ }
648
+
609
649
static jl_value_t * ml_matches (jl_methtable_t * mt ,
610
650
jl_tupletype_t * type , int lim , int include_ambiguous ,
611
651
int intersections , size_t world , int cache_result ,
@@ -634,10 +674,12 @@ static void jl_compilation_sig(
634
674
assert (jl_is_tuple_type (tt ));
635
675
size_t i , np = jl_nparams (tt );
636
676
size_t nargs = definition -> nargs ; // == jl_nparams(jl_unwrap_unionall(decl));
677
+ jl_value_t * type_i = NULL ;
678
+ JL_GC_PUSH1 (& type_i );
637
679
for (i = 0 ; i < np ; i ++ ) {
638
680
jl_value_t * elt = jl_tparam (tt , i );
639
681
jl_value_t * decl_i = jl_nth_slot_type (decl , i );
640
- jl_value_t * type_i = jl_rewrap_unionall (decl_i , decl );
682
+ type_i = jl_rewrap_unionall (decl_i , decl );
641
683
size_t i_arg = (i < nargs - 1 ? i : nargs - 1 );
642
684
643
685
if (jl_is_kind (type_i )) {
@@ -779,55 +821,45 @@ static void jl_compilation_sig(
779
821
// supertype of any other method signatures. so far we are conservative
780
822
// and the types we find should be bigger.
781
823
if (jl_nparams (tt ) >= nspec && jl_va_tuple_kind ((jl_datatype_t * )decl ) == JL_VARARG_UNBOUND ) {
782
- jl_svec_t * limited = jl_alloc_svec (nspec );
783
- JL_GC_PUSH1 (& limited );
784
824
if (!* newparams ) * newparams = tt -> parameters ;
785
- size_t i ;
786
- for (i = 0 ; i < nspec - 1 ; i ++ ) {
787
- jl_svecset (limited , i , jl_svecref (* newparams , i ));
788
- }
789
- jl_value_t * lasttype = jl_svecref (* newparams , i - 1 );
790
- // if all subsequent arguments are subtypes of lasttype, specialize
825
+ type_i = jl_svecref (* newparams , nspec - 2 );
826
+ // if all subsequent arguments are subtypes of type_i, specialize
791
827
// on that instead of decl. for example, if decl is
792
828
// (Any...)
793
829
// and type is
794
830
// (Symbol, Symbol, Symbol)
795
831
// then specialize as (Symbol...), but if type is
796
832
// (Symbol, Int32, Expr)
797
833
// then specialize as (Any...)
798
- size_t j = i ;
834
+ size_t j = nspec - 1 ;
799
835
int all_are_subtypes = 1 ;
800
836
for (; j < jl_svec_len (* newparams ); j ++ ) {
801
837
jl_value_t * paramj = jl_svecref (* newparams , j );
802
838
if (jl_is_vararg (paramj ))
803
839
paramj = jl_unwrap_vararg (paramj );
804
- if (!jl_subtype (paramj , lasttype )) {
840
+ if (!jl_subtype (paramj , type_i )) {
805
841
all_are_subtypes = 0 ;
806
842
break ;
807
843
}
808
844
}
809
845
if (all_are_subtypes ) {
810
846
// avoid Vararg{Type{Type{...}}}
811
- if (jl_is_type_type (lasttype ) && jl_is_type_type (jl_tparam0 (lasttype )))
812
- lasttype = (jl_value_t * )jl_type_type ;
813
- jl_svecset ( limited , i , jl_wrap_vararg (lasttype , (jl_value_t * )NULL ));
847
+ if (jl_is_type_type (type_i ) && jl_is_type_type (jl_tparam0 (type_i )))
848
+ type_i = (jl_value_t * )jl_type_type ;
849
+ type_i = ( jl_value_t * ) jl_wrap_vararg (type_i , (jl_value_t * )NULL ); // this cannot throw for these inputs
814
850
}
815
851
else {
816
- jl_value_t * unw = jl_unwrap_unionall (decl );
817
- jl_value_t * lastdeclt = jl_tparam (unw , jl_nparams (unw ) - 1 );
818
- assert (jl_is_vararg (lastdeclt ));
819
- int nsp = jl_svec_len (sparams );
820
- if (nsp > 0 && jl_has_free_typevars (lastdeclt )) {
821
- assert (jl_subtype_env_size (decl ) == nsp );
822
- lastdeclt = jl_instantiate_type_in_env (lastdeclt , (jl_unionall_t * )decl , jl_svec_data (sparams ));
823
- // TODO: rewrap_unionall(lastdeclt, sparams) if any sparams isa TypeVar???
824
- // TODO: if we made any replacements above, sparams may now be incorrect
825
- }
826
- jl_svecset (limited , i , lastdeclt );
852
+ type_i = inst_varargp_in_env (decl , sparams );
853
+ }
854
+ jl_svec_t * limited = jl_alloc_svec (nspec );
855
+ size_t i ;
856
+ for (i = 0 ; i < nspec - 1 ; i ++ ) {
857
+ jl_svecset (limited , i , jl_svecref (* newparams , i ));
827
858
}
859
+ jl_svecset (limited , i , type_i );
828
860
* newparams = limited ;
829
- JL_GC_POP ();
830
861
}
862
+ JL_GC_POP ();
831
863
}
832
864
833
865
// compute whether this type signature is a possible return value from jl_compilation_sig given a concrete-type for `tt`
@@ -865,56 +897,58 @@ JL_DLLEXPORT int jl_isa_compileable_sig(
865
897
jl_methtable_t * kwmt = mt == jl_kwcall_mt ? jl_kwmethod_table_for (decl ) : mt ;
866
898
if ((jl_value_t * )mt != jl_nothing ) {
867
899
// try to refine estimate of min and max
868
- if (kwmt && kwmt != jl_type_type_mt && kwmt != jl_nonfunction_mt && kwmt != jl_kwcall_mt )
900
+ if (kwmt != NULL && kwmt != jl_type_type_mt && kwmt != jl_nonfunction_mt && kwmt != jl_kwcall_mt )
901
+ // new methods may be added, increasing nspec_min later
869
902
nspec_min = jl_atomic_load_relaxed (& kwmt -> max_args ) + 2 + 2 * (mt == jl_kwcall_mt );
870
903
else
904
+ // nspec is always nargs+1, regardless of the other contents of these mt
871
905
nspec_max = nspec_min ;
872
906
}
873
- int isbound = (jl_va_tuple_kind ((jl_datatype_t * )decl ) == JL_VARARG_UNBOUND );
907
+ int isunbound = (jl_va_tuple_kind ((jl_datatype_t * )decl ) == JL_VARARG_UNBOUND );
874
908
if (jl_is_vararg (jl_tparam (type , np - 1 ))) {
875
- if (!isbound || np < nspec_min || np > nspec_max )
909
+ if (!isunbound || np < nspec_min || np > nspec_max )
876
910
return 0 ;
877
911
}
878
912
else {
879
- if (np < nargs - 1 || (isbound && np >= nspec_max ))
913
+ if (np < nargs - 1 || (isunbound && np >= nspec_max ))
880
914
return 0 ;
881
915
}
882
916
}
883
917
else if (np != nargs || jl_is_vararg (jl_tparam (type , np - 1 ))) {
884
918
return 0 ;
885
919
}
886
920
921
+ jl_value_t * type_i = NULL ;
922
+ JL_GC_PUSH1 (& type_i );
887
923
for (i = 0 ; i < np ; i ++ ) {
888
924
jl_value_t * elt = jl_tparam (type , i );
889
- jl_value_t * decl_i = jl_nth_slot_type ((jl_value_t * )decl , i );
890
- jl_value_t * type_i = jl_rewrap_unionall (decl_i , decl );
891
925
size_t i_arg = (i < nargs - 1 ? i : nargs - 1 );
892
926
893
927
if (jl_is_vararg (elt )) {
894
- elt = jl_unwrap_vararg (elt );
895
- if (jl_has_free_typevars (decl_i )) {
896
- // TODO: in this case, answer semi-conservatively that these varargs are always compilable
897
- // we don't have the ability to get sparams, so deciding if elt
898
- // is a potential result of jl_instantiate_type_in_env for decl_i
899
- // for any sparams that is consistent with the rest of the arguments
900
- // seems like it would be extremely difficult
901
- // and hopefully the upstream code probably gave us something reasonable
902
- continue ;
903
- }
904
- else if (jl_egal (elt , decl_i )) {
905
- continue ;
928
+ type_i = inst_varargp_in_env (decl , sparams );
929
+ if (jl_has_free_typevars (type_i )) {
930
+ JL_GC_POP ();
931
+ return 0 ; // something went badly wrong?
906
932
}
907
- else if (jl_is_type_type (elt ) && jl_is_type_type (jl_tparam0 (elt ))) {
908
- return 0 ;
933
+ if (jl_egal (elt , type_i ))
934
+ continue ; // elt could be chosen by inst_varargp_in_env for these sparams
935
+ elt = jl_unwrap_vararg (elt );
936
+ if (jl_is_type_type (elt ) && jl_is_type_type (jl_tparam0 (elt ))) {
937
+ JL_GC_POP ();
938
+ return 0 ; // elt would be set equal to jl_type_type instead
909
939
}
910
- // else, it needs to meet the usual rules
940
+ // else, elt also needs to meet the usual rules
911
941
}
912
942
943
+ jl_value_t * decl_i = jl_nth_slot_type (decl , i );
944
+ type_i = jl_rewrap_unionall (decl_i , decl );
945
+
913
946
if (i_arg > 0 && i_arg <= sizeof (definition -> nospecialize ) * 8 &&
914
947
(definition -> nospecialize & (1 << (i_arg - 1 )))) {
915
948
if (!jl_has_free_typevars (decl_i ) && !jl_is_kind (decl_i )) {
916
949
if (jl_egal (elt , decl_i ))
917
950
continue ;
951
+ JL_GC_POP ();
918
952
return 0 ;
919
953
}
920
954
}
@@ -923,10 +957,12 @@ JL_DLLEXPORT int jl_isa_compileable_sig(
923
957
// kind slots always get guard entries (checking for subtypes of Type)
924
958
if (jl_subtype (elt , type_i ) && !jl_subtype ((jl_value_t * )jl_type_type , type_i ))
925
959
continue ;
926
- // TODO: other code paths that could reach here
960
+ // TODO: other code paths that could reach here?
961
+ JL_GC_POP ();
927
962
return 0 ;
928
963
}
929
964
else if (jl_is_kind (type_i )) {
965
+ JL_GC_POP ();
930
966
return 0 ;
931
967
}
932
968
@@ -938,22 +974,31 @@ JL_DLLEXPORT int jl_isa_compileable_sig(
938
974
continue ;
939
975
if (i >= nargs && definition -> isva )
940
976
continue ;
977
+ JL_GC_POP ();
941
978
return 0 ;
942
979
}
943
- if (!iscalled && very_general_type (type_i ))
980
+ if (!iscalled && very_general_type (type_i )) {
981
+ JL_GC_POP ();
944
982
return 0 ;
945
- if (!jl_is_datatype (elt ))
983
+ }
984
+ if (!jl_is_datatype (elt )) {
985
+ JL_GC_POP ();
946
986
return 0 ;
987
+ }
947
988
948
989
// if the declared type was not Any or Union{Type, ...},
949
990
// then the match must been with kind, such as UnionAll or DataType,
950
991
// and the result of matching the type signature
951
992
// needs to be corrected to the concrete type 'kind' (and not to Type)
952
993
jl_value_t * kind = jl_typeof (jl_tparam0 (elt ));
953
- if (kind == jl_bottom_type )
994
+ if (kind == jl_bottom_type ) {
995
+ JL_GC_POP ();
954
996
return 0 ; // Type{Union{}} gets normalized to typeof(Union{})
955
- if (jl_subtype (kind , type_i ) && !jl_subtype ((jl_value_t * )jl_type_type , type_i ))
997
+ }
998
+ if (jl_subtype (kind , type_i ) && !jl_subtype ((jl_value_t * )jl_type_type , type_i )) {
999
+ JL_GC_POP ();
956
1000
return 0 ; // gets turned into a kind
1001
+ }
957
1002
958
1003
else if (jl_is_type_type (jl_tparam0 (elt )) &&
959
1004
// give up on specializing static parameters for Type{Type{Type{...}}}
@@ -966,20 +1011,20 @@ JL_DLLEXPORT int jl_isa_compileable_sig(
966
1011
this can be determined using a type intersection.
967
1012
*/
968
1013
if (i < nargs || !definition -> isva ) {
969
- jl_value_t * di = jl_type_intersection (type_i , (jl_value_t * )jl_type_type );
970
- JL_GC_PUSH1 (& di );
971
- assert (di != (jl_value_t * )jl_bottom_type );
972
- if (jl_is_kind (di )) {
1014
+ type_i = jl_type_intersection (type_i , (jl_value_t * )jl_type_type );
1015
+ assert (type_i != (jl_value_t * )jl_bottom_type );
1016
+ if (jl_is_kind (type_i )) {
973
1017
JL_GC_POP ();
974
1018
return 0 ;
975
1019
}
976
- else if (!jl_types_equal (di , elt )) {
1020
+ else if (!jl_types_equal (type_i , elt )) {
977
1021
JL_GC_POP ();
978
1022
return 0 ;
979
1023
}
980
- JL_GC_POP () ;
1024
+ continue ;
981
1025
}
982
1026
else {
1027
+ JL_GC_POP ();
983
1028
return 0 ;
984
1029
}
985
1030
}
@@ -1000,12 +1045,16 @@ JL_DLLEXPORT int jl_isa_compileable_sig(
1000
1045
// when called with a subtype of Function but is not called
1001
1046
if (elt == (jl_value_t * )jl_function_type )
1002
1047
continue ;
1048
+ JL_GC_POP ();
1003
1049
return 0 ;
1004
1050
}
1005
1051
1006
- if (!jl_is_concrete_type (elt ))
1052
+ if (!jl_is_concrete_type (elt )) {
1053
+ JL_GC_POP ();
1007
1054
return 0 ;
1055
+ }
1008
1056
}
1057
+ JL_GC_POP ();
1009
1058
return 1 ;
1010
1059
}
1011
1060
0 commit comments