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

Allow reinterpreting singleton types #43500

Merged
merged 5 commits into from
Jan 14, 2022

Conversation

Liozou
Copy link
Member

@Liozou Liozou commented Dec 21, 2021

Fix #43403. It does not actually allow reinterpreting all 0-sized types, only the immutable ones (aka singleton types), but I think that's what was intended anyway (see also #17149).

I'm not sure whether it should be merged, considering what @vtjnash said in #34865 (comment), but I'm opening the PR in case it is decided it is worth adding.

Since reinterpret is a fairly basic building block, there is also the potential issue of slowing down critical paths. I don't think there is any harm done in this regard since the sizeof(T) == 0 and isdefined(T, :instance) conditions should all be eliminated at compilation I think, but I'm no expert on this.

@JeffBezanson
Copy link
Sponsor Member

Hmm. It's hard to say whether we should allow this. The divide-by-zero error should be avoided at least. But then if we want to allow this, it should be implemented inside bitcast I think.

@JeffBezanson JeffBezanson added the status:triage This should be discussed on a triage call label Jan 5, 2022
@Liozou
Copy link
Member Author

Liozou commented Jan 5, 2022

To implement it inside bitcast, maybe singleton types should be considered to be primitive types? That's currently explicitly not the case because of the following line

julia/src/julia.h

Line 1217 in 98b485e

jl_datatype_size(v) > 0);
which originates in 62cca31 and I imagine there may be good reasons not to, but I'm no expert on this.

Additionally, I remembered that singleton types were primarily used for function types, and I don't know if giving a meaning to reinterpret(typeof(sum), nothing) really is desirable... Although I'm not sure it would hurt either.

@JeffBezanson
Copy link
Sponsor Member

From triage: bitcast and reinterpret (on non-arrays) don't support structs, so they shouldn't support 0-size structs either. However, reinterpret of arrays does allow it, so that case should work.

base/essentials.jl Outdated Show resolved Hide resolved
test/reinterpretarray.jl Outdated Show resolved Hide resolved
@JeffBezanson JeffBezanson removed the status:triage This should be discussed on a triage call label Jan 6, 2022
@Liozou
Copy link
Member Author

Liozou commented Jan 6, 2022

Thank you for the triage and the review! I added a commit with the fix: doing reinterpret(::singletontype, ::notanarray) reverts to being forbidden while reinterpret(::singletontype, ::somesingletonarray) continues to work.

Let me know if there is anything else I can do.

@Liozou
Copy link
Member Author

Liozou commented Jan 7, 2022

CI failure seems unrelated.

@@ -475,6 +497,10 @@ end
v = convert(T, v)::T
# Make sure to match the scalar reinterpret if that is applicable
if sizeof(T) == sizeof(S) && (fieldcount(T) + fieldcount(S)) == 0
if Base.issingletontype(T) # singleton types
@boundscheck checkbounds(a, i1, tailinds...)
return T.instance # setindex! is a noop here
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Suggested change
return T.instance # setindex! is a noop here
return a # setindex! is a noop here

This function is supposed to return the argument, though looks like several of the cases are wrong.

Copy link
Member Author

Choose a reason for hiding this comment

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

You're right, sorry about that! I fixed both instances in e63a8fb.
I also fixed the currently erroneous return value for setindex! on some reinterpretarrays where it would return the parent array:

julia> t = reinterpret(Int, UInt[15])
1-element reinterpret(Int64, ::Vector{UInt64}):
 15

julia> setindex!(t, 7, 1) # should return t instead of t.parent
1-element Vector{UInt64}:
 0x0000000000000007

That's a bugfix (I believe) but it's technically breaking so let me know if you prefer I'd move that to another PR.

@vtjnash vtjnash dismissed oscardssmith’s stale review January 13, 2022 04:20

the changes were made

@vtjnash vtjnash added the status:merge me PR is reviewed. Merge when all tests are passing label Jan 13, 2022
@DilumAluthge
Copy link
Member

@Liozou Can you rebase on the latest master? That should fix the llvmpasses failures.

@Liozou
Copy link
Member Author

Liozou commented Jan 14, 2022

Done, there is a remaining CI failure for the Sockets test but it looks unrelated.

@DilumAluthge DilumAluthge merged commit 7b1cc4b into JuliaLang:master Jan 14, 2022
@DilumAluthge DilumAluthge removed the status:merge me PR is reviewed. Merge when all tests are passing label Jan 14, 2022
N5N3 pushed a commit to N5N3/julia that referenced this pull request Jan 24, 2022
@Liozou Liozou deleted the reinterpretsingleton branch February 21, 2022 11:46
LilithHafner pushed a commit to LilithHafner/julia that referenced this pull request Feb 22, 2022
LilithHafner pushed a commit to LilithHafner/julia that referenced this pull request Mar 8, 2022
@Seelengrab
Copy link
Contributor

Seelengrab commented May 19, 2022

This PR (or one of the two follow ups, not 100% sure) allows reinterpret(Missing, Int8[]), which doesn't make too much sense to me:

julia> a = Int8[]
Int8[]

julia> ms = reinterpret(Missing, a)
0-element reinterpret(Missing, ::Vector{Int8})

julia> push!(a, 1)
1-element Vector{Int8}:
 1

julia> ms
1-element reinterpret(Missing, ::Vector{Int8}):
 missing

This was encountered during a discussion on discourse, about reinterpreting empty views/arrays. As 1.8 has not been released, perhaps this can be decided soon-ish?

Possible solution: disallow reinterpret to singleton types if the source array type is not also a singleton type.

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.

reinterpret between 0-sized types
7 participants