Skip to content

Commit 4fccb28

Browse files
committed
replace export of isleaftype with a more simply-defined isconcrete
fixes #17086
1 parent 8757abf commit 4fccb28

22 files changed

+69
-49
lines changed

base/broadcast.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ _nullable_eltype(f, A, As...) =
309309
T = _broadcast_eltype(f, A, Bs...)
310310
shape = broadcast_indices(A, Bs...)
311311
iter = CartesianRange(shape)
312-
if isleaftype(T)
312+
if Base._isleaftype(T)
313313
return broadcast_t(f, T, shape, iter, A, Bs...)
314314
end
315315
if isempty(iter)
@@ -320,8 +320,8 @@ end
320320
@inline function broadcast_c(f, ::Type{Nullable}, a...)
321321
nonnull = all(hasvalue, a)
322322
S = _nullable_eltype(f, a...)
323-
if isleaftype(S) && null_safe_op(f, maptoTuple(_unsafe_get_eltype,
324-
a...).types...)
323+
if Base._isleaftype(S) && null_safe_op(f, maptoTuple(_unsafe_get_eltype,
324+
a...).types...)
325325
Nullable{S}(f(map(unsafe_get, a)...), nonnull)
326326
else
327327
if nonnull

base/complex.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ big(z::Complex{T}) where {T<:Real} = Complex{big(T)}(z)
958958
complex(A::AbstractArray{<:Complex}) = A
959959

960960
function complex(A::AbstractArray{T}) where T
961-
if !isleaftype(T)
961+
if !isconcrete(T)
962962
error("`complex` not defined on abstractly-typed arrays; please convert to a more specific type")
963963
end
964964
convert(AbstractArray{typeof(complex(zero(T)))}, A)

base/deprecated.jl

+3
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,9 @@ import .Iterators.enumerate
17661766
# issue #5794
17671767
@deprecate map(f, d::T) where {T<:Associative} T( f(p) for p in pairs(d) )
17681768

1769+
# issue #17086
1770+
@deprecate isleaftype isconcrete
1771+
17691772
# END 0.7 deprecations
17701773

17711774
# BEGIN 1.0 deprecations

base/dict.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function show(io::IO, t::Associative{K,V}) where V where K
3434
if isempty(t)
3535
print(io, typeof(t), "()")
3636
else
37-
if isleaftype(K) && isleaftype(V)
37+
if _isleaftype(K) && _isleaftype(V)
3838
print(io, typeof(t).name)
3939
else
4040
print(io, typeof(t))
@@ -161,7 +161,7 @@ associative_with_eltype(DT_apply, ::Type) = DT_apply(Any, Any)()
161161
associative_with_eltype(DT_apply::F, kv, t) where {F} = grow_to!(associative_with_eltype(DT_apply, _default_eltype(typeof(kv))), kv)
162162
function associative_with_eltype(DT_apply::F, kv::Generator, t) where F
163163
T = _default_eltype(typeof(kv))
164-
if T <: Union{Pair, Tuple{Any, Any}} && isleaftype(T)
164+
if T <: Union{Pair, Tuple{Any, Any}} && _isleaftype(T)
165165
return associative_with_eltype(DT_apply, kv, T)
166166
end
167167
return grow_to!(associative_with_eltype(DT_apply, T), kv)

base/exports.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ export
931931
fieldname,
932932
fieldnames,
933933
fieldcount,
934-
isleaftype,
934+
isconcrete,
935935
oftype,
936936
promote,
937937
promote_rule,

base/float.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ Base.iszero(x::Float16) = reinterpret(UInt16, x) & ~sign_mask(Float16) == 0x0000
877877
float(A::AbstractArray{<:AbstractFloat}) = A
878878

879879
function float(A::AbstractArray{T}) where T
880-
if !isleaftype(T)
880+
if !isconcrete(T)
881881
error("`float` not defined on abstractly-typed arrays; please convert to a more specific type")
882882
end
883883
convert(AbstractArray{typeof(float(zero(T)))}, A)

