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

RFC: Avoid over-pessimization in apply_type_tfunc #27150

Merged
merged 1 commit into from
Jun 13, 2018
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
26 changes: 19 additions & 7 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -724,20 +724,34 @@ function apply_type_tfunc(@nospecialize(headtypetype), @nospecialize args...)
elseif isconstType(headtypetype)
headtype = headtypetype.parameters[1]
else
return Any
return Type
end
largs = length(args)
if headtype === Union
largs == 0 && return Const(Bottom)
largs == 1 && return args[1]
hasnonType = false
for i = 1:largs
ai = args[i]
if !isa(ai, Const) || !isa(ai.val, Type)
if isa(ai, Const)
if !isa(ai.val, Type)
if isa(ai.val, TypeVar)
hasnonType = true
else
return Union{}
end
end
else
if !isType(ai)
return Any
if !isa(ai, Type) || typeintersect(ai, Type) != Union{}
hasnonType = true
else
return Union{}
end
end
end
end
largs == 1 && return isa(args[1], Type) ? typeintersect(args[1], Type) : Type
hasnonType && return Type
ty = Union{}
allconst = true
for i = 1:largs
Expand All @@ -754,8 +768,7 @@ function apply_type_tfunc(@nospecialize(headtypetype), @nospecialize args...)
end
istuple = (headtype == Tuple)
if !istuple && !isa(headtype, UnionAll)
# TODO: return `Bottom` for trying to apply a non-UnionAll
return Any
return Union{}
end
uncertain = false
canconst = true
Expand All @@ -773,7 +786,6 @@ function apply_type_tfunc(@nospecialize(headtypetype), @nospecialize args...)
canconst = false
push!(tparams, ai.tv)
else
# TODO: return `Bottom` for trying to apply a non-UnionAll
uncertain = true
# These blocks improve type info but make compilation a bit slower.
# XXX
Expand Down
9 changes: 9 additions & 0 deletions test/compiler/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1581,3 +1581,12 @@ end

# Equivalence of Const(T.instance) and T for singleton types
@test Const(nothing) ⊑ Nothing && Nothing ⊑ Const(nothing)

# Don't pessimize apply_type to anything worse than Type and yield Bottom for invalid Unions
@test Core.Compiler.return_type(Core.apply_type, Tuple{Type{Union}}) == Type{Union{}}
@test Core.Compiler.return_type(Core.apply_type, Tuple{Type{Union},Any}) == Type
@test Core.Compiler.return_type(Core.apply_type, Tuple{Type{Union},Any,Any}) == Type
@test Core.Compiler.return_type(Core.apply_type, Tuple{Type{Union},Int}) == Union{}
@test Core.Compiler.return_type(Core.apply_type, Tuple{Type{Union},Any,Int}) == Union{}
@test Core.Compiler.return_type(Core.apply_type, Tuple{Any}) == Type
@test Core.Compiler.return_type(Core.apply_type, Tuple{Any,Any}) == Type