-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
RFC: Widen less aggressively in tmerge #23077
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2798,21 +2798,13 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb)) | |
if !(isa(typea,Type) || isa(typea,TypeVar)) || !(isa(typeb,Type) || isa(typeb,TypeVar)) | ||
return Any | ||
end | ||
if (typea <: Tuple) && (typeb <: Tuple) | ||
if isa(typea, DataType) && isa(typeb, DataType) && length(typea.parameters) == length(typeb.parameters) && !isvatuple(typea) && !isvatuple(typeb) | ||
return typejoin(typea, typeb) | ||
end | ||
if isa(typea, Union) || isa(typeb, Union) || (isa(typea,DataType) && length(typea.parameters)>3) || | ||
(isa(typeb,DataType) && length(typeb.parameters)>3) | ||
# widen tuples faster (see #6704), but not too much, to make sure we can infer | ||
# e.g. (t::Union{Tuple{Bool},Tuple{Bool,Int}})[1] | ||
return Tuple | ||
end | ||
end | ||
u = Union{typea, typeb} | ||
if unionlen(u) > MAX_TYPEUNION_LEN || type_too_complex(u, MAX_TYPE_DEPTH) | ||
# don't let type unions get too big | ||
# TODO: something smarter, like a common supertype | ||
if unionlen(u) > MAX_TYPEUNION_LEN | ||
u = typejoin(typea, typeb) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. perhaps do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To make this case convergent however, I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I completely understand the problem... if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Monotonicity here seems like it may depend on typejoin being associative, such that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, then There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can see from the implementation that at least There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Making There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct me if I'm wrong, but ensuring convergence requires monotonicity in the sense that julia> a´ = a = Ref{Int}
Ref{Int64}
julia> b = Ref{UInt}
Ref{UInt64}
julia> b´ = Ref{<:Integer}
Ref{#s1} where #s1<:Integer
julia> typejoin(a, b)
Ref
julia> typejoin(a, b´)
Ref{#s1} where #s1<:Integer
julia> a <: a´ && b <: b´
true
julia> typejoin(a, b) <: typejoin(a, b´)
false But turns out we're already using julia> a´ = a = Tuple{Int32, Ref{Int}}
Tuple{Int32,Ref{Int64}}
julia> b = Tuple{Int64, Ref{UInt}}
Tuple{Int64,Ref{UInt64}}
julia> b´ = Tuple{Int64, Ref{<:Integer}}
Tuple{Int64,Ref{#s30} where #s30<:Integer}
julia> Core.Inference.tmerge(a, b)
Tuple{Signed,Ref}
julia> Core.Inference.tmerge(a, b´)
Tuple{Signed,Ref{#s30} where #s30<:Integer}
julia> a <: a´ && b <: b´
true
julia> Core.Inference.tmerge(a, b) <: Core.Inference.tmerge(a, b´)
false Unless someone tells me I'm off track here and this is not an issue, my idea would be to first rethink There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, that cannot be the right interpretation of "monotonicity" in this context, there are too many cases where |
||
end | ||
if type_too_complex(u, MAX_TYPE_DEPTH) | ||
# helps convergence speed (large types that are changing value become very slow to | ||
# work with very quickly) | ||
return Any | ||
end | ||
return u | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume removing this doesn't reintroduce #6704? (it's partially handled by #21933 now, but I also don't handle Tuple correctly there – don't widen it fast enough – partially due to assuming that this code here existed)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't, at least not the code as posted there. I didn't try to find variations that might still cause problems, though.
Ah, I wasn't aware of that.