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

make Tuple{Union{}} unconstructable #49111

Merged
merged 1 commit into from
Apr 10, 2023
Merged

make Tuple{Union{}} unconstructable #49111

merged 1 commit into from
Apr 10, 2023

Conversation

vtjnash
Copy link
Sponsor Member

@vtjnash vtjnash commented Mar 22, 2023

Type intersection assumed it was equal to Union{}, so this makes it unconstructable so that holds true. This is similar to what the NamedTuple constructor does.

Secondarily, this fixes an inference bug where it would create Vararg{Union{}} and then incorrectly handle that fieldtype.

There is an upgrade helper for packages that rely on this not throwing an exception of Base.Iterators.TupleOrBottom(p...), though (judging by changes in Base), I don't expect it to be widely needed. We can do a PkgEval run though to verify.

@vtjnash vtjnash added needs nanosoldier run This PR should have benchmarks run on it needs pkgeval Tests for all registered packages should be run with this change labels Mar 22, 2023
@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Mar 23, 2023

@nanosoldier runbenchmarks(!"scalar", vs=":master")

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Mar 23, 2023

@nanosoldier runtests()

@test_throws ErrorException("Tuple field type cannot be Union{}") Tuple{Int, Vararg{Union{},1}}
@test_throws ErrorException("Tuple field type cannot be Union{}") Tuple{Vararg{Union{},1}}
@test Tuple{} <: Tuple{Vararg{Union{},N}} where N
@test !(Tuple{} >: Tuple{Vararg{Union{},N}} where N)
Copy link
Member

Choose a reason for hiding this comment

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

Why is that? Is there an N for which the LHS is not >: the RHS? Isn't N==0 the only admissible choice?

Copy link
Sponsor Member Author

@vtjnash vtjnash Mar 23, 2023

Choose a reason for hiding this comment

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

yeah, subtyping cannot be allowed to fully know that though, since we don't really want the concrete type Tuple{} to be equal to a non-concrete type

Copy link
Member

@N5N3 N5N3 Mar 23, 2023

Choose a reason for hiding this comment

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

Perhaps we'd better normalize Tuple{A,B,C,Vararg{Union{},N}} where N to Tuple{A,B,C} after this change?

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

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

No, that makes a different type, where N is free

Copy link
Member

Choose a reason for hiding this comment

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

What about Tuple{} >: Tuple{Vararg{Union{}}}? There's a check for <:, but should these be ==?

Copy link
Sponsor Member Author

@vtjnash vtjnash Mar 24, 2023

Choose a reason for hiding this comment

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

Tuple{Vararg{Union{}}} is invalid (it is just Tuple{} now)

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

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

I guess that raises the possibility of making Vararg{Union{}} itself also directly throw an error. I was trying to be conservative in allowing Union{} but constructing a different sort of object. There could be a case to be made that Union{} should not appear their either though (which would allow deleting several more tests as non-applicable also)

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here.

@maleadt
Copy link
Member

maleadt commented Mar 23, 2023

PkgEval crashed.

@nanosoldier runtests()

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Mar 23, 2023

@nanosoldier runbenchmarks(["string", "join"], vs=":master")

@vtjnash vtjnash removed the needs pkgeval Tests for all registered packages should be run with this change label Mar 23, 2023
@nanosoldier
Copy link
Collaborator

Your package evaluation job has completed - possible new issues were detected.
A full report can be found here.

@martinholters
Copy link
Member

From MCMCChains:

│ ERROR: Tuple field type cannot be Union{}
│ Stacktrace:
│   [1] eltypes(t::Tuple{Vector{Union{}}})
│     @ Base.Broadcast ./broadcast.jl:739

And indeed, on master:

julia> Base.Broadcast.eltypes((Union{}[],))
Tuple{Union{}}

Should that be reworked to return (types...,) instead of Tuple{types...} to deal with the possibility of a Union{} in types?

@N5N3
Copy link
Member

N5N3 commented Mar 24, 2023

Perhaps we'd better rewake #39295 and drop Broadcast.eltypes?
Even we return a (...,) instead of a Tuple{...,}, Broadcast.combine_eltypes still needs to handle possible Union{}.

@martinholters
Copy link
Member

Ah, right, the result of eltypes is passed to Base._return_type. But then we know the result is Union{} if any of the arguments is Union{} (right?), so eltypes could bail out and return Union{} instead of Tuple{..., Union{}, ...} and then combine_eltypes could skip Base._return_type and return Union{} directlly. Seems like a change sufficiently small to include here.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Mar 24, 2023

Right, I just forgot to fix up a couple calls. Before:

julia> Base.promote_op(tuple, Union{}, Int)
Tuple{Union{}, Int64}

after

julia> Base.promote_op(tuple, Union{}, Int)
Union{}

