Skip to content

Commit 11b6433

Browse files
committed
typemap: handle typeof(Union{}) as equivalent to Type{Union{}}
This is an odd inversion in the specificity lattice where supertype(T) is more specific than T (and type-equal to T). Handle that here by consistently normalizing to the more specific copy, to avoid complications later.
1 parent 5b579b8 commit 11b6433

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

src/codegen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ static inline jl_cgval_t ghostValue(jl_value_t *typ)
11531153
return jl_cgval_t(); // Undef{}
11541154
if (typ == (jl_value_t*)jl_typeofbottom_type) {
11551155
// normalize TypeofBottom to Type{Union{}}
1156-
typ = (jl_value_t*)jl_wrap_Type(jl_bottom_type);
1156+
typ = (jl_value_t*)jl_typeofbottom_type->super;
11571157
}
11581158
if (jl_is_type_type(typ)) {
11591159
// replace T::Type{T} with T, by assuming that T must be a leaftype of some sort

src/typemap.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "julia_assert.h"
1111

1212
#define MAX_METHLIST_COUNT 12 // this can strongly affect the sysimg size and speed!
13-
#define INIT_CACHE_SIZE 8 // must be a power-of-two
1413

1514
#ifdef __cplusplus
1615
extern "C" {
@@ -354,14 +353,19 @@ int jl_typemap_intersection_visitor(jl_typemap_t *map, int offs,
354353
//}
355354
if (jl_typeof(map) == (jl_value_t *)jl_typemap_level_type) {
356355
jl_typemap_level_t *cache = (jl_typemap_level_t*)map;
357-
jl_value_t *ty = NULL;
356+
jl_value_t *ty;
358357
size_t l = jl_nparams(ttypes);
359358
if (closure->va && l <= offs + 1) {
360359
ty = closure->va;
361360
}
362361
else if (l > offs) {
363362
ty = jl_tparam(ttypes, offs);
364363
}
364+
else {
365+
ty = NULL;
366+
}
367+
if (ty == (jl_value_t*)jl_typeofbottom_type)
368+
ty = (jl_value_t*)jl_assume(jl_typeofbottom_type)->super;
365369
if (ty) {
366370
while (jl_is_typevar(ty))
367371
ty = ((jl_tvar_t*)ty)->ub;
@@ -551,7 +555,7 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(
551555
if (jl_typeof(ml_or_cache) == (jl_value_t *)jl_typemap_level_type) {
552556
jl_typemap_level_t *cache = (jl_typemap_level_t*)ml_or_cache;
553557
// called object is the primary key for constructors, otherwise first argument
554-
jl_value_t *ty = NULL;
558+
jl_value_t *ty;
555559
jl_value_t *ttypes = jl_unwrap_unionall((jl_value_t*)search->types);
556560
JL_GC_PROMISE_ROOTED(ttypes);
557561
assert(jl_is_datatype(ttypes));
@@ -571,9 +575,14 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(
571575
else if (l > offs) {
572576
ty = jl_tparam(ttypes, offs);
573577
}
574-
// If there is a type at offs, look in the optimized caches
575-
if (!subtype) {
576-
if (ty && jl_is_any(ty))
578+
else {
579+
ty = NULL;
580+
}
581+
if (ty == (jl_value_t*)jl_typeofbottom_type)
582+
ty = (jl_value_t*)jl_assume(jl_typeofbottom_type)->super;
583+
// If there is a type at offs, look in the optimized leaf type caches
584+
if (ty && !subtype) {
585+
if (jl_is_any(ty))
577586
return jl_typemap_assoc_by_type(cache->any, search, offs + 1, subtype);
578587
if (isva) // in lookup mode, want to match Vararg exactly, not as a subtype
579588
ty = NULL;
@@ -836,7 +845,7 @@ static void jl_typemap_level_insert_(
836845
jl_value_t *ttypes = jl_unwrap_unionall((jl_value_t*)newrec->sig);
837846
size_t l = jl_nparams(ttypes);
838847
// compute the type at offset `offs` into `sig`, which may be a Vararg
839-
jl_value_t *t1 = NULL;
848+
jl_value_t *t1;
840849
int isva = 0;
841850
if (l <= offs + 1) {
842851
t1 = jl_tparam(ttypes, l - 1);
@@ -851,6 +860,11 @@ static void jl_typemap_level_insert_(
851860
else if (l > offs) {
852861
t1 = jl_tparam(ttypes, offs);
853862
}
863+
else {
864+
t1 = NULL;
865+
}
866+
if (t1 == (jl_value_t*)jl_typeofbottom_type)
867+
t1 = (jl_value_t*)jl_assume(jl_typeofbottom_type)->super;
854868
// If the type at `offs` is Any, put it in the Any list
855869
if (t1 && jl_is_any(t1)) {
856870
jl_typemap_insert_generic(map, &cache->any, (jl_value_t*)cache, newrec, offs+1, tparams);

test/precompile.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ try
171171
const layout2 = Any[Ptr{Int8}(0), Ptr{Int16}(1), Ptr{Int32}(-1)]
172172
const layout3 = collect(x.match for x in eachmatch(r"..", "abcdefghijk"))::Vector{SubString{String}}
173173
174+
# create a backedge that includes Type{Union{}}, to ensure lookup can handle that
175+
call_bottom() = show(stdout::IO, Union{})
176+
Core.Compiler.return_type(call_bottom, ())
177+
174178
# check that @ccallable works from precompiled modules
175179
Base.@ccallable Cint f35014(x::Cint) = x+Cint(1)
176180
end

0 commit comments

Comments
 (0)