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: fix vararg normalization in rewrap #39134

Merged
merged 1 commit into from
Jan 10, 2021
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
9 changes: 5 additions & 4 deletions base/compiler/typelattice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ function ⊑(@nospecialize(a), @nospecialize(b))
(a === Any || b === NOT_FOUND) && return false
a === Union{} && return true
b === Union{} && return false
@assert !isa(a, TypeVar) "invalid lattice item"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is somewhat hot. Move this check all the way down to the === check?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think a pointer comparison will affect this, relative to the many other egal and subtyping test it does

@assert !isa(b, TypeVar) "invalid lattice item"
if isa(a, Conditional)
if isa(b, Conditional)
return issubconditional(a, b)
Expand Down Expand Up @@ -177,11 +179,10 @@ function ⊑(@nospecialize(a), @nospecialize(b))
return false
elseif isa(a, PartialTypeVar) && b === TypeVar
return true
elseif !(isa(a, Type) || isa(a, TypeVar)) ||
!(isa(b, Type) || isa(b, TypeVar))
return a === b
else
elseif isa(a, Type) && isa(b, Type)
return a <: b
else # handle this conservatively in the remaining cases
return a === b
end
end

Expand Down
2 changes: 1 addition & 1 deletion base/compiler/typeutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#####################

function rewrap(@nospecialize(t), @nospecialize(u))
if isa(t, TypeVar) || isa(t, Type)
if isa(t, TypeVar) || isa(t, Type) || isa(t, Core.TypeofVararg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did add a specialization of rewrap_unionall that handles this case (since anything else would be breaking), but I'm not all that convinced that rewrap_unionall should actually work on Vararg. In many cases it's the wrong thing to do. Maybe just make the Vararg case explicit here, since this is an internal function? Alternatively, I think there's only one or two callsites of this that allow a Vararg, so maybe they should use a different entrypoint.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the || already makes it pretty explicit. We can consider other designs later as continued clean up, but this seems to fix CI regression for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright

return rewrap_unionall(t, u)
end
return t
Expand Down
8 changes: 8 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ isdispatchelem(@nospecialize x) = !isa(x, Type) || Core.Compiler.isdispatchelem(
using Random, Core.IR
using InteractiveUtils: code_llvm

f39082(x::Vararg{T}) where {T <: Number} = x[1]
let ast = only(code_typed(f39082, Tuple{Vararg{Rational}}))[1]
@test ast.slottypes == Any[Const(f39082), Tuple{Vararg{Rational}}]
end
let ast = only(code_typed(f39082, Tuple{Rational, Vararg{Rational}}))[1]
@test ast.slottypes == Any[Const(f39082), Tuple{Rational, Vararg{Rational}}]
end

# demonstrate some of the type-size limits
@test Core.Compiler.limit_type_size(Ref{Complex{T} where T}, Ref, Ref, 100, 0) == Ref
@test Core.Compiler.limit_type_size(Ref{Complex{T} where T}, Ref{Complex{T} where T}, Ref, 100, 0) == Ref{Complex{T} where T}
Expand Down