@nanosoldier runtests(["PersistenceDiagrams", "MLJModels", "Observers", "MLJTestInterface", "DynamicSparseArrays", "CGcoefficient", "GeoClustering", "Tidier", "MLJ", "QEDbase", "Concorde", "DASSL", "GeneratorArrays", "TMLE", "Nullables", "GLFixedEffectModels", "UnivariateFunctions", "NodeCall", "FunctionalTables", "QuantumTomography", "MLJTestIntegration", "EnlilGrids", "Resample", "MCMCChains", "Plasmo", "AlgebraOfGraphics", "PiecewiseDeterministicMarkovProcesses", "VoronoiFVM", "MakieThemes", "ParameterEstimation", "ConcreteStructs", "ConformalPrediction", "OMEinsum", "PDFHighlights", "BinaryTraits", "HomalgProject", "POMDPStressTesting", "StochasticIntegrals", "GenerativeTopographicMapping", "FixedEffectModels", "PreprocessMD", "SimpleANOVA", "Bloqade", "ContinuousWavelets", "Tapestree", "NodalPolynomialSpaces", "RealPolynomialRoots", "Anatta", "FeatureTransforms", "StochasticAD", "WhereTraits", "EvoTrees", "SBMLToolkit", "PANDA", "CooperativeGames", "Ai4EComponentLib", "HierarchicalUtils", "FastAI", "MLJLinearModels", "GraphNeuralNetworks", "UnfoldMakie", "AlgebraicAgents"])

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Mar 24, 2023

@nanosoldier runbenchmarks(["string", "join"], vs=":master")

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Mar 24, 2023

