@@ -650,7 +650,7 @@ static void jl_compilation_sig(
650
650
else if (jl_is_type_type (elt )) { // elt isa Type{T}
651
651
if (very_general_type (decl_i )) {
652
652
/*
653
- here 's a fairly simple heuristic: if this argument slot's
653
+ Here 's a fairly simple heuristic: if this argument slot's
654
654
declared type is general (Type or Any),
655
655
then don't specialize for every Type that got passed.
656
656
@@ -665,8 +665,9 @@ static void jl_compilation_sig(
665
665
x::TypeConstructor matches the first but not the second, while
666
666
also matching all other TypeConstructors. This means neither
667
667
Type{TC} nor TypeConstructor is more specific.
668
+
669
+ But don't apply this heuristic if the argument is called (issue #36783).
668
670
*/
669
- // don't apply this heuristic if the argument is called (issue #36783)
670
671
int iscalled = i_arg > 0 && i_arg <= 8 && (definition -> called & (1 << (i_arg - 1 )));
671
672
if (!iscalled ) {
672
673
if (!* newparams ) * newparams = jl_svec_copy (tt -> parameters );
@@ -676,13 +677,13 @@ static void jl_compilation_sig(
676
677
else if (jl_is_type_type (jl_tparam0 (elt )) &&
677
678
// try to give up on specializing type parameters for Type{Type{Type{...}}}
678
679
(jl_is_type_type (jl_tparam0 (jl_tparam0 (elt ))) || !jl_has_free_typevars (decl_i ))) {
679
- // TODO: this is probably solidly unsound and would corrupt the cache in many cases
680
680
/*
681
681
actual argument was Type{...}, we computed its type as
682
- Type{Type{...}}. we must avoid unbounded nesting here, so
683
- cache the signature as Type{T}, unless something more
684
- specific like Type{Type{Int32}} was actually declared.
685
- this can be determined using a type intersection.
682
+ Type{Type{...}}. we like to avoid unbounded nesting here, so
683
+ compile (and hopefully cache) the signature as Type{T},
684
+ unless something more specific like Type{Type{Int32}} was
685
+ actually declared. this can be determined using a type
686
+ intersection.
686
687
*/
687
688
if (!* newparams ) * newparams = jl_svec_copy (tt -> parameters );
688
689
if (i < nargs || !definition -> isva ) {
@@ -1024,12 +1025,12 @@ static jl_method_instance_t *cache_method(
1024
1025
intptr_t nspec = (mt == NULL || mt == jl_type_type_mt || mt == jl_nonfunction_mt ? definition -> nargs + 1 : mt -> max_args + 2 );
1025
1026
jl_compilation_sig (tt , sparams , definition , nspec , & newparams );
1026
1027
if (newparams ) {
1027
- cache_with_orig = 0 ;
1028
1028
compilationsig = jl_apply_tuple_type (newparams );
1029
1029
temp2 = (jl_value_t * )compilationsig ;
1030
1030
// In most cases `!jl_isa_compileable_sig(tt, definition))`,
1031
1031
// although for some cases, (notably Varargs)
1032
1032
// we might choose a replacement type that's preferable but not strictly better
1033
+ cache_with_orig = !jl_subtype (compilationsig , definition -> sig );
1033
1034
}
1034
1035
// TODO: maybe assert(jl_isa_compileable_sig(compilationsig, definition));
1035
1036
newmeth = jl_specializations_get_linfo (definition , (jl_value_t * )compilationsig , sparams );
@@ -1038,7 +1039,6 @@ static jl_method_instance_t *cache_method(
1038
1039
jl_svec_t * guardsigs = jl_emptysvec ;
1039
1040
if (!cache_with_orig && mt ) {
1040
1041
// now examine what will happen if we chose to use this sig in the cache
1041
- // TODO: should we first check `compilationsig <: definition`?
1042
1042
size_t min_valid2 = 1 ;
1043
1043
size_t max_valid2 = ~(size_t )0 ;
1044
1044
temp = ml_matches (mt , 0 , compilationsig , MAX_UNSPECIALIZED_CONFLICTS , 1 , 1 , world , 0 , & min_valid2 , & max_valid2 , NULL );
0 commit comments