Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inference: better align type_more_complex with _limit_type_size for Type #51600

Merged
merged 1 commit into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading