Skip to content

Commit aa42963

Browse files
authored
inference: better align type_more_complex with _limit_type_size for Type (#51600)
A small further extension to #51512 to better align the internal behavior of the `_limit_type_size` and `type_more_complex` computations.
1 parent 3bb0392 commit aa42963

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

base/compiler/typelimits.jl

+24-6
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
128128
return Type{<:Type}
129129
end
130130
# try to peek into c to get a comparison object, but if we can't perhaps t is already simple enough on its own
131-
# (this is slightly more permissive than type_more_complex implements for the same case).
132131
if isType(c)
133132
ct = c.parameters[1]
134133
else
@@ -178,7 +177,7 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
178177
return Any
179178
end
180179
widert = t.name.wrapper
181-
if !(t <: widert)
180+
if !(t <: widert) # XXX: we should call has_free_typevars(t) here, but usually t does not have those wrappers by the time it got here
182181
# This can happen when a typevar has bounds too wide for its context, e.g.
183182
# `Complex{T} where T` is not a subtype of `Complex`. In that case widen even
184183
# faster to something safe to ensure the result is a supertype of the input.
@@ -229,20 +228,22 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
229228
return false # Bottom is as simple as they come
230229
elseif isa(t, DataType) && isempty(t.parameters)
231230
return false # fastpath: unparameterized types are always finite
232-
elseif tupledepth > 0 && is_derived_type_from_any(unwrap_unionall(t), sources, depth)
231+
elseif is_derived_type_from_any(unwrap_unionall(t), sources, depth)
233232
return false # t isn't something new
234233
end
235234
# peel off wrappers
236235
isvarargtype(t) && (t = unwrapva(t))
237236
isvarargtype(c) && (c = unwrapva(c))
238237
if isa(c, UnionAll)
239-
# allow wrapping type with fewer UnionAlls than comparison if in a covariant context
238+
# allow wrapping type with fewer UnionAlls than comparison only if in a covariant context
240239
if !isa(t, UnionAll) && tupledepth == 0
241240
return true
242241
end
243-
t = unwrap_unionall(t)
244242
c = unwrap_unionall(c)
245243
end
244+
if isa(t, UnionAll)
245+
t = unwrap_unionall(t)
246+
end
246247
# rules for various comparison types
247248
if isa(c, TypeVar)
248249
tupledepth = 1
@@ -265,7 +266,24 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
265266
# base case for data types
266267
if isa(t, DataType)
267268
tP = t.parameters
268-
if isa(c, DataType) && t.name === c.name
269+
if isType(t)
270+
# Type is fairly important, so do not widen it as fast as other types if avoidable
271+
tt = tP[1]
272+
ttu = unwrap_unionall(tt) # TODO: use argument_datatype(tt) after #50692 fixed
273+
if isType(c)
274+
ct = c.parameters[1]
275+
else
276+
ct = Union{}
277+
tupledepth == 0 && return true # cannot allow nesting
278+
end
279+
# allow creating variation within a nested Type, but not very deep
280+
if tupledepth > 1
281+
tupledepth = 1
282+
else
283+
tupledepth = 0
284+
end
285+
return type_more_complex(tt, ct, sources, depth + 1, tupledepth, 0)
286+
elseif isa(c, DataType) && t.name === c.name
269287
cP = c.parameters
270288
length(cP) < length(tP) && return true
271289
isempty(tP) && return false

test/compiler/inference.jl

+8-6
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ end
6060
# issue #42835
6161
@test !Core.Compiler.type_more_complex(Int, Any, Core.svec(), 1, 1, 1)
6262
@test !Core.Compiler.type_more_complex(Int, Type{Int}, Core.svec(), 1, 1, 1)
63-
@test Core.Compiler.type_more_complex(Type{Int}, Any, Core.svec(), 1, 1, 1) # maybe should be fixed?
63+
@test !Core.Compiler.type_more_complex(Type{Int}, Any, Core.svec(), 1, 1, 1)
64+
@test Core.Compiler.type_more_complex(Type{Type{Int}}, Any, Core.svec(), 1, 1, 1)
6465
@test Core.Compiler.limit_type_size(Type{Int}, Any, Union{}, 0, 0) == Type{Int}
6566
@test Core.Compiler.type_more_complex(Type{Type{Int}}, Type{Int}, Core.svec(Type{Int}), 1, 1, 1)
6667
@test Core.Compiler.type_more_complex(Type{Type{Int}}, Int, Core.svec(Type{Int}), 1, 1, 1)
@@ -80,15 +81,16 @@ end
8081
@test Core.Compiler.type_more_complex(Type{Type{Type{ComplexF32}}}, Type{Type{ComplexF32}}, Core.svec(Type{ComplexF32}), 1, 1, 1)
8182

8283
# n.b. Type{Type{Union{}} === Type{Core.TypeofBottom}
83-
@test Core.Compiler.type_more_complex(Type{Union{}}, Any, Core.svec(), 1, 1, 1)
84-
@test Core.Compiler.type_more_complex(Type{Type{Union{}}}, Any, Core.svec(), 1, 1, 1)
84+
@test !Core.Compiler.type_more_complex(Type{Union{}}, Any, Core.svec(), 1, 1, 1)
85+
@test !Core.Compiler.type_more_complex(Type{Type{Union{}}}, Any, Core.svec(), 1, 1, 1)
8586
@test Core.Compiler.type_more_complex(Type{Type{Type{Union{}}}}, Any, Core.svec(), 1, 1, 1)
8687
@test Core.Compiler.type_more_complex(Type{Type{Type{Union{}}}}, Type{Type{Union{}}}, Core.svec(Type{Type{Union{}}}), 1, 1, 1)
8788
@test Core.Compiler.type_more_complex(Type{Type{Type{Type{Union{}}}}}, Type{Type{Type{Union{}}}}, Core.svec(Type{Type{Type{Union{}}}}), 1, 1, 1)
8889

8990
@test !Core.Compiler.type_more_complex(Type{1}, Type{2}, Core.svec(), 1, 1, 1)
9091
@test Core.Compiler.type_more_complex(Type{Union{Float32,Float64}}, Union{Float32,Float64}, Core.svec(Union{Float32,Float64}), 1, 1, 1)
91-
@test Core.Compiler.type_more_complex(Type{Union{Float32,Float64}}, Union{Float32,Float64}, Core.svec(Union{Float32,Float64}), 0, 1, 1)
92+
@test Core.Compiler.type_more_complex(Type{Type{Union{Float32,Float64}}}, Union{Float32,Float64}, Core.svec(Union{Float32,Float64}), 1, 1, 1)
93+
@test Core.Compiler.type_more_complex(Type{Type{Union{Float32,Float64}}}, Type{Union{Float32,Float64}}, Core.svec(Type{Union{Float32,Float64}}), 1, 1, 1)
9294
@test Core.Compiler.type_more_complex(Type{<:Union{Float32,Float64}}, Type{Union{Float32,Float64}}, Core.svec(Union{Float32,Float64}), 1, 1, 1)
9395
@test Core.Compiler.type_more_complex(Type{<:Union{Float32,Float64}}, Any, Core.svec(Union{Float32,Float64}), 1, 1, 1)
9496

@@ -97,8 +99,8 @@ end
9799
@test Core.Compiler.type_more_complex(Tuple{Vararg{Tuple}}, Tuple{Vararg{Tuple{}}}, Core.svec(), 0, 0, 0)
98100

99101
let # 40336
100-
t = Type{Type{Int}}
101-
c = Type{Int}
102+
t = Type{Type{Type{Int}}}
103+
c = Type{Type{Int}}
102104
r = Core.Compiler.limit_type_size(t, c, c, 100, 100)
103105
@test t !== r && t <: r
104106
end

0 commit comments

Comments
 (0)