Skip to content

Commit

Permalink
inference: better align type_more_complex with _limit_type_size for T…
Browse files Browse the repository at this point in the history
…ype (#51600)

A small further extension to #51512 to better align the internal
behavior of the `_limit_type_size` and `type_more_complex` computations.
  • Loading branch information
vtjnash authored Oct 7, 2023
1 parent 3bb0392 commit aa42963
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
30 changes: 24 additions & 6 deletions base/compiler/typelimits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
return Type{<:Type}
end
# try to peek into c to get a comparison object, but if we can't perhaps t is already simple enough on its own
# (this is slightly more permissive than type_more_complex implements for the same case).
if isType(c)
ct = c.parameters[1]
else
Expand Down Expand Up @@ -178,7 +177,7 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec
return Any
end
widert = t.name.wrapper
if !(t <: widert)
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
# This can happen when a typevar has bounds too wide for its context, e.g.
# `Complex{T} where T` is not a subtype of `Complex`. In that case widen even
# faster to something safe to ensure the result is a supertype of the input.
Expand Down Expand Up @@ -229,20 +228,22 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
return false # Bottom is as simple as they come
elseif isa(t, DataType) && isempty(t.parameters)
return false # fastpath: unparameterized types are always finite
elseif tupledepth > 0 && is_derived_type_from_any(unwrap_unionall(t), sources, depth)
elseif is_derived_type_from_any(unwrap_unionall(t), sources, depth)
return false # t isn't something new
end
# peel off wrappers
isvarargtype(t) && (t = unwrapva(t))
isvarargtype(c) && (c = unwrapva(c))
if isa(c, UnionAll)
# allow wrapping type with fewer UnionAlls than comparison if in a covariant context
# allow wrapping type with fewer UnionAlls than comparison only if in a covariant context
if !isa(t, UnionAll) && tupledepth == 0
return true
end
t = unwrap_unionall(t)
c = unwrap_unionall(c)
end
if isa(t, UnionAll)
t = unwrap_unionall(t)
end
# rules for various comparison types
if isa(c, TypeVar)
tupledepth = 1
Expand All @@ -265,7 +266,24 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
# base case for data types
if isa(t, DataType)
tP = t.parameters
if isa(c, DataType) && t.name === c.name
if isType(t)
# Type is fairly important, so do not widen it as fast as other types if avoidable
tt = tP[1]
ttu = unwrap_unionall(tt) # TODO: use argument_datatype(tt) after #50692 fixed
if isType(c)
ct = c.parameters[1]
else
ct = Union{}
tupledepth == 0 && return true # cannot allow nesting
end
# allow creating variation within a nested Type, but not very deep
if tupledepth > 1
tupledepth = 1
else
tupledepth = 0
end
return type_more_complex(tt, ct, sources, depth + 1, tupledepth, 0)
elseif isa(c, DataType) && t.name === c.name
cP = c.parameters
length(cP) < length(tP) && return true
isempty(tP) && return false
Expand Down
14 changes: 8 additions & 6 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ end
# issue #42835
@test !Core.Compiler.type_more_complex(Int, Any, Core.svec(), 1, 1, 1)
@test !Core.Compiler.type_more_complex(Int, Type{Int}, Core.svec(), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Int}, Any, Core.svec(), 1, 1, 1) # maybe should be fixed?
@test !Core.Compiler.type_more_complex(Type{Int}, Any, Core.svec(), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Type{Int}}, Any, Core.svec(), 1, 1, 1)
@test Core.Compiler.limit_type_size(Type{Int}, Any, Union{}, 0, 0) == Type{Int}
@test Core.Compiler.type_more_complex(Type{Type{Int}}, Type{Int}, Core.svec(Type{Int}), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Type{Int}}, Int, Core.svec(Type{Int}), 1, 1, 1)
Expand All @@ -80,15 +81,16 @@ end
@test Core.Compiler.type_more_complex(Type{Type{Type{ComplexF32}}}, Type{Type{ComplexF32}}, Core.svec(Type{ComplexF32}), 1, 1, 1)

# n.b. Type{Type{Union{}} === Type{Core.TypeofBottom}
@test Core.Compiler.type_more_complex(Type{Union{}}, Any, Core.svec(), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Type{Union{}}}, Any, Core.svec(), 1, 1, 1)
@test !Core.Compiler.type_more_complex(Type{Union{}}, Any, Core.svec(), 1, 1, 1)
@test !Core.Compiler.type_more_complex(Type{Type{Union{}}}, Any, Core.svec(), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Type{Type{Union{}}}}, Any, Core.svec(), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Type{Type{Union{}}}}, Type{Type{Union{}}}, Core.svec(Type{Type{Union{}}}), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Type{Type{Type{Union{}}}}}, Type{Type{Type{Union{}}}}, Core.svec(Type{Type{Type{Union{}}}}), 1, 1, 1)

@test !Core.Compiler.type_more_complex(Type{1}, Type{2}, Core.svec(), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Union{Float32,Float64}}, Union{Float32,Float64}, Core.svec(Union{Float32,Float64}), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Union{Float32,Float64}}, Union{Float32,Float64}, Core.svec(Union{Float32,Float64}), 0, 1, 1)
@test Core.Compiler.type_more_complex(Type{Type{Union{Float32,Float64}}}, Union{Float32,Float64}, Core.svec(Union{Float32,Float64}), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{Type{Union{Float32,Float64}}}, Type{Union{Float32,Float64}}, Core.svec(Type{Union{Float32,Float64}}), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{<:Union{Float32,Float64}}, Type{Union{Float32,Float64}}, Core.svec(Union{Float32,Float64}), 1, 1, 1)
@test Core.Compiler.type_more_complex(Type{<:Union{Float32,Float64}}, Any, Core.svec(Union{Float32,Float64}), 1, 1, 1)

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

let # 40336
t = Type{Type{Int}}
c = Type{Int}
t = Type{Type{Type{Int}}}
c = Type{Type{Int}}
r = Core.Compiler.limit_type_size(t, c, c, 100, 100)
@test t !== r && t <: r
end
Expand Down

0 comments on commit aa42963

Please sign in to comment.