diff --git a/base/compiler/typelimits.jl b/base/compiler/typelimits.jl index 980cfe5f2115b..82c95dd9d0614 100644 --- a/base/compiler/typelimits.jl +++ b/base/compiler/typelimits.jl @@ -66,7 +66,10 @@ function is_derived_type(@nospecialize(t), @nospecialize(c), mindepth::Int) # it cannot have a reference cycle in the type graph cF = c.types for f in cF - is_derived_type(t, f, mindepth) && return true + # often a parameter is also a field type; avoid searching twice + if !contains_is(c.parameters, f) + is_derived_type(t, f, mindepth) && return true + end end end end diff --git a/base/essentials.jl b/base/essentials.jl index 6a7f1eb999473..cc21bd6c144bc 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -794,6 +794,9 @@ function invokelatest(@nospecialize(f), @nospecialize args...; kwargs...) Core._apply_latest(inner) end +# TODO: possibly make this an intrinsic +inferencebarrier(@nospecialize(x)) = Ref{Any}(x)[] + """ isempty(collection) -> Bool diff --git a/base/show.jl b/base/show.jl index d42e09296d2bb..29320479f7534 100644 --- a/base/show.jl +++ b/base/show.jl @@ -326,7 +326,10 @@ show(x) = show(stdout::IO, x) show(io::IO, @nospecialize(x)) = show_default(io, x) -function show_default(io::IO, @nospecialize(x)) +# avoid inferring show_default on the type of `x` +show_default(io::IO, @nospecialize(x)) = _show_default(io, inferencebarrier(x)) + +function _show_default(io::IO, @nospecialize(x)) t = typeof(x)::DataType show(io, t) print(io, '(') diff --git a/src/subtype.c b/src/subtype.c index 22313b4b430d4..f46b6e7bd0d6b 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -193,6 +193,7 @@ static int obviously_egal(jl_value_t *a, jl_value_t *b) if (jl_is_datatype(a)) { jl_datatype_t *ad = (jl_datatype_t*)a, *bd = (jl_datatype_t*)b; if (ad->name != bd->name) return 0; + if (ad->isconcretetype || bd->isconcretetype) return 0; size_t i, np = jl_nparams(ad); if (np != jl_nparams(bd)) return 0; for(i=0; i < np; i++) { diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index d63ead4eeea1c..74211a8453746 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -2325,3 +2325,26 @@ h28762(::Type{X}) where {X} = Array{f28762(X)}(undef, 0) @inferred g28762(Array) @inferred h28762(Array) end + +# issue #31663 +module I31663 +abstract type AbstractNode end + +struct Node{N1<:AbstractNode, N2<:AbstractNode} <: AbstractNode + a::N1 + b::N2 +end + +struct Leaf <: AbstractNode +end + +function gen_nodes(qty::Integer) :: AbstractNode + @assert qty > 0 + result = Leaf() + for i in 1:qty + result = Node(result, Leaf()) + end + return result +end +end +@test count(==('}'), string(I31663.gen_nodes(50))) == 1275