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

WIP: Allow convert and reinterpret for Arrays of unions with missing/nothing #36186

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

oxinabox
Copy link
Contributor

@oxinabox oxinabox commented Jun 7, 2020

Closes #26681 and #31152

Right now convert kind of breaks the compiler and i am not sure why.
Debugging that is pending, so right now it is commented out so i could run the reinterpet tests

Writing this is made harder by #36185

@oxinabox oxinabox changed the title Allow convert and reinterpret for Arrays of unions with missing/nothing WIP: Allow convert and reinterpret for Arrays of unions with missing/nothing Jun 7, 2020
base/regex.jl Outdated Show resolved Hide resolved
@oxinabox oxinabox force-pushed the ox/unionconv branch 2 times, most recently from 1dcb9b1 to da23ed5 Compare June 7, 2020 23:19
remove mistakenly included files

remove mistakenly included files
==#
end
# Resolve ambiguity
#Base.convert(::Type{Array{Any,1}}, xs::Array{Any,1}) = xs
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know why this is ambiguous, and the answer would probably go a long way to explaining why this breaks so much

@@ -69,6 +69,33 @@ convert(::Type{T}, x::T) where {T>:Union{Missing, Nothing}} = x
convert(::Type{T}, x) where {T>:Missing} = convert(nonmissingtype_checked(T), x)
convert(::Type{T}, x) where {T>:Union{Missing, Nothing}} = convert(nonmissingtype_checked(nonnothingtype_checked(T)), x)

for Cs in ((:Missing,), (:Nothing,), (:Missing, :Nothing))
@eval function Base.reinterpret(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Suggested change
@eval function Base.reinterpret(
@eval function reinterpret(

base/missing.jl Outdated Show resolved Hide resolved
base/missing.jl Outdated Show resolved Hide resolved
@oxinabox
Copy link
Contributor Author

oxinabox commented Jun 8, 2020

So turns out there a a ton of problems with doing reinterprete this way (at least for now) like leaking memory.

So I am just going to leave this to sit here and people can take my test cases for when it is done the right way

@StefanKarpinski
Copy link
Sponsor Member

In general, we want to move away from reinterpret—it has many issues. What you really want is a conversion that's very cheap (i.e. free), which has the desired semantics.

@oxinabox
Copy link
Contributor Author

oxinabox commented Jun 8, 2020

In general, we want to move away from reinterpret—it has many issues. What you really want is a conversion that's very cheap (i.e. free), which has the desired semantics.

Ok, I thought it made sense to have a reinterpret that is the "I know what I am doing, trust me, take those bits in memory and interpret them as this type"
and then a convert that when that is safe does this, and when it isn't doesn't

xs::Array{Union{T, $(Cs...)},N}
) where {T,N}
isbitstype(T) || throw(ArgumentError("cannot reinterpret `$(eltype(xs))`, type `$(T)` is not a bits type"))
return unsafe_wrap(Array{T,N}, Ptr{T}(pointer(xs)), length(xs))
Copy link
Sponsor Member

@KristofferC KristofferC Jun 8, 2020

Choose a reason for hiding this comment

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

What happens when xs get's garbage collected? Doesn't this mess with TBAA?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

idk, I didn't even know we did aliasing detection.

@KristofferC
Copy link
Sponsor Member

I think the only way this could be reasonably done is to "move" (think std::move) ownership of the original array to the new one (in a similar way how String does it when acting on a Vector{UInt8}).

@oxinabox
Copy link
Contributor Author

oxinabox commented Jun 9, 2020

I think the only way this could be reasonably done is to "move" (think std::move) ownership of the original array to the new one (in a similar way how String does it when acting on a Vector{UInt8}).

Then it can't be called reinterpret, but that is Ok

@KristofferC
Copy link
Sponsor Member

It would be something like unsafe_move!

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.

Feature request: convert between Array{Union{T, Missing}, N} and Array{T, N} without copying
3 participants