Skip to content

Commit 32423a8

Browse files
authored
handle unbound vars in NTuple fields (#55405)
Comparing objects by `==` will happily answer nonsense for malformed type comparisons, such as `unwrap_unionall(A) == A`. Avoid forming that query. Additionally, need to recourse through Vararg when examining type structure to make decisions. Fix #55076 Fix #55189
1 parent f276757 commit 32423a8

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

src/builtins.c

+6
Original file line numberDiff line numberDiff line change
@@ -2084,6 +2084,12 @@ static int references_name(jl_value_t *p, jl_typename_t *name, int affects_layou
20842084
return references_name(((jl_uniontype_t*)p)->a, name, affects_layout, freevars) ||
20852085
references_name(((jl_uniontype_t*)p)->b, name, affects_layout, freevars);
20862086
}
2087+
if (jl_is_vararg(p)) {
2088+
jl_value_t *T = ((jl_vararg_t*)p)->T;
2089+
jl_value_t *N = ((jl_vararg_t*)p)->N;
2090+
return (T && references_name(T, name, affects_layout, freevars)) ||
2091+
(N && references_name(N, name, affects_layout, freevars));
2092+
}
20872093
if (jl_is_typevar(p))
20882094
return 0; // already checked by unionall, if applicable
20892095
if (jl_is_datatype(p)) {

src/jltypes.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1961,7 +1961,7 @@ static jl_value_t *jl_tupletype_fill(size_t n, jl_value_t *t, int check, int not
19611961
t = normalize_unionalls(t);
19621962
p = t;
19631963
jl_value_t *tw = extract_wrapper(t);
1964-
if (tw && t != tw && jl_types_equal(t, tw))
1964+
if (tw && t != tw && !jl_has_free_typevars(t) && jl_types_equal(t, tw))
19651965
t = tw;
19661966
p = t;
19671967
check = 0; // remember that checks are already done now
@@ -2045,7 +2045,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
20452045
// normalize types equal to wrappers (prepare for Typeofwrapper)
20462046
jl_value_t *tw = extract_wrapper(pi);
20472047
if (tw && tw != pi && (tn != jl_type_typename || jl_typeof(pi) == jl_typeof(tw)) &&
2048-
jl_types_equal(pi, tw)) {
2048+
!jl_has_free_typevars(pi) && jl_types_equal(pi, tw)) {
20492049
iparams[i] = tw;
20502050
if (p) jl_gc_wb(p, tw);
20512051
}
@@ -2717,7 +2717,7 @@ jl_vararg_t *jl_wrap_vararg(jl_value_t *t, jl_value_t *n, int check, int nothrow
27172717
if (valid) {
27182718
t = normalize_unionalls(t);
27192719
jl_value_t *tw = extract_wrapper(t);
2720-
if (tw && t != tw && jl_types_equal(t, tw))
2720+
if (tw && t != tw && !jl_has_free_typevars(t) && jl_types_equal(t, tw))
27212721
t = tw;
27222722
}
27232723
}

test/core.jl

+7
Original file line numberDiff line numberDiff line change
@@ -7495,6 +7495,13 @@ struct A43411{S, T}
74957495
end
74967496
@test isbitstype(A43411{(:a,), Tuple{Int}})
74977497

7498+
# issue #55189
7499+
struct A55189{N}
7500+
children::NTuple{N,A55189{N}}
7501+
end
7502+
@test fieldtype(A55189{2}, 1) === Tuple{A55189{2}, A55189{2}}
7503+
@assert !isbitstype(A55189{2})
7504+
74987505
# issue #44614
74997506
struct T44614_1{T}
75007507
m::T

0 commit comments

Comments
 (0)