Skip to content

Commit 285c770

Browse files
committed
also optimize {Type{T},T} lookup
Since T cannot be Union{} here, the prior optimization would not get detected post facto, but a priori this cannot be inhabited for T=Union{}, so we can exclude it immediately. This does not happen during inference, but shows up during edge validation somewhat often.
1 parent a08e327 commit 285c770

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

src/typemap.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,16 @@ static int jl_typemap_intersection_node_visitor(jl_typemap_entry_t *ml, struct t
565565
int jl_has_intersect_type_not_kind(jl_value_t *t);
566566
int jl_has_intersect_kind_not_type(jl_value_t *t);
567567

568+
// if TypeVar tv is used covariantly, it cannot be Union{}
569+
int has_covariant_var(jl_datatype_t *ttypes, jl_tvar_t *tv)
570+
{
571+
size_t i, l = jl_nparams(ttypes);
572+
for (i = 0; i < l; i++)
573+
if (jl_tparam(ttypes, i) == (jl_value_t*)tv)
574+
return 1;
575+
return 0;
576+
}
577+
568578
void typemap_slurp_search(jl_typemap_entry_t *ml, struct typemap_intersection_env *closure)
569579
{
570580
// n.b. we could consider mt->max_args here too, so this optimization
@@ -640,7 +650,12 @@ int jl_typemap_intersection_visitor(jl_typemap_t *map, int offs,
640650
typetype = jl_unwrap_unionall(ty);
641651
typetype = jl_is_type_type(typetype) ? jl_tparam0(typetype) : NULL;
642652
name = typetype ? jl_type_extract_name(typetype) : NULL;
643-
exclude_typeofbottom = !(typetype ? jl_parameter_includes_bottom(typetype) : jl_subtype((jl_value_t*)jl_typeofbottom_type, ty));
653+
if (!typetype)
654+
exclude_typeofbottom = !jl_subtype((jl_value_t*)jl_typeofbottom_type, ty);
655+
else if (jl_is_typevar(typetype))
656+
exclude_typeofbottom = has_covariant_var((jl_datatype_t*)ttypes, (jl_tvar_t*)typetype);
657+
else
658+
exclude_typeofbottom = !jl_parameter_includes_bottom(typetype);
644659
}
645660
}
646661
// First check for intersections with methods defined on Type{T}, where T was a concrete type

0 commit comments

Comments
 (0)