base/inference.jl

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ const NF = NotFound()
6363
const LineNum = Int
6464
const VarTable = Array{Any,1}
6565

66+
const isleaftype = _isleaftype
67+
6668
# The type of a variable load is either a value or an UndefVarError
6769
mutable struct VarState
6870
typ

base/interactiveutil.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ Evaluates the arguments to the function or macro call, determines their types, a
555555
function type_close_enough(@nospecialize(x), @nospecialize(t))
556556
x == t && return true
557557
return (isa(x,DataType) && isa(t,DataType) && x.name === t.name &&
558-
!isleaftype(t) && x <: t) ||
558+
!_isleaftype(t) && x <: t) ||
559559
(isa(x,Union) && isa(t,DataType) && (type_close_enough(x.a, t) || type_close_enough(x.b, t)))
560560
end
561561

base/iterators.jl

+4-7
Original file line numberDiff line numberDiff line change
@@ -733,17 +733,14 @@ iteratoreltype(::Type{Flatten{I}}) where {I} = _flatteneltype(I, iteratoreltype(
733733
_flatteneltype(I, ::HasEltype) = iteratoreltype(eltype(I))
734734
_flatteneltype(I, et) = EltypeUnknown()
735735

736-
flatten_iteratorsize(::Union{HasShape, HasLength}, b::Type{<:Tuple}) = isleaftype(b) ? HasLength() : SizeUnknown()
737-
flatten_iteratorsize(::Union{HasShape, HasLength}, b::Type{<:Number}) = HasLength()
736+
flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:NTuple{N,Any}}) where {N} = HasLength()
737+
flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Tuple}) = SizeUnknown()
738+
flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Number}) = HasLength()
738739
flatten_iteratorsize(a, b) = SizeUnknown()
739740

740741
iteratorsize(::Type{Flatten{I}}) where {I} = flatten_iteratorsize(iteratorsize(I), eltype(I))
741742

742-
function flatten_length(f, ::Type{T}) where {T<:Tuple}
743-
if !isleaftype(T)
744-
throw(ArgumentError(
745-
"Cannot compute length of a tuple-type which is not a leaf-type"))
746-
end
743+
function flatten_length(f, T::Type{<:NTuple{N,Any}}) where {N}
747744
fieldcount(T)*length(f.it)
748745
end
749746
flatten_length(f, ::Type{<:Number}) = length(f.it)

