Skip to content

Commit

Permalink
allow concrete-eval for Union-type arguments
Browse files Browse the repository at this point in the history
By allowing `hasuniquerep` to analyze `Union`-types.
Motivated by <aviatesk/JET.jl#444>.
  • Loading branch information
aviatesk committed Jan 10, 2023
1 parent 88030b0 commit c29b9f7
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 5 deletions.
3 changes: 1 addition & 2 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,7 @@ julia> Base.isbitsunion(Union{Float64, String})
false
```
"""
isbitsunion(u::Union) = allocatedinline(u)
isbitsunion(x) = false
isbitsunion(@nospecialize x) = isa(x, Union) && allocatedinline(x)

function _unsetindex!(A::Array{T}, i::Int) where {T}
@inline
Expand Down
8 changes: 5 additions & 3 deletions base/compiler/typeutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ function hasuniquerep(@nospecialize t)
isa(t, TypeVar) && return false # TypeVars are identified by address, not equality
iskindtype(typeof(t)) || return true # non-types are always compared by egal in the type system
isconcretetype(t) && return true # these are also interned and pointer comparable
if isa(t, DataType) && t.name !== Tuple.name && !isvarargtype(t) # invariant DataTypes
return _all(hasuniquerep, t.parameters)
if isa(t, Union)
return hasuniquerep(t.a) && hasuniquerep(t.b)
elseif isa(t, DataType) && t.name !== Tuple.name && !isvarargtype(t) # invariant DataTypes
return all(hasuniquerep, t.parameters)
end
return false
end

"""
isTypeDataType(@nospecialize t) -> Bool
isTypeDataType(t) -> Bool
For a type `t` test whether ∀S s.t. `isa(S, rewrap_unionall(Type{t}, ...))`,
we have `isa(S, DataType)`. In particular, if a statement is typed as `Type{t}`
Expand Down
5 changes: 5 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4709,3 +4709,8 @@ end
@Base.constprop :aggressive type_level_recurse2(x...) = type_level_recurse1(x...)
type_level_recurse_entry() = Val{type_level_recurse1(1)}()
@test Base.return_types(type_level_recurse_entry, ()) |> only == Val{1}

# `isconstType` for `Union`-types
@test Base.return_types((Type{Union{Int,UInt}},)) do T
Base.allocatedinline(T) ? nothing : missing
end |> only === Nothing

0 comments on commit c29b9f7

Please sign in to comment.