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