From 958a72f8daeb0b08d779a58caca608a7072ed248 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Wed, 27 Dec 2023 19:44:04 -0600 Subject: [PATCH 1/5] remove dependence on Julia internal `Core.Compiler.return_type` --- .gitignore | 2 ++ src/Dictionaries.jl | 14 ++++++++++++++ src/Dictionary.jl | 4 ++-- src/broadcast.jl | 4 ++-- src/map.jl | 6 +++--- test/map.jl | 4 ++-- 6 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fc6527 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Manifest.toml + diff --git a/src/Dictionaries.jl b/src/Dictionaries.jl index 50d9f10..49baca3 100644 --- a/src/Dictionaries.jl +++ b/src/Dictionaries.jl @@ -13,6 +13,20 @@ export dictionary, index, distinct, disjoint, isdictequal, filterview, sortkeys, export issettable, isinsertable, set!, unset! export istokenizable, tokentype, tokens, tokenized, gettoken, gettokenvalue, istokenassigned, settokenvalue!, gettoken!, deletetoken!, sharetokens +""" + return_type(f, types)::DataType + +Find the return type of `f` called with `types`. + +!!! note + Currently, this method depends on `code_typed`. +""" +function return_type(f, types)::DataType + return last(only(code_typed(f, types; + optimize=false, + debuginfo=:none))) +end + include("AbstractDictionary.jl") include("AbstractIndices.jl") diff --git a/src/Dictionary.jl b/src/Dictionary.jl index 2fbcd03..f00bd7d 100644 --- a/src/Dictionary.jl +++ b/src/Dictionary.jl @@ -220,8 +220,8 @@ function _dictionary(key, value, ::Type{Dictionary}, iter) tmp = iterate(iter) if tmp === nothing IT = Base.@default_eltype(iter) - I = Core.Compiler.return_type(first, Tuple{IT}) - T = Core.Compiler.return_type(last, Tuple{IT}) + I = return_type(first, Tuple{IT}) + T = return_type(last, Tuple{IT}) return Dictionary{I, T}() end (x, s) = tmp diff --git a/src/broadcast.jl b/src/broadcast.jl index 3cbdded..a394cff 100644 --- a/src/broadcast.jl +++ b/src/broadcast.jl @@ -19,7 +19,7 @@ _data(d::BroadcastedDictionary) = getfield(d, :data) sharetokens = _sharetokens(dicts...) I = keytype(dicts[1]) Ts = Base.Broadcast.eltypes(data) - T = Core.Compiler.return_type(f, Ts) + T = return_type(f, Ts) return BroadcastedDictionary{I, T, typeof(f), typeof(data)}(f, data, sharetokens) end @@ -130,4 +130,4 @@ end Base.Broadcast.materialize(d::BroadcastedDictionary) = copy(d) Base.Broadcast.materialize!(out::AbstractDictionary, d::BroadcastedDictionary) = copyto!(out, d) -Base.Broadcast.materialize!(out::AbstractDictionary, bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{0}, Nothing, typeof(identity)}) = fill!(out, bc.args[1][]) \ No newline at end of file +Base.Broadcast.materialize!(out::AbstractDictionary, bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{0}, Nothing, typeof(identity)}) = fill!(out, bc.args[1][]) diff --git a/src/map.jl b/src/map.jl index c46b308..8f69ccf 100644 --- a/src/map.jl +++ b/src/map.jl @@ -88,13 +88,13 @@ function Base.map!(f, out::AbstractDictionary) end function Base.map(f, d::AbstractDictionary) - out = similar(d, Core.Compiler.return_type(f, Tuple{eltype(d)})) + out = similar(d, return_type(f, Tuple{eltype(d)})) @inbounds map!(f, out, d) return out end function Base.map(f, d::AbstractDictionary, ds::AbstractDictionary...) - out = similar(d, Core.Compiler.return_type(f, Tuple{eltype(d), map(eltype, ds)...})) + out = similar(d, return_type(f, Tuple{eltype(d), map(eltype, ds)...})) @inbounds map!(f, out, d, ds...) return out end @@ -146,7 +146,7 @@ empty_type(::Type{<:MappedDictionary{<:Any, <:Any, <:Any, <:Tuple{D, Vararg{Abst if VERSION > v"1.6-" function Iterators.map(f, d::AbstractDictionary) I = keytype(d) - T = Core.Compiler.return_type(f, Tuple{eltype(d)}) # Base normally wouldn't invoke inference for something like this... + T = return_type(f, Tuple{eltype(d)}) # Base normally wouldn't invoke inference for something like this... return MappedDictionary{I, T, typeof(f), Tuple{typeof(d)}}(f, (d,)) end end diff --git a/test/map.jl b/test/map.jl index a9aef5b..68bf3b5 100644 --- a/test/map.jl +++ b/test/map.jl @@ -1,7 +1,7 @@ @testset "map" begin function _mapview(f, d::AbstractDictionary) I = keytype(d) - T = Core.Compiler.return_type(f, Tuple{eltype(d)}) + T = Dictionaries.return_type(f, Tuple{eltype(d)}) return MappedDictionary{I, T, typeof(f), Tuple{typeof(d)}}(f, (d,)) end @@ -23,4 +23,4 @@ @test _mapview(iseven, d)::Dictionaries.MappedDictionary == dictionary([1=>false, 2=>false, 3=>true, 4=>true, 5=>false]) @test _mapview(isodd, d)::Dictionaries.MappedDictionary == dictionary([1=>true, 2=>true, 3=>false, 4=>false, 5=>true]) -end \ No newline at end of file +end From bac632b3cc607675c302c17cd27c30ebbc4d1774 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Wed, 27 Dec 2023 19:44:24 -0600 Subject: [PATCH 2/5] patch bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 5985072..26c5975 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Dictionaries" uuid = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" authors = ["Andy Ferris "] -version = "0.3.25" +version = "0.3.26" [deps] Indexing = "313cdc1a-70c2-5d6a-ae34-0150d3930a38" From 11887c8ee51cea1eca62467dcacdada9f5ec8113 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Wed, 27 Dec 2023 19:56:12 -0600 Subject: [PATCH 3/5] remove restriction --- src/Dictionaries.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Dictionaries.jl b/src/Dictionaries.jl index 49baca3..f9c406f 100644 --- a/src/Dictionaries.jl +++ b/src/Dictionaries.jl @@ -14,14 +14,14 @@ export issettable, isinsertable, set!, unset! export istokenizable, tokentype, tokens, tokenized, gettoken, gettokenvalue, istokenassigned, settokenvalue!, gettoken!, deletetoken!, sharetokens """ - return_type(f, types)::DataType + return_type(f, types) Find the return type of `f` called with `types`. !!! note Currently, this method depends on `code_typed`. """ -function return_type(f, types)::DataType +function return_type(f, types) return last(only(code_typed(f, types; optimize=false, debuginfo=:none))) From 898a033642589e8629056946d4585819469f5a97 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Wed, 27 Dec 2023 21:14:18 -0600 Subject: [PATCH 4/5] Problems with Indices{Union{}} on Julia 1.10 --- src/Indices.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Indices.jl b/src/Indices.jl index 87f65bf..98ff75c 100644 --- a/src/Indices.jl +++ b/src/Indices.jl @@ -65,7 +65,15 @@ function Indices(iter) iter = collect(iter) end - return Indices{eltype(iter)}(iter) + # This is necessary to make map'ing across an empty dictionary work + # In both Julia 1.9 and 1.10 eltype(::Tuple{}) == Union{} + # but in Julia 1.10, this causes problems downstream when Indices{Union{}} + # is used. For an empty iterator, we actually don't know what the + # True(tm) eltype is, so the top of the type hierarchy (Any) is + # just as reasonable as the bottom (Union{}) + I = isempty(iter) ? Any : eltype(iter) + + return Indices{I}(iter) end function Indices{I}(iter) where {I} From c83f30042fcb765a55451208b6dd9095e5860968 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Wed, 27 Dec 2023 21:17:48 -0600 Subject: [PATCH 5/5] more specific --- src/Indices.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Indices.jl b/src/Indices.jl index 98ff75c..59d210b 100644 --- a/src/Indices.jl +++ b/src/Indices.jl @@ -71,7 +71,7 @@ function Indices(iter) # is used. For an empty iterator, we actually don't know what the # True(tm) eltype is, so the top of the type hierarchy (Any) is # just as reasonable as the bottom (Union{}) - I = isempty(iter) ? Any : eltype(iter) + I = typeof(iter) == Tuple{} ? Any : eltype(iter) return Indices{I}(iter) end