@nanosoldier runbenchmarks("string" && "join", vs=":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - no performance regressions were detected. A full report can be found here.

@nanosoldier
Copy link
Collaborator

Your package evaluation job has completed - possible new issues were detected.
A full report can be found here.

@vtjnash vtjnash removed the needs nanosoldier run This PR should have benchmarks run on it label Mar 28, 2023
@vtjnash vtjnash added the status:merge me PR is reviewed. Merge when all tests are passing label Apr 7, 2023
Type intersection assumed it was equal to Union{}, so this makes it
unconstructable so that holds true. This is similar to what the
NamedTuple constructor does.

Secondarily, this fixes an inference bug where it would create
Vararg{Union{}} and then incorrectly handle that fieldtype.

- Fixes #32392
- Addresses part of the concerns discussed in
  #24614 (comment)
- Addresses part of the issues presented in
  #26175
- May allow improving jl_type_equality_is_identity
  (https://github.com/JuliaLang/julia/pull/49017/files#diff-882927c6e612596e22406ae0d06adcee88a9ec05e8b61ad81b48942e2cb266e9R986)
- May allow improving intersection (finish_unionall can be more
  aggressive at computing varval for any typevars that appears in
  covariant position and has lb=Union{} and ub=leaf type)
@George9000
Copy link
Contributor

@vtjnash Similar error as above in testset REPL reported on buildkite and on my local build (macOS ARM):

details
Error in testset REPL:
Error During Test at /Users/foo/applications/julia/test/testdefs.jl:21
  Got exception outside of a @test
  LoadError: Tuple field type cannot be Union{}
  Stacktrace:
    [1] complete_methods!(out::Vector{REPL.REPLCompletions.Completion}, funct::Any, args_ex::Vector{Any}, kwargs_ex::Set{Symbol}, max_method_completions::Int64, exact_nargs::Bool)
      @ REPL.REPLCompletions ~/applications/julia/usr/share/julia/stdlib/v1.10/REPL/src/REPLCompletions.jl:708
    [2] complete_methods
      @ ~/applications/julia/usr/share/julia/stdlib/v1.10/REPL/src/REPLCompletions.jl:588 [inlined]
    [3] completions(string::String, pos::Int64, context_module::Module, shift::Bool)
      @ REPL.REPLCompletions ~/applications/julia/usr/share/julia/stdlib/v1.10/REPL/src/REPLCompletions.jl:1053
    [4] completions
      @ ~/applications/julia/usr/share/julia/stdlib/v1.10/REPL/src/REPLCompletions.jl:967 [inlined]
    [5] test_complete(s::String)
      @ Main.Test72Main_REPL.REPLCompletionsTest ~/applications/julia/usr/share/julia/stdlib/v1.10/REPL/test/replcompletions.jl:154
    [6] top-level scope
      @ ~/applications/julia/usr/share/julia/stdlib/v1.10/REPL/test/replcompletions.jl:518
    [7] include(mod::Module, _path::String)
      @ Base ./Base.jl:488
    [8] include(x::String)
      @ Main.Test72Main_REPL.REPLCompletionsTest ~/applications/julia/usr/share/julia/stdlib/v1.10/REPL/test/runtests.jl:9
    [9] top-level scope
      @ ~/applications/julia/usr/share/julia/stdlib/v1.10/REPL/test/runtests.jl:10
   [10] include
      @ ./Base.jl:488 [inlined]
   [11] macro expansion
      @ ~/applications/julia/test/testdefs.jl:29 [inlined]
   [12] macro expansion
      @ ~/applications/julia/usr/share/julia/stdlib/v1.10/Test/src/Test.jl:1504 [inlined]
   [13] macro expansion
      @ ~/applications/julia/test/testdefs.jl:23 [inlined]
   [14] macro expansion
      @ ./timing.jl:502 [inlined]
   [15] runtests(name::String, path::String, isolate::Bool; seed::UInt128)
      @ Main ~/applications/julia/test/testdefs.jl:21
   [16] runtests
      @ ~/applications/julia/test/testdefs.jl:5 [inlined]
   [17] #invokelatest#2
      @ ./essentials.jl:869 [inlined]
   [18] invokelatest
      @ ./essentials.jl:864 [inlined]
   [19] #153
      @ ~/applications/julia/usr/share/julia/stdlib/v1.10/Distributed/src/remotecall.jl:425 [inlined]
   [20] run_work_thunk(thunk::Distributed.var"#153#154"{typeof(runtests), Tuple{String, String}, Base.Pairs{Symbol, UInt128, Tuple{Symbol}, @NamedTuple{seed::UInt128}}}, print_error::Bool)
      @ Distributed ~/applications/julia/usr/share/julia/stdlib/v1.10/Distributed/src/process_messages.jl:70
   [21] remotecall_fetch(::Function, ::Distributed.LocalProcess, ::String, ::Vararg{String}; kwargs::Base.Pairs{Symbol, UInt128, Tuple{Symbol}, @NamedTuple{seed::UInt128}})
      @ Distributed ~/applications/julia/usr/share/julia/stdlib/v1.10/Distributed/src/remotecall.jl:450
   [22] remotecall_fetch(::Function, ::Int64, ::String, ::Vararg{String}; kwargs::Base.Pairs{Symbol, UInt128, Tuple{Symbol}, @NamedTuple{seed::UInt128}})
      @ Distributed ~/applications/julia/usr/share/julia/stdlib/v1.10/Distributed/src/remotecall.jl:492
   [23] macro expansion
      @ ~/applications/julia/test/runtests.jl:256 [inlined]
   [24] (::var"#39#49"{Vector{Task}, var"#print_testworker_errored#45"{ReentrantLock, Int64, Int64}, var"#print_testworker_stats#43"{ReentrantLock, Int64, Int64, Int64, Int64, Int64, Int64}, Vector{Any}, Dict{String, DateTime}})()
      @ Main ./task.jl:514
  in expression starting at /Users/foo/applications/julia/usr/share/julia/stdlib/v1.10/REPL/test/replcompletions.jl:517
  in expression starting at /Users/foo/applications/julia/usr/share/julia/stdlib/v1.10/REPL/test/runtests.jl:9
ERROR: LoadError: Test run finished with errors
in expression starting at /Users/foo/applications/julia/test/runtests.jl:93
gmake[1]: *** [Makefile:25: REPL] Error 1
gmake: *** [Makefile:615: test-REPL] Error 2

@giordano giordano removed the status:merge me PR is reviewed. Merge when all tests are passing label Apr 11, 2023
vtjnash added a commit that referenced this pull request Apr 17, 2023
Xnartharax pushed a commit to Xnartharax/julia that referenced this pull request Apr 19, 2023
Type intersection assumed it was equal to Union{}, so this makes it
unconstructable so that holds true. This is similar to what the
NamedTuple constructor does.

Secondarily, this fixes an inference bug where it would create
Vararg{Union{}} and then incorrectly handle that fieldtype.

- Fixes JuliaLang#32392
- Addresses part of the concerns discussed in
  JuliaLang#24614 (comment)
- Addresses part of the issues presented in
  JuliaLang#26175
- May allow improving jl_type_equality_is_identity
  (https://github.com/JuliaLang/julia/pull/49017/files#diff-882927c6e612596e22406ae0d06adcee88a9ec05e8b61ad81b48942e2cb266e9R986)
- May allow improving intersection (finish_unionall can be more
  aggressive at computing varval for any typevars that appears in
  covariant position and has lb=Union{} and ub=leaf type)
vtjnash added a commit that referenced this pull request Apr 20, 2023
…ion{}} otherwise (#49393)

This was a primary motivation for #49111. Previously, we'd see some
some method specializations such as `convert(::Type{T}, ::T) where
T<:Float64` (apparently from inference of some tuple convert
specializations), which were not necessary to have.
benlorenz added a commit to benlorenz/libcxxwrap-julia that referenced this pull request May 3, 2023
this was changed in JuliaLang/julia#49111

for older julia versions this cast should be a no-op
barche pushed a commit to JuliaInterop/libcxxwrap-julia that referenced this pull request May 3, 2023
this was changed in JuliaLang/julia#49111

for older julia versions this cast should be a no-op
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

typeintersect bug with NTuple
7 participants