base/methodshow.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ function show(io::IO, m::Method; kwtype::Nullable{DataType}=Nullable{DataType}()
108108
# TODO: more accurate test? (tn.name === "#" name)
109109
ft0 === typeof(getfield(ft.name.module, ft.name.mt.name))
110110
print(io, ft.name.mt.name)
111-
elseif isa(ft, DataType) && ft.name === Type.body.name && isleaftype(ft)
111+
elseif isa(ft, DataType) && ft.name === Type.body.name
112112
f = ft.parameters[1]
113113
if isa(f, DataType) && isempty(f.parameters)
114114
print(io, f)
@@ -235,7 +235,7 @@ function show(io::IO, ::MIME"text/html", m::Method; kwtype::Nullable{DataType}=N
235235
isdefined(ft.name.module, ft.name.mt.name) &&
236236
ft0 === typeof(getfield(ft.name.module, ft.name.mt.name))
237237
print(io, ft.name.mt.name)
238-
elseif isa(ft, DataType) && ft.name === Type.body.name && isleaftype(ft)
238+
elseif isa(ft, DataType) && ft.name === Type.body.name
239239
f = ft.parameters[1]
240240
if isa(f, DataType) && isempty(f.parameters)
241241
print(io, f)

base/nullable.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ end
339339
"""
340340
Return the given type if it is concrete, and `Union{}` otherwise.
341341
"""
342-
nullable_returntype(::Type{T}) where {T} = isleaftype(T) ? T : Union{}
342+
nullable_returntype(::Type{T}) where {T} = _isleaftype(T) ? T : Union{}
343343

344344
"""
345345
map(f, x::Nullable)
@@ -365,7 +365,7 @@ Nullable{Bool}()
365365
"""
366366
function map(f, x::Nullable{T}) where T
367367
S = promote_op(f, T)
368-
if isleaftype(S) && null_safe_op(f, T)
368+
if _isleaftype(S) && null_safe_op(f, T)
369369
Nullable(f(unsafe_get(x)), !isnull(x))
370370
else
371371
if isnull(x)

base/promotion.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,13 @@ promote_op(::Any...) = (@_inline_meta; Any)
346346
function promote_op(f, ::Type{S}) where S
347347
@_inline_meta
348348
T = _return_type(f, Tuple{_default_type(S)})
349-
isleaftype(S) && return isleaftype(T) ? T : Any
349+
_isleaftype(S) && return _isleaftype(T) ? T : Any
350350
return typejoin(S, T)
351351
end
352352
function promote_op(f, ::Type{R}, ::Type{S}) where {R,S}
353353
@_inline_meta
354354
T = _return_type(f, Tuple{_default_type(R), _default_type(S)})
355-
isleaftype(R) && isleaftype(S) && return isleaftype(T) ? T : Any
355+
_isleaftype(R) && _isleaftype(S) && return _isleaftype(T) ? T : Any
356356
return typejoin(R, S, T)
357357
end
358358

base/reflection.jl

+18-10
Original file line numberDiff line numberDiff line change
@@ -287,28 +287,36 @@ isbits(t::DataType) = (@_pure_meta; !t.mutable & (t.layout != C_NULL) && datatyp
287287
isbits(t::Type) = (@_pure_meta; false)
288288
isbits(x) = (@_pure_meta; isbits(typeof(x)))
289289

290+
_isleaftype(@nospecialize(t)) = (@_pure_meta; isa(t, DataType) && t.isleaftype)
291+
290292
"""
291-
isleaftype(T)
293+
isconcrete(T)
292294
293-
Determine whether `T`'s only subtypes are itself and `Union{}`. This means `T` is
294-
a concrete type that can have instances.
295+
Determine whether `T` is a concrete type, meaning it can have direct instances
296+
(values `x` such that `typeof(x) === T`).
295297
296298
# Examples
297299
```jldoctest
298-
julia> isleaftype(Complex)
300+
julia> isconcrete(Complex)
299301
false
300302
301-
julia> isleaftype(Complex{Float32})
303+
julia> isconcrete(Complex{Float32})
302304
true
303305
304-
julia> isleaftype(Vector{Complex})
306+
julia> isconcrete(Vector{Complex})
305307
true
306308
307-
julia> isleaftype(Vector{Complex{Float32}})
309+
julia> isconcrete(Vector{Complex{Float32}})
308310
true
311+
312+
julia> isconcrete(Union{})
313+
false
314+
315+
julia> isconcrete(Union{Int,String})
316+
false
309317
```
310318
"""
311-
isleaftype(@nospecialize(t)) = (@_pure_meta; isa(t, DataType) && t.isleaftype)
319+
isconcrete(@nospecialize(t)) = (@_pure_meta; isa(t, DataType) && t.layout != C_NULL)
312320

313321
"""
314322
Base.isabstract(T)
@@ -791,7 +799,7 @@ function _dump_function_linfo(linfo::Core.MethodInstance, world::UInt, native::B
791799
end
792800

793801
# TODO: use jl_is_cacheable_sig instead of isleaftype
794-
isleaftype(linfo.specTypes) || (str = "; WARNING: This code may not match what actually runs.\n" * str)
802+
_isleaftype(linfo.specTypes) || (str = "; WARNING: This code may not match what actually runs.\n" * str)
795803
return str
796804
end
797805

@@ -822,7 +830,7 @@ code_native(::IO, ::Any, ::Symbol) = error("illegal code_native call") # resolve
822830

823831
# give a decent error message if we try to instantiate a staged function on non-leaf types
824832
function func_for_method_checked(m::Method, @nospecialize types)
825-
if isdefined(m,:generator) && !isdefined(m,:source) && !isleaftype(types)
833+
if isdefined(m,:generator) && !isdefined(m,:source) && !_isleaftype(types)
826834
error("cannot call @generated function `", m, "` ",
827835
"with abstract argument types: ", types)
828836
end

base/refpointer.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ convert(::Type{Ref{T}}, x) where {T} = RefValue{T}(x)
5555
function unsafe_convert(P::Type{Ptr{T}}, b::RefValue{T}) where T
5656
if isbits(T) || isbitsunion(T)
5757
return convert(P, pointer_from_objref(b))
58-
elseif isleaftype(T)
58+
elseif _isleaftype(T)
5959
return convert(P, pointer_from_objref(b.x))
6060
else
6161
# If the slot is not leaf type, it could be either isbits or not.

base/replutil.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ function show_method_candidates(io::IO, ex::MethodError, kwargs::Vector=Any[])
468468
# pool MethodErrors for these two functions.
469469
if f === convert && !isempty(arg_types_param)
470470
at1 = arg_types_param[1]
471-
if isa(at1,DataType) && (at1::DataType).name === Type.body.name && isleaftype(at1)
471+
if isa(at1,DataType) && (at1::DataType).name === Type.body.name && !Core.Inference.has_free_typevars(at1)
472472
push!(funcs, (at1.parameters[1], arg_types_param[2:end]))
473473
end
474474
end

base/set.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ for sets of arbitrary objects.
1818
Set(itr) = Set{eltype(itr)}(itr)
1919
function Set(g::Generator)
2020
T = _default_eltype(typeof(g))
21-
(isleaftype(T) || T === Union{}) || return grow_to!(Set{T}(), g)
21+
(_isleaftype(T) || T === Union{}) || return grow_to!(Set{T}(), g)
2222
return Set{T}(g)
2323
end
2424

@@ -266,7 +266,7 @@ function unique(itr)
266266
return out
267267
end
268268
x, i = next(itr, i)
269-
if !isleaftype(T) && iteratoreltype(itr) == EltypeUnknown()
269+
if !_isleaftype(T) && iteratoreltype(itr) == EltypeUnknown()
270270
S = typeof(x)
271271
return _unique_from(itr, S[x], Set{S}((x,)), i)
272272
end

base/show.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ function show_type_name(io::IO, tn::TypeName)
253253
globname_str = string(globname)
254254
if ('#' globname_str && '@' globname_str && isdefined(tn, :module) &&
255255
isbindingresolved(tn.module, globname) && isdefined(tn.module, globname) &&
256-
isa(getfield(tn.module, globname), tn.wrapper) && isleaftype(tn.wrapper))
256+
isa(getfield(tn.module, globname), tn.wrapper) && _isleaftype(tn.wrapper))
257257
globfunc = true
258258
end
259259
end
@@ -617,7 +617,7 @@ function show_expr_type(io::IO, @nospecialize(ty), emph::Bool)
617617
elseif ty === Core.IntrinsicFunction
618618
print(io, "::I")
619619
else
620-
if emph && (!isleaftype(ty) || ty == Core.Box)
620+
if emph && (!_isleaftype(ty) || ty == Core.Box)
621621
emphasize(io, "::$ty")
622622
else
623623
print(io, "::$ty")
@@ -1171,7 +1171,7 @@ function show_tuple_as_call(io::IO, name::Symbol, sig::Type)
11711171
isdefined(uw.name.module, uw.name.mt.name) &&
11721172
ft == typeof(getfield(uw.name.module, uw.name.mt.name))
11731173
print(io, uw.name.mt.name)
1174-
elseif isa(ft, DataType) && ft.name === Type.body.name && isleaftype(ft)
1174+
elseif isa(ft, DataType) && ft.name === Type.body.name && !Core.Inference.has_free_typevars(ft)
11751175
f = ft.parameters[1]
11761176
print(io, f)
11771177
else
@@ -1913,7 +1913,7 @@ function array_eltype_show_how(X)
19131913
str = string(e)
19141914
end
19151915
# Types hard-coded here are those which are created by default for a given syntax
1916-
(isleaftype(e),
1916+
(_isleaftype(e),
19171917
(!isempty(X) && (e===Float64 || e===Int || e===Char || e===String) ? "" : str))
19181918
end
19191919

doc/src/stdlib/base.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ Base.fieldoffset
106106
Core.fieldtype
107107
Base.isimmutable
108108
Base.isbits
109-
Base.isleaftype
109+
Base.isconcrete
110110
Base.typejoin
111111
Base.typeintersect
112112
Base.instances

test/arrayops.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1916,7 +1916,7 @@ let A = zeros(Int, 2, 2), B = zeros(Float64, 2, 2)
19161916
for f in [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16,
19171917
f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
19181918
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42]
1919-
@test isleaftype(Base.return_types(f, ())[1])
1919+
@test Base._isleaftype(Base.return_types(f, ())[1])
19201920
end
19211921
end
19221922

test/core.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ let elT = T22624.body.body.body.types[1].parameters[1]
169169
elT2 = elT.body.types[1].parameters[1]
170170
@test elT2 == T22624{Int64, Int64, C} where C
171171
@test elT2.body.types[1].parameters[1] === elT2
172-
@test isleaftype(elT2.body.types[1])
172+
@test Base._isleaftype(elT2.body.types[1])
173173
end
174174

175175
# issue #3890
@@ -4284,7 +4284,7 @@ let a = Val{Val{TypeVar(:_, Int)}},
42844284

42854285
@test !isdefined(a, :instance)
42864286
@test isdefined(b, :instance)
4287-
@test isleaftype(b)
4287+
@test Base._isleaftype(b)
42884288
end
42894289

42904290
# A return type widened to Type{Union{T,Void}} should not confuse

test/inference.jl

+1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ function find_tvar10930(arg)
186186
end
187187
@test find_tvar10930(Vararg{Int}) === 1
188188

189+
const isleaftype = Base._isleaftype
189190

190191
# issue #12474
191192
@generated function f12474(::Any)

test/reflection.jl

+14-5
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,20 @@ end # module WarnType
139139
@test isbits(Tuple{Vararg{Any, 0}})
140140

141141
# issue #16670
142-
@test isleaftype(Tuple{Int, Vararg{Int, 2}})
143-
@test !isleaftype(Tuple{Integer, Vararg{Int, 2}})
144-
@test !isleaftype(Tuple{Int, Vararg{Int}})
145-
@test isleaftype(Type{Tuple{Integer, Vararg{Int}}})
146-
@test isleaftype(Type{Vector})
142+
@test Base._isleaftype(Tuple{Int, Vararg{Int, 2}})
143+
@test !Base._isleaftype(Tuple{Integer, Vararg{Int, 2}})
144+
@test !Base._isleaftype(Tuple{Int, Vararg{Int}})
145+
@test Base._isleaftype(Type{Tuple{Integer, Vararg{Int}}})
146+
@test Base._isleaftype(Type{Vector})
147+
@test isconcrete(Int)
148+
@test isconcrete(Vector{Int})
149+
@test isconcrete(Tuple{Int, Vararg{Int, 2}})
150+
@test !isconcrete(Tuple{Integer, Vararg{Int, 2}})
151+
@test !isconcrete(Tuple{Int, Vararg{Int}})
152+
@test !isconcrete(Type{Tuple{Integer, Vararg{Int}}})
153+
@test !isconcrete(Type{Vector})
154+
@test !isconcrete(Union{})
155+
@test !isconcrete(Tuple{Union{}})
147156

148157
# issue #10165
149158
i10165(::Type) = 0

0 commit comments

Comments
 (0)