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

separate isbitstype(::Type) from isbits #26850

Merged
merged 1 commit into from
Apr 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
separate isbitstype(::Type) from isbits
  • Loading branch information
JeffBezanson committed Apr 19, 2018
commit 5177038980e9ecc6b16ca80a86e680d376d67ad7
2 changes: 1 addition & 1 deletion base/Enums.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ macro enum(T, syms...)
if isa(T, Expr) && T.head == :(::) && length(T.args) == 2 && isa(T.args[1], Symbol)
typename = T.args[1]
basetype = eval(__module__, T.args[2])
if !isa(basetype, DataType) || !(basetype <: Integer) || !isbits(basetype)
if !isa(basetype, DataType) || !(basetype <: Integer) || !isbitstype(basetype)
throw(ArgumentError("invalid base type for Enum $typename, $T=::$basetype; base type must be an integer primitive type"))
end
elseif !isa(T, Symbol)
Expand Down
12 changes: 6 additions & 6 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ asize_from(a::Array, n) = n > ndims(a) ? () : (arraysize(a,n), asize_from(a, n+1
"""
Base.isbitsunion(::Type{T})

Return whether a type is an "is-bits" Union type, meaning each type included in a Union is `isbits`.
Return whether a type is an "is-bits" Union type, meaning each type included in a Union is `isbitstype`.
"""
isbitsunion(u::Union) = ccall(:jl_array_store_unboxed, Cint, (Any,), u) == Cint(1)
isbitsunion(x) = false

"""
Base.bitsunionsize(U::Union)

For a Union of `isbits` types, return the size of the largest type; assumes `Base.isbitsunion(U) == true`
For a Union of `isbitstype` types, return the size of the largest type; assumes `Base.isbitsunion(U) == true`
"""
function bitsunionsize(u::Union)
sz = Ref{Csize_t}(0)
Expand All @@ -134,7 +134,7 @@ function bitsunionsize(u::Union)
end

length(a::Array) = arraylen(a)
elsize(::Type{<:Array{T}}) where {T} = isbits(T) ? sizeof(T) : (isbitsunion(T) ? bitsunionsize(T) : sizeof(Ptr))
elsize(::Type{<:Array{T}}) where {T} = isbitstype(T) ? sizeof(T) : (isbitsunion(T) ? bitsunionsize(T) : sizeof(Ptr))
sizeof(a::Array) = Core.sizeof(a)

function isassigned(a::Array, i::Int...)
Expand Down Expand Up @@ -177,7 +177,7 @@ the same manner as C.
function unsafe_copyto!(dest::Array{T}, doffs, src::Array{T}, soffs, n) where T
t1 = @_gc_preserve_begin dest
t2 = @_gc_preserve_begin src
if isbits(T)
if isbitstype(T)
unsafe_copyto!(pointer(dest, doffs), pointer(src, soffs), n)
elseif isbitsunion(T)
ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, UInt),
Expand Down Expand Up @@ -1477,7 +1477,7 @@ function vcat(arrays::Vector{T}...) where T
end
arr = Vector{T}(undef, n)
ptr = pointer(arr)
if isbits(T)
if isbitstype(T)
elsz = Core.sizeof(T)
elseif isbitsunion(T)
elsz = bitsunionsize(T)
Expand All @@ -1489,7 +1489,7 @@ function vcat(arrays::Vector{T}...) where T
for a in arrays
na = length(a)
nba = na * elsz
if isbits(T)
if isbitstype(T)
ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, UInt),
ptr, a, nba)
elseif isbitsunion(T)
Expand Down
2 changes: 1 addition & 1 deletion base/arraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function reverse(A::Array{T}; dims::Integer) where T
end
end
else
if isbits(T) && M>200
if isbitstype(T) && M>200
for i = 1:sd
ri = sd+1-i
for j=0:stride:(N-stride)
Expand Down
9 changes: 5 additions & 4 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ function optimize(me::InferenceState)
me.src.inlineable = false
elseif !me.src.inlineable && isa(def, Method)
bonus = 0
if me.bestguess ⊑ Tuple && !isbits(widenconst(me.bestguess))
if me.bestguess ⊑ Tuple && !isbitstype(widenconst(me.bestguess))
bonus = me.params.inline_tupleret_bonus
end
me.src.inlineable = isinlineable(def, me.src, me.mod, me.params, bonus)
Expand Down Expand Up @@ -706,7 +706,7 @@ end
# since codegen optimizations of functions like `is` will depend on knowing it
function widen_slot_type(@nospecialize(ty), untypedload::Bool)
if isa(ty, DataType)
if untypedload || isbits(ty) || isdefined(ty, :instance)
if untypedload || isbitstype(ty) || isdefined(ty, :instance)
return ty
end
elseif isa(ty, Union)
Expand Down Expand Up @@ -1154,6 +1154,7 @@ function inlineable(@nospecialize(f), @nospecialize(ft), e::Expr, atypes::Vector
f === Core.sizeof || f === isdefined ||
istopfunction(topmod, f, :typejoin) ||
istopfunction(topmod, f, :isbits) ||
istopfunction(topmod, f, :isbitstype) ||
istopfunction(topmod, f, :promote_type) ||
(f === Core.kwfunc && length(argexprs) == 2) ||
(is_inlineable_constant(val) &&
Expand Down Expand Up @@ -3093,7 +3094,7 @@ function structinfo_new(ctx::AllocOptContext, ex::Expr, vt::DataType)
si.defs[i] = ex.args[i + 1]
else
ft = fieldtype(vt, i)
if isbits(ft)
if isbitstype(ft)
ex = Expr(:new, ft)
ex.typ = ft
si.defs[i] = ex
Expand Down Expand Up @@ -3630,7 +3631,7 @@ function split_struct_alloc_single!(ctx::AllocOptContext, info, key, nf, has_pre
if !@isdefined(fld_name)
fld_name = :struct_field
end
need_preserved_root = has_preserve && !isbits(field_typ)
need_preserved_root = has_preserve && !isbitstype(field_typ)
local var_slot
if !has_def
# If there's no direct use of the field
Expand Down
1 change: 1 addition & 0 deletions base/compiler/ssair/inlining2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,7 @@ function early_inline_special_case(ir::IRCode, @nospecialize(f), @nospecialize(f
f === Core.sizeof || f === isdefined ||
istopfunction(topmod, f, :typejoin) ||
istopfunction(topmod, f, :isbits) ||
istopfunction(topmod, f, :isbitstype) ||
istopfunction(topmod, f, :promote_type) ||
(f === Core.kwfunc && length(atypes) == 2) ||
(is_inlineable_constant(val) &&
Expand Down
4 changes: 2 additions & 2 deletions base/compiler/ssair/passes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ is_tuple_call(ir, def) = isa(def, Expr) && is_known_call(def, tuple, ir, ir.mod)

function process_immutable_preserve(new_preserves::Vector{Any}, compact::IncrementalCompact, def::Expr)
for arg in (isexpr(def, :new) ? def.args : def.args[2:end])
if !isbits(compact_exprtype(compact, arg))
if !isbitstype(compact_exprtype(compact, arg))
push!(new_preserves, arg)
end
end
Expand Down Expand Up @@ -373,7 +373,7 @@ function getfield_elim_pass!(ir::IRCode, domtree::DomTree)
for stmt in du.uses
ir[SSAValue(stmt)] = compute_value_for_use(ir, domtree, allblocks, du, phinodes, fidx, stmt)
end
if !isbits(fieldtype(typ, fidx))
if !isbitstype(fieldtype(typ, fidx))
for (use, list) in preserve_uses
push!(list, compute_value_for_use(ir, domtree, allblocks, du, phinodes, fidx, use))
end
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ function isdefined_tfunc(args...)
end
elseif idx <= 0 || (!isvatuple(a1) && idx > fieldcount(a1))
return Const(false)
elseif !isvatuple(a1) && isbits(fieldtype(a1, idx))
elseif !isvatuple(a1) && isbitstype(fieldtype(a1, idx))
return Const(true)
elseif isa(arg1, Const) && isimmutable((arg1::Const).val)
return Const(isdefined((arg1::Const).val, idx))
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/typelimits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function is_derived_type(@nospecialize(t), @nospecialize(c), mindepth::Int)
for p in cP
is_derived_type(t, p, mindepth) && return true
end
if isconcretetype(c) && isbits(c)
if isconcretetype(c) && isbitstype(c)
# see if it was extracted from a fieldtype
# however, only look through types that can be inlined
# to ensure monotonicity of derivation
Expand Down
4 changes: 2 additions & 2 deletions base/compiler/typeutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ end
function valid_tparam(@nospecialize(x))
if isa(x, Tuple)
for t in x
isa(t, Symbol) || isbits(typeof(t)) || return false
isa(t, Symbol) || isbitstype(typeof(t)) || return false
end
return true
end
return isa(x, Symbol) || isbits(typeof(x))
return isa(x, Symbol) || isbitstype(typeof(x))
end

has_free_typevars(@nospecialize(t)) = ccall(:jl_has_free_typevars, Cint, (Any,), t) != 0
Expand Down
8 changes: 4 additions & 4 deletions base/deepcopy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ end
function deepcopy_internal(@nospecialize(x), stackdict::IdDict)
T = typeof(x)::DataType
nf = nfields(x)
(isbits(T) || nf == 0) && return x
(isbitstype(T) || nf == 0) && return x
if haskey(stackdict, x)
return stackdict[x]
end
Expand All @@ -79,15 +79,15 @@ function deepcopy_internal(x::Array, stackdict::IdDict)
end

function _deepcopy_array_t(@nospecialize(x), T, stackdict::IdDict)
if isbits(T)
if isbitstype(T)
return (stackdict[x]=copy(x))
end
dest = similar(x)
stackdict[x] = dest
for i = 1:(length(x)::Int)
if ccall(:jl_array_isassigned, Cint, (Any, Csize_t), x, i-1) != 0
xi = ccall(:jl_arrayref, Any, (Any, Csize_t), x, i-1)
if !isbits(typeof(xi))
if !isbitstype(typeof(xi))
xi = deepcopy_internal(xi, stackdict)
end
ccall(:jl_arrayset, Cvoid, (Any, Any, Csize_t), dest, xi, i-1)
Expand All @@ -101,7 +101,7 @@ function deepcopy_internal(x::Union{Dict,IdDict}, stackdict::IdDict)
return stackdict[x]::typeof(x)
end

if isbits(eltype(x))
if isbitstype(eltype(x))
return (stackdict[x] = copy(x))
end

Expand Down
3 changes: 3 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,9 @@ end
# To remove this deprecation, remove the `keep` argument from the function signatures as well as
# the internal logic that deals with the renaming. These live in base/strings/util.jl.

# when this is removed, `isbitstype(typeof(x))` can be replaced with `isbits(x)`
@deprecate isbits(@nospecialize(t::Type)) isbitstype(t)

# END 0.7 deprecations

# BEGIN 1.0 deprecations
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ export
fieldcount,
# propertynames,
isabstracttype,
isbitstype,
isprimitivetype,
isstructtype,
isconcretetype,
Expand Down
8 changes: 4 additions & 4 deletions base/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ write(s::IO, x::Bool) = write(s, UInt8(x))
write(to::IO, p::Ptr) = write(to, convert(UInt, p))

function write(s::IO, A::AbstractArray)
if !isbits(eltype(A))
if !isbitstype(eltype(A))
depwarn("Calling `write` on non-isbits arrays is deprecated. Use a loop or `serialize` instead.", :write)
end
nb = 0
Expand All @@ -529,7 +529,7 @@ function write(s::IO, A::AbstractArray)
end

function write(s::IO, a::Array)
if isbits(eltype(a))
if isbitstype(eltype(a))
return GC.@preserve a unsafe_write(s, pointer(a), sizeof(a))
else
depwarn("Calling `write` on non-isbits arrays is deprecated. Use a loop or `serialize` instead.", :write)
Expand All @@ -542,7 +542,7 @@ function write(s::IO, a::Array)
end

function write(s::IO, a::SubArray{T,N,<:Array}) where {T,N}
if !isbits(T)
if !isbitstype(T)
return invoke(write, Tuple{IO, AbstractArray}, s, a)
end
elsz = sizeof(T)
Expand Down Expand Up @@ -605,7 +605,7 @@ function read!(s::IO, a::Array{UInt8})
end

function read!(s::IO, a::Array{T}) where T
if isbits(T)
if isbitstype(T)
GC.@preserve a unsafe_read(s, pointer(a), sizeof(a))
else
for i in eachindex(a)
Expand Down
2 changes: 1 addition & 1 deletion base/iobuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ function read_sub(from::GenericIOBuffer, a::AbstractArray{T}, offs, nel) where T
if offs+nel-1 > length(a) || offs < 1 || nel < 0
throw(BoundsError())
end
if isbits(T) && isa(a,Array)
if isbitstype(T) && isa(a,Array)
nb = UInt(nel * sizeof(T))
GC.@preserve a unsafe_read(from, pointer(a, offs), nb)
else
Expand Down
2 changes: 1 addition & 1 deletion base/reducedim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function _reducedim_init(f, op, fv, fop, A, region)
if T !== Any && applicable(zero, T)
x = f(zero(T))
z = op(fv(x), fv(x))
Tr = typeof(z) == typeof(x) && !isbits(T) ? T : typeof(z)
Tr = typeof(z) == typeof(x) && !isbitstype(T) ? T : typeof(z)
else
z = fv(fop(f, A))
Tr = typeof(z)
Expand Down
16 changes: 11 additions & 5 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -352,11 +352,11 @@ function isprimitivetype(@nospecialize(t::Type))
end

"""
isbits(T)
isbitstype(T)

Return `true` if type `T` is a "plain data" type,
meaning it is immutable and contains no references to other values,
only `primitive` types and other `isbits` types.
only `primitive` types and other `isbitstype` types.
Typical examples are numeric types such as [`UInt8`](@ref),
[`Float64`](@ref), and [`Complex{Float64}`](@ref).
This category of types is significant since they are valid as type parameters,
Expand All @@ -365,14 +365,20 @@ and have a defined layout that is compatible with C.

# Examples
```jldoctest
julia> isbits(Complex{Float64})
julia> isbitstype(Complex{Float64})
true

julia> isbits(Complex)
julia> isbitstype(Complex)
false
```
"""
isbits(@nospecialize(t::Type)) = (@_pure_meta; isa(t, DataType) && t.isbitstype)
isbitstype(@nospecialize(t::Type)) = (@_pure_meta; isa(t, DataType) && t.isbitstype)

"""
isbits(x)

Return `true` if `x` is an instance of an `isbitstype` type.
"""
isbits(@nospecialize x) = (@_pure_meta; typeof(x).isbitstype)

"""
Expand Down
2 changes: 1 addition & 1 deletion base/refpointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ if is_primary_base_module
return RefArray(a) # effectively a no-op
end
function Ref{P}(a::Array{T}) where P<:Union{Ptr,Cwstring,Cstring} where T
if (!isbits(T) && T <: eltype(P))
if (!isbitstype(T) && T <: eltype(P))
# this Array already has the right memory layout for the requested Ref
return RefArray(a,1,false) # root something, so that this function is type-stable
else
Expand Down
4 changes: 2 additions & 2 deletions base/reinterpretarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ struct ReinterpretArray{T,N,S,A<:AbstractArray{S, N}} <: AbstractArray{T, N}
The resulting array would have non-integral first dimension.
"""))
end
isbits(T) || throwbits(S, T, T)
isbits(S) || throwbits(S, T, S)
isbitstype(T) || throwbits(S, T, T)
isbitstype(S) || throwbits(S, T, S)
(N != 0 || sizeof(T) == sizeof(S)) || throwsize0(S, T)
if N != 0 && sizeof(S) != sizeof(T)
dim = size(a)[1]
Expand Down
4 changes: 2 additions & 2 deletions base/summarysize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function summarysize(obj;
else
nf = _nfields(x)
ft = typeof(x).types
if !isbits(ft[i]) && isdefined(x, i)
if !isbitstype(ft[i]) && isdefined(x, i)
val = getfield(x, i)
end
end
Expand Down Expand Up @@ -108,7 +108,7 @@ function (ss::SummarySize)(obj::Array)
if !haskey(ss.seen, datakey)
ss.seen[datakey] = true
size += Core.sizeof(obj)
if !isbits(eltype(obj)) && !isempty(obj)
if !isbitstype(eltype(obj)) && !isempty(obj)
push!(ss.frontier_x, obj)
push!(ss.frontier_i, 1)
end
Expand Down
2 changes: 1 addition & 1 deletion base/threadcall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function do_threadcall(fun_ptr::Ptr{Cvoid}, rettype::Type, argtypes::Vector, arg
args_arr = Vector{UInt8}(undef, args_size)
ptr = pointer(args_arr)
for (T, x) in zip(argtypes, argvals)
isbits(T) || throw(ArgumentError("threadcall requires isbits argument types"))
isbitstype(T) || throw(ArgumentError("threadcall requires isbits argument types"))
y = cconvert(T, x)
push!(roots, y)
unsafe_store!(convert(Ptr{T}, ptr), unsafe_convert(T, y)::T)
Expand Down
1 change: 1 addition & 0 deletions doc/src/base/base.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ Base.fieldname
Base.sizeof(::Type)
Base.isconcretetype
Base.isbits
Base.isbitstype
Core.fieldtype
Base.fieldcount
Base.fieldoffset
Expand Down
4 changes: 2 additions & 2 deletions stdlib/Distributed/src/clusterserialize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ function syms_2b_sent(s::ClusterSerializer, identifier)
for sym in check_syms
v = getfield(Main, sym)

if isbits(v)
if isbitstype(typeof(v))
push!(lst, sym)
else
oid = objectid(v)
Expand All @@ -146,7 +146,7 @@ function serialize_global_from_main(s::ClusterSerializer, sym)

oid = objectid(v)
record_v = true
if isbits(v)
if isbitstype(typeof(v))
record_v = false
elseif !haskey(s.glbs_sent, oid)
# set up a finalizer the first time this object is sent
Expand Down
Loading