@@ -24,7 +24,7 @@ function explain_eltype(@nospecialize(T), depth=0; maxdepth=10)
2424 msg *= explain_eltype (U, depth+ 1 )
2525 end
2626 end
27- elseif Base. ismutabletype (T)
27+ elseif Base. ismutabletype (T) && Base . datatype_fieldcount (T) != 0
2828 msg = " " ^ depth * " $T is a mutable type\n "
2929 elseif hasfieldcount (T)
3030 msg = " " ^ depth * " $T is a struct that's not allocated inline\n "
4747# these are stored with a selector at the end (handled by Julia).
4848# 3. bitstype unions (`Union{Int, Float32}`, etc)
4949# these are stored contiguously and require a selector array (handled by us)
50- @inline function check_eltype (name, T)
51- eltype_is_invalid = ! Base. allocatedinline (T) || (hasfieldcount (T) && any (! Base. allocatedinline, fieldtypes (T)))
52- if eltype_is_invalid
50+ # As well as "mutable singleton" types like `Symbol` that use pointer-identity
51+
52+ function valid_type (@nospecialize (T))
53+ if Base. allocatedinline (T)
54+ if hasfieldcount (T)
55+ return all (valid_type, fieldtypes (T))
56+ end
57+ return true
58+ elseif Base. ismutabletype (T)
59+ return Base. datatype_fieldcount (T) == 0
60+ end
61+ return false
62+ end
63+
64+ @inline function check_eltype (name, T)
65+ if ! valid_type (T)
5366 explanation = explain_eltype (T)
5467 error ("""
5568 $name only supports element types that are allocated inline.
234247function Base. unsafe_wrap (:: Type{CuArray{T,N,M}} ,
235248 ptr:: CuPtr{T} , dims:: NTuple{N,Int} ;
236249 own:: Bool = false , ctx:: CuContext = context ()) where {T,N,M}
237- isbitstype (T) || throw ( ArgumentError ( " Can only unsafe_wrap a pointer to a bits type " ) )
250+ check_eltype ( " unsafe_wrap(CuArray, ...) " , T )
238251 sz = prod (dims) * aligned_sizeof (T)
239252
240253 # create a memory object
0 commit comments