Skip to content

Commit 03fc530

Browse files
JeffBezansonKristofferC
authored andcommitted
fix #33954, recursion through field types in is_derived_type (#34223)
(cherry picked from commit 8b57f64)
1 parent 9bd498d commit 03fc530

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

base/compiler/typelimits.jl

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,6 @@ function is_derived_type(@nospecialize(t), @nospecialize(c), mindepth::Int)
5757
for p in cP
5858
is_derived_type(t, p, mindepth) && return true
5959
end
60-
if isconcretetype(c) && isbitstype(c)
61-
# see if it was extracted from a fieldtype
62-
# however, only look through types that can be inlined
63-
# to ensure monotonicity of derivation
64-
# since we know that for immutable, concrete, bits types,
65-
# the field types must have been constructed prior to the type,
66-
# it cannot have a reference cycle in the type graph
67-
cF = c.types
68-
for f in cF
69-
# often a parameter is also a field type; avoid searching twice
70-
if !contains_is(c.parameters, f)
71-
is_derived_type(t, f, mindepth) && return true
72-
end
73-
end
74-
end
7560
end
7661
return false
7762
end

src/datatype.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ static int references_name(jl_value_t *p, jl_typename_t *name) JL_NOTSAFEPOINT
306306
if (jl_is_datatype(p)) {
307307
if (((jl_datatype_t*)p)->name == name)
308308
return 1;
309+
if (((jl_datatype_t*)p)->layout && jl_datatype_nfields(p) == 0)
310+
return 0;
309311
size_t i, l = jl_nparams(p);
310312
for (i = 0; i < l; i++) {
311313
if (references_name(jl_tparam(p, i), name))
@@ -401,6 +403,7 @@ void jl_compute_field_offsets(jl_datatype_t *st)
401403
jl_value_t *fld = jl_svecref(w->types, i);
402404
if (references_name(fld, w->name)) {
403405
isinlinealloc = 0;
406+
isbitstype = 0;
404407
break;
405408
}
406409
}

test/compiler/inference.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,3 +2485,10 @@ end
24852485
# constant prop of `Symbol("")`
24862486
f_getf_computed_symbol(p) = getfield(p, Symbol("first"))
24872487
@test Base.return_types(f_getf_computed_symbol, Tuple{Pair{Int8,String}}) == [Int8]
2488+
2489+
# issue #33954
2490+
struct X33954
2491+
x::Ptr{X33954}
2492+
end
2493+
f33954(x) = rand(Bool) ? f33954((x,)) : x
2494+
@test Base.return_types(f33954, Tuple{X33954})[1] >: X33954

test/core.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7140,3 +7140,19 @@ end
71407140
struct SplatBadIterate; end
71417141
Base.iterate(s::SplatBadIterate, args...) = ()
71427142
@test_throws BoundsError (SplatBadIterate()...,)
7143+
7144+
# issue #33954, layout with circular type parameters but not fields
7145+
struct P33954{T}
7146+
end
7147+
struct A33954
7148+
x::P33954{A33954}
7149+
end
7150+
@test isbitstype(Tuple{A33954})
7151+
struct Q33954{T}
7152+
x::Int
7153+
end
7154+
struct B33954
7155+
x::Q33954{B33954}
7156+
end
7157+
@test_broken isbitstype(Tuple{B33954})
7158+
@test_broken isbitstype(B33954)

0 commit comments

Comments
 (0)