Improve return type inferrability of in for homogeneous tuples#61526
Open
Improve return type inferrability of in for homogeneous tuples#61526
in for homogeneous tuples#61526Conversation
Overload `_in_tuple` for `Tuple{Vararg{T}}` so that, when the element
type `T` is known not to intersect `Missing`, the return type is pinned
as `Bool` rather than `Union{Bool,Missing}`.
This is motivated by JET(LS), which reports diagnostics when a
non-`Bool` value appears in a branch condition. Without this change,
straightforward code like:
```julia
function get_valid_flags(xs::Vector{String})
flags = tuple(xs...)
"flag" in flags ? flags : nothing # non-boolean `Missing` found in boolean context (1/2 union split)
end
```
because the inferred return type of
`::String in ::Tuple{Vararg{String}}` is currently
`Union{Bool,Missing}`, even though elements are all `String` and it's
trivially clear that it never returns `missing`.
Implementation notes:
- Rather than adding a new `in` method for `Tuple{Vararg{T}}`, this
overloads `_in_tuple` instead. Adding a separate
`::Any in ::Tuple{Vararg{T}}` method would increase the number of
methods matching `x::Any in itr::Tuple` from 3 to 4, potentially
degrading inferrability at abstract call sites.
- The additional `hasintersect(T, Missing)` would no runtime cost: the
added `_in_tuple` is only compiled for concrete `T`, and in that case
the `typeintersect` result will be statically inlined.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overload
_in_tupleforTuple{Vararg{T}}so that, when the element typeTis known not to intersectMissing, the return type is pinned asBoolrather thanUnion{Bool,Missing}.This is motivated by JET(LS), which reports diagnostics when a non-
Boolvalue appears in a branch condition. Without this change, straightforward code like:because the inferred return type of
::String in ::Tuple{Vararg{String}}is currentlyUnion{Bool,Missing}, even though elements are allStringand it's trivially clear that it never returnsmissing.Implementation notes:
inmethod forTuple{Vararg{T}}, this overloads_in_tupleinstead. Adding a separate::Any in ::Tuple{Vararg{T}}method would increase the number of methods matchingx::Any in itr::Tuplefrom 3 to 4, potentially degrading inferrability at abstract call sites.hasintersect(T, Missing)would no runtime cost: the added_in_tupleis only compiled for concreteT, and in that case thetypeintersectresult will be statically inlined.