From 077420c18050794dbdd1d9a024ff4ab4cdccc3d3 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Tue, 21 Feb 2017 10:47:25 +0100 Subject: [PATCH 1/3] Rename isleaftype() to isconcrete() For consistency, also change the C function jl_is_leaf_type() to jl_is_concrete_type(). Replace (almost) all uses of "leaf" which mean "concrete". --- base/broadcast.jl | 4 +- base/complex.jl | 2 +- base/deprecated.jl | 2 + base/dict.jl | 4 +- base/exports.jl | 2 +- base/float.jl | 2 +- base/inference.jl | 54 ++++++++++---------- base/interactiveutil.jl | 6 +-- base/methodshow.jl | 4 +- base/nullable.jl | 4 +- base/promotion.jl | 4 +- base/reflection.jl | 22 ++++---- base/replutil.jl | 2 +- base/set.jl | 4 +- base/show.jl | 6 +-- doc/images/jltypes.svg | 4 +- doc/src/devdocs/object.md | 2 +- doc/src/manual/calling-c-and-fortran-code.md | 8 +-- doc/src/manual/performance-tips.md | 4 +- doc/src/stdlib/base.md | 2 +- src/array.c | 2 +- src/builtins.c | 2 +- src/ccall.cpp | 22 ++++---- src/cgutils.cpp | 32 ++++++------ src/codegen.cpp | 54 ++++++++++---------- src/datatype.c | 8 +-- src/dump.c | 4 +- src/gf.c | 38 +++++++------- src/interpreter.c | 2 +- src/intrinsics.cpp | 6 +-- src/jltypes.c | 36 ++++++------- src/julia.h | 16 +++--- src/method.c | 2 +- src/runtime_intrinsics.c | 6 +-- src/subtype.c | 20 ++++---- src/typemap.c | 42 +++++++-------- test/arrayops.jl | 2 +- test/core.jl | 2 +- test/inference.jl | 16 +++--- test/reflection.jl | 12 ++--- 40 files changed, 234 insertions(+), 232 deletions(-) diff --git a/base/broadcast.jl b/base/broadcast.jl index d85194e670cc9..02e8f41a42141 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -289,7 +289,7 @@ _broadcast_eltype(f, A, Bs...) = Base._return_type(f, eltypestuple(A, Bs...)) T = _broadcast_eltype(f, A, Bs...) shape = broadcast_indices(A, Bs...) iter = CartesianRange(shape) - if isleaftype(T) + if isconcrete(T) return broadcast_t(f, T, shape, iter, A, Bs...) end if isempty(iter) @@ -305,7 +305,7 @@ end @inline function broadcast_c(f, ::Type{Nullable}, a...) nonnull = all(hasvalue, a) S = _broadcast_eltype(f, a...) - if isleaftype(S) && null_safe_eltype_op(f, a...) + if isconcrete(S) && null_safe_eltype_op(f, a...) Nullable{S}(f(map(unsafe_get, a)...), nonnull) else if nonnull diff --git a/base/complex.jl b/base/complex.jl index 4a1ae9ed210e1..ba4fdfb65628d 100644 --- a/base/complex.jl +++ b/base/complex.jl @@ -885,7 +885,7 @@ big(z::Complex{<:Integer}) = Complex{BigInt}(z) complex(A::AbstractArray{<:Complex}) = A function complex{T}(A::AbstractArray{T}) - if !isleaftype(T) + if !isconcrete(T) error("`complex` not defined on abstractly-typed arrays; please convert to a more specific type") end convert(AbstractArray{typeof(complex(zero(T)))}, A) diff --git a/base/deprecated.jl b/base/deprecated.jl index 9ecfd1843f90f..aff54d7b8c2ad 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1278,6 +1278,8 @@ end @deprecate_binding LinearSlow IndexCartesian false @deprecate_binding linearindexing IndexStyle false +@deprecate isleaftype isconcrete + # END 0.6 deprecations # BEGIN 1.0 deprecations diff --git a/base/dict.jl b/base/dict.jl index 4fe8ce2d669e3..90dedd9bf4e00 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -34,7 +34,7 @@ function show{K,V}(io::IO, t::Associative{K,V}) if isempty(t) print(io, typeof(t), "()") else - if isleaftype(K) && isleaftype(V) + if isconcrete(K) && isconcrete(V) print(io, typeof(t).name) else print(io, typeof(t)) @@ -161,7 +161,7 @@ associative_with_eltype(DT_apply, ::Type) = DT_apply(Any, Any)() associative_with_eltype{F}(DT_apply::F, kv, t) = grow_to!(associative_with_eltype(DT_apply, _default_eltype(typeof(kv))), kv) function associative_with_eltype{F}(DT_apply::F, kv::Generator, t) T = _default_eltype(typeof(kv)) - if T <: Union{Pair, Tuple{Any, Any}} && isleaftype(T) + if T <: Union{Pair, Tuple{Any, Any}} && isconcrete(T) return associative_with_eltype(DT_apply, kv, T) end return grow_to!(associative_with_eltype(DT_apply, T), kv) diff --git a/base/exports.jl b/base/exports.jl index 51bfbf6632ef1..e4f8f970f6d8b 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -979,7 +979,7 @@ export fieldoffset, fieldname, fieldnames, - isleaftype, + isconcrete, oftype, promote, promote_rule, diff --git a/base/float.jl b/base/float.jl index f3b7abdfa5c4c..a2715231a8a48 100644 --- a/base/float.jl +++ b/base/float.jl @@ -848,7 +848,7 @@ truncmask(x, mask) = x float(A::AbstractArray{<:AbstractFloat}) = A function float{T}(A::AbstractArray{T}) - if !isleaftype(T) + if !isconcrete(T) error("`float` not defined on abstractly-typed arrays; please convert to a more specific type") end convert(AbstractArray{typeof(float(zero(T)))}, A) diff --git a/base/inference.jl b/base/inference.jl index eb52cbde5f204..724e677715808 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -347,7 +347,7 @@ const _Type_name = Type.body.name isType(t::ANY) = isa(t, DataType) && (t::DataType).name === _Type_name # true if Type is inlineable as constant (is a singleton) -isconstType(t::ANY) = isType(t) && (isleaftype(t.parameters[1]) || t.parameters[1] === Union{}) +isconstType(t::ANY) = isType(t) && (isconcrete(t.parameters[1]) || t.parameters[1] === Union{}) const IInf = typemax(Int) # integer infinity const n_ifunc = reinterpret(Int32,arraylen)+1 @@ -544,7 +544,7 @@ add_tfunc(nfields, 1, 1, isa(x,Const) && return Const(nfields(x.val)) isa(x,Conditional) && return Const(nfields(Bool)) if isType(x) - isleaftype(x.parameters[1]) && return Const(nfields(x.parameters[1])) + isconcrete(x.parameters[1]) && return Const(nfields(x.parameters[1])) elseif isa(x,DataType) && !x.abstract && !(x.name === Tuple.name && isvatuple(x)) return Const(length(x.types)) end @@ -578,13 +578,13 @@ function typeof_tfunc(t::ANY) return Const(Bool) elseif isType(t) tp = t.parameters[1] - if !isleaftype(tp) + if !isconcrete(tp) return DataType # typeof(Kind::Type)::DataType else return Const(typeof(tp)) # XXX: this is not necessarily true end elseif isa(t, DataType) - if isleaftype(t) || isvarargtype(t) + if isconcrete(t) || isvarargtype(t) return Const(t) elseif t === Any return DataType @@ -625,11 +625,11 @@ add_tfunc(isa, 2, 2, if t !== Any && !has_free_typevars(t) if v ⊑ t return Const(true) - elseif isa(v, Const) || isa(v, Conditional) || isleaftype(v) + elseif isa(v, Const) || isa(v, Conditional) || isconcrete(v) return Const(false) end end - # TODO: handle non-leaftype(t) by testing against lower and upper bounds + # TODO: handle non-concrete t by testing against lower and upper bounds return Bool end) add_tfunc(issubtype, 2, 2, @@ -739,7 +739,7 @@ function getfield_tfunc(s00::ANY, name) s = unwrap_unionall(s00) if isType(s) p1 = s.parameters[1] - if !isleaftype(p1) + if !isconcrete(p1) return Any end s = DataType # typeof(p1) @@ -826,7 +826,7 @@ function getfield_tfunc(s00::ANY, name) if fld < 1 || fld > nf return Bottom end - if isType(s00) && isleaftype(s00.parameters[1]) + if isType(s00) && isconcrete(s00.parameters[1]) sp = s00.parameters[1] elseif isa(s00, Const) && isa(s00.val, DataType) sp = s00.val @@ -926,7 +926,7 @@ has_free_typevars(t::ANY) = ccall(:jl_has_free_typevars, Cint, (Any,), t)!=0 function apply_type_tfunc(headtypetype::ANY, args::ANY...) if isa(headtypetype, Const) headtype = headtypetype.val - elseif isType(headtypetype) && isleaftype(headtypetype.parameters[1]) + elseif isType(headtypetype) && isconcrete(headtypetype.parameters[1]) headtype = headtypetype.parameters[1] else return Any @@ -949,7 +949,7 @@ function apply_type_tfunc(headtypetype::ANY, args::ANY...) ai = args[i] if isType(ai) aty = ai.parameters[1] - isleaftype(aty) || (allconst = false) + isconcrete(aty) || (allconst = false) else aty = (ai::Const).val end @@ -970,7 +970,7 @@ function apply_type_tfunc(headtypetype::ANY, args::ANY...) ai = args[i] if isType(ai) aip1 = ai.parameters[1] - canconst &= isleaftype(aip1) + canconst &= isconcrete(aip1) push!(tparams, aip1) elseif isa(ai, Const) && (isa(ai.val, Type) || isa(ai.val, TypeVar) || valid_tparam(ai.val)) push!(tparams, ai.val) @@ -1045,7 +1045,7 @@ add_tfunc(apply_type, 1, IInf, apply_type_tfunc) end function invoke_tfunc(f::ANY, types::ANY, argtype::ANY, sv::InferenceState) - if !isleaftype(Type{types}) + if !isconcrete(Type{types}) return Any end argtype = typeintersect(types,limit_tuple_type(argtype, sv.params)) @@ -1513,7 +1513,7 @@ function return_type_tfunc(argtypes::ANY, vtypes::VarTable, sv::InferenceState) if isa(tt, Const) || (isType(tt) && !has_free_typevars(tt)) aft = argtypes[2] if isa(aft, Const) || (isType(aft) && !has_free_typevars(aft)) || - (isleaftype(aft) && !(aft <: Builtin) && !(aft <: IntrinsicFunction)) + (isconcrete(aft) && !(aft <: Builtin) && !(aft <: IntrinsicFunction)) af_argtype = isa(tt, Const) ? tt.val : tt.parameters[1] if isa(af_argtype, DataType) && af_argtype <: Tuple argtypes_vec = Any[aft, af_argtype.parameters...] @@ -1527,7 +1527,7 @@ function return_type_tfunc(argtypes::ANY, vtypes::VarTable, sv::InferenceState) if isa(rt, Const) # output was computed to be constant return Const(typeof(rt.val)) - elseif isleaftype(rt) + elseif isconcrete(rt) # output type was known for certain return Const(rt) elseif (isa(tt, Const) || isconstType(tt)) && @@ -1614,9 +1614,9 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect if isa(aft, Const) af = aft.val else - if isType(aft) && isleaftype(aft.parameters[1]) + if isType(aft) && isconcrete(aft.parameters[1]) af = aft.parameters[1] - elseif isleaftype(aft) && isdefined(aft, :instance) + elseif isconcrete(aft) && isdefined(aft, :instance) af = aft.instance else # TODO jb/functions: take advantage of case where non-constant `af`'s type is known @@ -1847,9 +1847,9 @@ function abstract_eval_call(e::Expr, vtypes::VarTable, sv::InferenceState) if isa(ft, Const) f = ft.val else - if isType(ft) && isleaftype(ft.parameters[1]) + if isType(ft) && isconcrete(ft.parameters[1]) f = ft.parameters[1] - elseif isleaftype(ft) && isdefined(ft, :instance) + elseif isconcrete(ft) && isdefined(ft, :instance) f = ft.instance else for i = 2:(length(argtypes)-1) @@ -1858,7 +1858,7 @@ function abstract_eval_call(e::Expr, vtypes::VarTable, sv::InferenceState) end end # non-constant function, but type is known - if (isleaftype(ft) || ft <: Type) && !(ft <: Builtin) && !(ft <: IntrinsicFunction) + if (isconcrete(ft) || ft <: Type) && !(ft <: Builtin) && !(ft <: IntrinsicFunction) return abstract_call_gf_by_type(nothing, argtypes_to_type(argtypes), sv) end return Any @@ -2370,7 +2370,7 @@ function code_for_method(method::Method, atypes::ANY, sparams::SimpleVector, wor if world < min_world(method) || world > max_world(method) return nothing end - if method.isstaged && !isleaftype(atypes) + if method.isstaged && !isconcrete(atypes) # don't call staged functions on abstract types. # (see issues #8504, #10230) # we can't guarantee that their type behavior is monotonic. @@ -3397,7 +3397,7 @@ function effect_free(e::ANY, src::CodeInfo, mod::Module, allow_volatile::Bool) return false elseif is_known_call(e, getfield, src, mod) et = exprtype(e, src, mod) - if !isa(et,Const) && !(isType(et) && isleaftype(et)) + if !isa(et,Const) && !(isType(et) && isconcrete(et)) # first argument must be immutable to ensure e is affect_free a = ea[2] typ = widenconst(exprtype(a, src, mod)) @@ -3635,7 +3635,7 @@ end # inline functions whose bodies are "inline_worthy" # where the function body doesn't contain any argument more than once. -# static parameters are ok if all the static parameter values are leaf types, +# static parameters are ok if all the static parameter values are concrete types, # meaning they are fully known. # `ft` is the type of the function. `f` is the exact function if known, or else `nothing`. function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::InferenceState) @@ -3643,7 +3643,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference if (f === typeassert || ft ⊑ typeof(typeassert)) && length(atypes)==3 # typeassert(x::S, T) => x, when S<:T - if isType(atypes[3]) && isleaftype(atypes[3]) && + if isType(atypes[3]) && isconcrete(atypes[3]) && atypes[2] ⊑ atypes[3].parameters[1] return (argexprs[2], ()) end @@ -3667,7 +3667,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference if f === Core.invoke && length(atypes) >= 3 ft = widenconst(atypes[2]) invoke_tt = widenconst(atypes[3]) - if !isleaftype(ft) || !isleaftype(invoke_tt) || !isType(invoke_tt) + if !isconcrete(ft) || !isconcrete(invoke_tt) || !isType(invoke_tt) return NF end if !(isa(invoke_tt.parameters[1], Type) && @@ -4333,7 +4333,7 @@ function inlining_pass(e::Expr, sv::InferenceState) ft = Bool else f = nothing - if !( isleaftype(ft) || ft<:Type ) + if !( isconcrete(ft) || ft<:Type ) return (e, stmts) end end @@ -4438,7 +4438,7 @@ function inlining_pass(e::Expr, sv::InferenceState) ft = Bool else f = nothing - if !( isleaftype(ft) || ft<:Type ) + if !( isconcrete(ft) || ft<:Type ) return (e,stmts) end end @@ -4950,7 +4950,7 @@ function is_allocation(e::ANY, sv::InferenceState) return (length(e.args)-1,()) elseif e.head === :new typ = widenconst(exprtype(e, sv.src, sv.mod)) - if isa(typ, DataType) && isleaftype(typ) + if isa(typ, DataType) && isconcrete(typ) nf = length(e.args) - 1 names = fieldnames(typ) @assert(nf <= nfields(typ)) diff --git a/base/interactiveutil.jl b/base/interactiveutil.jl index 1d569265a3773..77f8b49959be0 100644 --- a/base/interactiveutil.jl +++ b/base/interactiveutil.jl @@ -315,8 +315,8 @@ versioninfo(verbose::Bool) = versioninfo(STDOUT,verbose) Prints lowered and type-inferred ASTs for the methods matching the given generic function and type signature to `io` which defaults to `STDOUT`. The ASTs are annotated in such a way -as to cause "non-leaf" types to be emphasized (if color is available, displayed in red). -This serves as a warning of potential type instability. Not all non-leaf types are particularly +as to cause non-concrete types to be emphasized (if color is available, displayed in red). +This serves as a warning of potential type instability. Not all non-concrete types are particularly problematic for performance, so the results need to be used judiciously. See [`@code_warntype`](@ref man-code-warntype) for more information. """ @@ -502,7 +502,7 @@ Evaluates the arguments to the function or macro call, determines their types, a function type_close_enough(x::ANY, t::ANY) x == t && return true return (isa(x,DataType) && isa(t,DataType) && x.name === t.name && - !isleaftype(t) && x <: t) || + !isconcrete(t) && x <: t) || (isa(x,Union) && isa(t,DataType) && (type_close_enough(x.a, t) || type_close_enough(x.b, t))) end diff --git a/base/methodshow.jl b/base/methodshow.jl index 95623a477b542..bc58520dd7a92 100644 --- a/base/methodshow.jl +++ b/base/methodshow.jl @@ -111,7 +111,7 @@ function show(io::IO, m::Method; kwtype::Nullable{DataType}=Nullable{DataType}() # TODO: more accurate test? (tn.name === "#" name) ft == typeof(getfield(ft.name.module, ft.name.mt.name)) print(io, ft.name.mt.name) - elseif isa(ft, DataType) && ft.name === Type.body.name && isleaftype(ft) + elseif isa(ft, DataType) && ft.name === Type.body.name && isconcrete(ft) f = ft.parameters[1] if isa(f, DataType) && isempty(f.parameters) print(io, f) @@ -232,7 +232,7 @@ function show(io::IO, ::MIME"text/html", m::Method; kwtype::Nullable{DataType}=N isdefined(ft.name.module, ft.name.mt.name) && ft == typeof(getfield(ft.name.module, ft.name.mt.name)) print(io, ft.name.mt.name) - elseif isa(ft, DataType) && ft.name === Type.body.name && isleaftype(ft) + elseif isa(ft, DataType) && ft.name === Type.body.name && isconcrete(ft) f = ft.parameters[1] if isa(f, DataType) && isempty(f.parameters) print(io, f) diff --git a/base/nullable.jl b/base/nullable.jl index c27804abd895f..43ff7066ac112 100644 --- a/base/nullable.jl +++ b/base/nullable.jl @@ -271,7 +271,7 @@ end """ Return the given type if it is concrete, and `Union{}` otherwise. """ -nullable_returntype{T}(::Type{T}) = isleaftype(T) ? T : Union{} +nullable_returntype{T}(::Type{T}) = isconcrete(T) ? T : Union{} """ map(f, x::Nullable) @@ -285,7 +285,7 @@ type `Nullable{typeof(f(x))}`. """ function map{T}(f, x::Nullable{T}) S = promote_op(f, T) - if isleaftype(S) && null_safe_op(f, T) + if isconcrete(S) && null_safe_op(f, T) Nullable(f(unsafe_get(x)), !isnull(x)) else if isnull(x) diff --git a/base/promotion.jl b/base/promotion.jl index 98efd35b044a3..832b80caa6dcf 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -314,13 +314,13 @@ promote_op(::Any...) = (@_pure_meta; Any) function promote_op{S}(f, ::Type{S}) @_inline_meta T = _return_type(f, Tuple{_default_type(S)}) - isleaftype(S) && return isleaftype(T) ? T : Any + isconcrete(S) && return isconcrete(T) ? T : Any return typejoin(S, T) end function promote_op{R,S}(f, ::Type{R}, ::Type{S}) @_inline_meta T = _return_type(f, Tuple{_default_type(R), _default_type(S)}) - isleaftype(R) && isleaftype(S) && return isleaftype(T) ? T : Any + isconcrete(R) && isconcrete(S) && return isconcrete(T) ? T : Any return typejoin(R, S, T) end diff --git a/base/reflection.jl b/base/reflection.jl index 12995bcb0a55f..51c7450da6978 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -234,25 +234,25 @@ isbits(t::Type) = (@_pure_meta; false) isbits(x) = (@_pure_meta; isbits(typeof(x))) """ - isleaftype(T) + isconcrete(T) Determine whether `T`'s only subtypes are itself and `Union{}`. This means `T` is a concrete type that can have instances. ```jldoctest -julia> isleaftype(Complex) +julia> isconcrete(Complex) false -julia> isleaftype(Complex{Float32}) +julia> isconcrete(Complex{Float32}) true -julia> isleaftype(Vector{Complex}) +julia> isconcrete(Vector{Complex}) true -julia> isleaftype(Vector{Complex{Float32}}) +julia> isconcrete(Vector{Complex{Float32}}) true """ -isleaftype(t::ANY) = (@_pure_meta; isa(t, DataType) && t.isleaftype) +isconcrete(t::ANY) = (@_pure_meta; isa(t, DataType) && t.isconcrete) """ Base.isabstract(T) @@ -727,8 +727,8 @@ function _dump_function_linfo(linfo::Core.MethodInstance, world::UInt, native::B (Ptr{Void}, Bool, Bool), llvmf, strip_ir_metadata, dump_module) end - # TODO: use jl_is_cacheable_sig instead of isleaftype - isleaftype(linfo.specTypes) || (str = "; WARNING: This code may not match what actually runs.\n" * str) + # TODO: use jl_is_cacheable_sig instead of isconcrete + isconcrete(linfo.specTypes) || (str = "; WARNING: This code may not match what actually runs.\n" * str) return str end @@ -757,9 +757,9 @@ code_native(io::IO, f::ANY, types::ANY=Tuple, syntax::Symbol=:att) = code_native(f::ANY, types::ANY=Tuple, syntax::Symbol=:att) = code_native(STDOUT, f, types, syntax) code_native(::IO, ::ANY, ::Symbol) = error("illegal code_native call") # resolve ambiguous call -# give a decent error message if we try to instantiate a staged function on non-leaf types +# give a decent error message if we try to instantiate a staged function on non-concrete types function func_for_method_checked(m::Method, types::ANY) - if m.isstaged && !isleaftype(types) + if m.isstaged && !isconcrete(types) error("cannot call @generated function `", m, "` ", "with abstract argument types: ", types) end @@ -822,7 +822,7 @@ function which(f::ANY, t::ANY) throw(ArgumentError("argument is not a generic function")) end t = to_tuple_type(t) - if isleaftype(t) + if isconcrete(t) ms = methods(f, t) isempty(ms) && error("no method found for the specified argument types") length(ms)!=1 && error("no unique matching method for the specified argument types") diff --git a/base/replutil.jl b/base/replutil.jl index 4f60d3140e15e..78d8878ae31cd 100644 --- a/base/replutil.jl +++ b/base/replutil.jl @@ -434,7 +434,7 @@ function show_method_candidates(io::IO, ex::MethodError, kwargs::Vector=Any[]) # pool MethodErrors for these two functions. if f === convert && !isempty(arg_types_param) at1 = arg_types_param[1] - if isa(at1,DataType) && (at1::DataType).name === Type.body.name && isleaftype(at1) + if isa(at1,DataType) && (at1::DataType).name === Type.body.name && isconcrete(at1) push!(funcs, (at1.parameters[1], arg_types_param[2:end])) end end diff --git a/base/set.jl b/base/set.jl index f6983758c2195..8d941a54d3c0d 100644 --- a/base/set.jl +++ b/base/set.jl @@ -10,7 +10,7 @@ Set() = Set{Any}() Set(itr) = Set{eltype(itr)}(itr) function Set(g::Generator) T = _default_eltype(typeof(g)) - (isleaftype(T) || T === Union{}) || return grow_to!(Set{T}(), g) + (isconcrete(T) || T === Union{}) || return grow_to!(Set{T}(), g) return Set{T}(g) end @@ -132,7 +132,7 @@ function unique(itr) return out end x, i = next(itr, i) - if !isleaftype(T) + if !isconcrete(T) S = typeof(x) return _unique_from(itr, S[x], Set{S}((x,)), i) end diff --git a/base/show.jl b/base/show.jl index 35c69995f43c6..d74e3f963bbed 100644 --- a/base/show.jl +++ b/base/show.jl @@ -503,7 +503,7 @@ function show_expr_type(io::IO, ty, emph) elseif ty === Core.IntrinsicFunction print(io, "::I") else - if emph && (!isleaftype(ty) || ty == Core.Box) + if emph && (!isconcrete(ty) || ty == Core.Box) emphasize(io, "::$ty") else print(io, "::$ty") @@ -1044,7 +1044,7 @@ function show_lambda_types(io::IO, li::Core.MethodInstance) isdefined(ft.name.module, ft.name.mt.name) && ft == typeof(getfield(ft.name.module, ft.name.mt.name)) print(io, ft.name.mt.name) - elseif isa(ft, DataType) && ft.name === Type.body.name && isleaftype(ft) + elseif isa(ft, DataType) && ft.name === Type.body.name && isconcrete(ft) f = ft.parameters[1] print(io, f) else @@ -1732,7 +1732,7 @@ function array_eltype_show_how(X) str = string(e) end # Types hard-coded here are those which are created by default for a given syntax - isleaftype(e), (!isempty(X) && (e===Float64 || e===Int || e===Char) ? "" : str) + isconcrete(e), (!isempty(X) && (e===Float64 || e===Int || e===Char) ? "" : str) end function show_vector(io::IO, v, opn, cls) diff --git a/doc/images/jltypes.svg b/doc/images/jltypes.svg index dc7de531a649a..6e5f4bef22009 100644 --- a/doc/images/jltypes.svg +++ b/doc/images/jltypes.svg @@ -281,7 +281,7 @@ valid as type tags - - has uid assigned - not an abstract type - none of the direct type parametersare a TypeVar - no type parameter is a bound TypeVar*, recursively tested - if this is a Tuple type, then there is an additional restriction that all type parameters are leaf types + - has uid assigned - not an abstract type - none of the direct type parametersare a TypeVar - no type parameter is a bound TypeVar*, recursively tested - if this is a Tuple type, then there is an additional restriction that all type parameters are concrete types @@ -333,7 +333,7 @@ - is leaf type + is concrete type diff --git a/doc/src/devdocs/object.md b/doc/src/devdocs/object.md index 2b18c1f80d239..f81e440676e96 100644 --- a/doc/src/devdocs/object.md +++ b/doc/src/devdocs/object.md @@ -20,7 +20,7 @@ typedef struct { } jl_typetag_t; ``` -The type of any Julia object is an instance of a leaf `jl_datatype_t` object. The `jl_typeof()` +The type of any Julia object is an instance of a concrete `jl_datatype_t` object. The `jl_typeof()` function can be used to query for it: ```julia diff --git a/doc/src/manual/calling-c-and-fortran-code.md b/doc/src/manual/calling-c-and-fortran-code.md index 1ce2f564c0972..bc771c7eac97a 100644 --- a/doc/src/manual/calling-c-and-fortran-code.md +++ b/doc/src/manual/calling-c-and-fortran-code.md @@ -264,14 +264,14 @@ First, a review of some relevant Julia type terminology: | Syntax / Keyword | Example | Description | |:----------------------------- |:------------------------------------------- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `mutable struct` | `String` | "Leaf Type" :: A group of related data that includes a type-tag, is managed by the Julia GC, and is defined by object-identity. The type parameters of a leaf type must be fully defined (no `TypeVars` are allowed) in order for the instance to be constructed. | -| `abstract type` | `Any`, `AbstractArray{T, N}`, `Complex{T}` | "Super Type" :: A super-type (not a leaf-type) that cannot be instantiated, but can be used to describe a group of types. | +| `mutable struct` | `String` | "Concrete Type" :: A group of related data that includes a type-tag, is managed by the Julia GC, and is defined by object-identity. The type parameters of a concrete type must be fully defined (no `TypeVars` are allowed) in order for the instance to be constructed. | +| `abstract type` | `Any`, `AbstractArray{T, N}`, `Complex{T}` | "Super Type" :: A super-type (not a concrete type) that cannot be instantiated, but can be used to describe a group of types. | | `T{A}` | `Vector{Int}` | "Type Parameter" :: A specialization of a type (typically used for dispatch or storage optimization). | | | | "TypeVar" :: The `T` in the type parameter declaration is referred to as a TypeVar (short for type variable). | | `primitive type` | `Int`, `Float64` | "Primitive Type" :: A type with no fields, but a size. It is stored and defined by-value. | | `struct` | `Pair{Int, Int}` | "Struct" :: A type with all fields defined to be constant. It is defined by-value. And may be stored with a type-tag. | | | `Complex128` (`isbits`) | "Is-Bits" :: A `primitive type`, or a `struct` type where all fields are other `isbits` types. It is defined by-value, and is stored without a type-tag. | -| `struct ...; end` | `nothing` | "Singleton" :: a Leaf Type or Struct with no fields. | +| `struct ...; end` | `nothing` | "Singleton" :: a Concrete Type or Struct with no fields. | | `(...)` or `tuple(...)` | `(1, 2, 3)` | "Tuple" :: an immutable data-structure similar to an anonymous struct type, or a constant array. Represented as either an array or a struct. | ### Bits Types: @@ -574,7 +574,7 @@ For translating a C argument list to Julia: * argument value will be copied (passed by value) * `struct T` (including typedef to a struct) - * `T`, where `T` is a Julia leaf type + * `T`, where `T` is a Julia concrete type * argument value will be copied (passed by value) * `void*` diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index a0c9ed220dbe0..5c49243f4516c 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -1402,7 +1402,7 @@ is difficult or impossible: for example, currently it's not possible to infer th of an anonymous function. In such cases, the tips above (e.g., adding type annotations and/or breaking up functions) are your best tools to contain the "damage" from type instability. -The following examples may help you interpret expressions marked as containing non-leaf types: +The following examples may help you interpret expressions marked as containing non-concrete types: * Function body ending in `end::Union{T1,T2})` @@ -1419,7 +1419,7 @@ The following examples may help you interpret expressions marked as containing n element accesses * `(top(getfield))(A::ArrayContainer{Float64},:data)::Array{Float64,N}` - * Interpretation: getting a field that is of non-leaf type. In this case, `ArrayContainer` had a + * Interpretation: getting a field that is of non-concrete type. In this case, `ArrayContainer` had a field `data::Array{T}`. But `Array` needs the dimension `N`, too, to be a concrete type. * Suggestion: use concrete types like `Array{T,3}` or `Array{T,N}`, where `N` is now a parameter of `ArrayContainer` diff --git a/doc/src/stdlib/base.md b/doc/src/stdlib/base.md index 770ab55f9131b..4c6289d551f2f 100644 --- a/doc/src/stdlib/base.md +++ b/doc/src/stdlib/base.md @@ -107,7 +107,7 @@ Base.fieldoffset Core.fieldtype Base.isimmutable Base.isbits -Base.isleaftype +Base.isconcrete Base.typejoin Base.typeintersect Base.Val diff --git a/src/array.c b/src/array.c index 51690ddb5774f..6caf56fd3aa49 100644 --- a/src/array.c +++ b/src/array.c @@ -24,7 +24,7 @@ extern "C" { static inline int store_unboxed(jl_value_t *el_type) // jl_isbits { - return jl_is_leaf_type(el_type) && jl_is_immutable(el_type) && + return jl_is_concrete_type(el_type) && jl_is_immutable(el_type) && ((jl_datatype_t*)el_type)->layout && ((jl_datatype_t*)el_type)->layout->npointers == 0; } diff --git a/src/builtins.c b/src/builtins.c index 4d40c470a04c8..b41e42a76f06d 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -256,7 +256,7 @@ JL_CALLABLE(jl_f_sizeof) jl_error("type does not have a canonical binary representation"); if (!(dx->name->names == jl_emptysvec && jl_datatype_size(dx) > 0)) { // names===() and size > 0 => bitstype, size always known - if (dx->abstract || !jl_is_leaf_type(x)) + if (dx->abstract || !jl_is_concrete_type(x)) jl_error("argument is an abstract type; size is indeterminate"); } return jl_box_long(jl_datatype_size(x)); diff --git a/src/ccall.cpp b/src/ccall.cpp index 1e672d198efdf..f1d67dd2db046 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -549,7 +549,7 @@ static Value *julia_to_address(Type *to, jl_value_t *jlto, jl_unionall_t *jlto_e // yes copy Value *nbytes; AllocaInst *ai; - if (jl_is_leaf_type(ety) || jl_is_primitivetype(ety)) { + if (jl_is_concrete_type(ety) || jl_is_primitivetype(ety)) { int nb = jl_datatype_size(ety); nbytes = ConstantInt::get(T_int32, nb); ai = emit_static_alloca(T_int8, nb, ctx); @@ -1188,8 +1188,8 @@ static jl_cgval_t mark_or_box_ccall_result(Value *result, bool isboxed, jl_value if (!static_rt) { assert(!isboxed && ctx->spvals_ptr && unionall && jl_is_datatype(rt)); Value *runtime_dt = runtime_apply_type(rt, unionall, ctx); - // TODO: is this leaf check actually necessary, or is it structurally guaranteed? - emit_leafcheck(runtime_dt, "ccall: return type must be a leaf DataType", ctx); + // TODO: is this concrete check actually necessary, or is it structurally guaranteed? + emit_concrete_check(runtime_dt, "ccall: return type must be a concrete DataType", ctx); #if JL_LLVM_VERSION >= 30600 const DataLayout &DL = jl_ExecutionEngine->getDataLayout(); #else @@ -1430,11 +1430,11 @@ static const std::string verify_ccall_sig(size_t nargs, jl_value_t *&rt, jl_valu } if (!retboxed && static_rt) { - if (!jl_is_leaf_type(rt)) { + if (!jl_is_concrete_type(rt)) { if (jl_is_cpointer_type(rt)) return "ccall: return type Ptr should have an element type (not Ptr{_<:T})"; else if (rt != jl_bottom_type) - return "ccall: return type must be a leaf DataType"; + return "ccall: return type must be a concrete DataType"; } } @@ -1681,17 +1681,17 @@ static jl_cgval_t emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx) builder.SetInsertPoint(contBB); return ghostValue(jl_void_type); } - if (fptr == (void(*)(void))&jl_is_leaf_type || + if (fptr == (void(*)(void))&jl_is_concrete_type || ((f_lib==NULL || (intptr_t)f_lib==2) - && f_name && !strcmp(f_name, "jl_is_leaf_type"))) { + && f_name && !strcmp(f_name, "jl_is_concrete_type"))) { assert(nargt == 1); assert(!isVa && !llvmcall); jl_value_t *arg = args[4]; jl_value_t *ty = expr_type(arg, ctx); if (jl_is_type_type(ty) && !jl_is_typevar(jl_tparam0(ty))) { - int isleaf = jl_is_leaf_type(jl_tparam0(ty)); + int isconcrete = jl_is_concrete_type(jl_tparam0(ty)); JL_GC_POP(); - return mark_or_box_ccall_result(ConstantInt::get(T_int32, isleaf), + return mark_or_box_ccall_result(ConstantInt::get(T_int32, isconcrete), false, rt, unionall, static_rt, ctx); } } @@ -1717,7 +1717,7 @@ static jl_cgval_t emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx) if (jl_is_type_type((jl_value_t*)fargt)) fargt = jl_tparam0(fargt); } - if (jl_is_tuple_type(fargt) && jl_is_leaf_type(fargt)) { + if (jl_is_tuple_type(fargt) && jl_is_concrete_type(fargt)) { frt = jl_tparam0(frt); Value *llvmf = NULL; JL_TRY { @@ -1831,7 +1831,7 @@ jl_cgval_t function_sig_t::emit_a_ccall( jl_cgval_t &arg = argv[ai]; // if we know the function sparams, try to fill those in now - // so that the julia_to_native type checks are more likely to be doable (e.g. leaf types) at compile-time + // so that the julia_to_native type checks are more likely to be doable (e.g. concrete types) at compile-time jl_value_t *jargty_in_env = jargty; if (ctx->spvals_ptr == NULL && !toboxed && unionall_env && jl_has_typevar_from_unionall(jargty, unionall_env)) { jargty_in_env = jl_instantiate_type_in_env(jargty_in_env, unionall_env, jl_svec_data(ctx->linfo->sparam_vals)); diff --git a/src/cgutils.cpp b/src/cgutils.cpp index b2e3d2a4b84c5..c3afcdcf75408 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -180,7 +180,7 @@ static DIType julia_type_to_di(jl_value_t *jt, DIBuilder *dbuilder, bool isboxed #endif } #if JL_LLVM_VERSION >= 30700 - else if (!jl_is_leaf_type(jt)) { + else if (!jl_is_concrete_type(jt)) { jdt->ditype = jl_pvalue_dillvmt; return jl_pvalue_dillvmt; } @@ -364,7 +364,7 @@ JL_DLLEXPORT Type *julia_type_to_llvm(jl_value_t *jt, bool *isboxed) if (isboxed) *isboxed = false; if (jt == (jl_value_t*)jl_bottom_type) return T_void; - if (jl_is_leaf_type(jt)) { + if (jl_is_concrete_type(jt)) { if ((jl_is_primitivetype(jt) || jl_isbits(jt))) { if (jl_datatype_nbits(jt) == 0) return T_void; @@ -409,7 +409,7 @@ static Type *bitstype_to_llvm(jl_value_t *bt) return Type::getIntNTy(jl_LLVMContext, nb * 8); } -// compute whether all leaf subtypes of this type have the same layout +// compute whether all concrete subtypes of this type have the same layout // (which is conservatively approximated here by asking whether the types of any of the // fields depend on any of the parameters of the containing type) static bool julia_struct_has_layout(jl_datatype_t *dt, jl_unionall_t *ua) @@ -466,7 +466,7 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isbox if (jst->layout) isptr = jl_field_isptr(jst, i); else // compute what jl_compute_field_offsets would say - isptr = jl_isbits(ty) && jl_is_leaf_type(ty) && ((jl_datatype_t*)ty)->layout; + isptr = jl_isbits(ty) && jl_is_concrete_type(ty) && ((jl_datatype_t*)ty)->layout; Type *lty; if (isptr) lty = T_pjlvalue; @@ -542,7 +542,7 @@ static bool is_tupletype_homogeneous(jl_svec_t *t) size_t i, l = jl_svec_len(t); if (l > 0) { jl_value_t *t0 = jl_svecref(t, 0); - if (!jl_is_leaf_type(t0)) + if (!jl_is_concrete_type(t0)) return false; for(i=1; i < l; i++) { if (!jl_types_equal(t0, jl_svecref(t,i))) @@ -617,7 +617,7 @@ static Value *emit_typeof(Value *tt) static jl_cgval_t emit_typeof(const jl_cgval_t &p, jl_codectx_t *ctx) { // given p, compute its type - if (!p.constant && p.isboxed && !jl_is_leaf_type(p.typ)) { + if (!p.constant && p.isboxed && !jl_is_concrete_type(p.typ)) { return mark_julia_type(emit_typeof(p.V), true, jl_datatype_type, ctx, /*needsroot*/false); } jl_value_t *aty = p.typ; @@ -827,7 +827,7 @@ static Value *emit_isa(const jl_cgval_t &x, jl_value_t *type, const std::string #endif ConstantInt::get(T_int32, 0)); } - else if (jl_is_leaf_type(type)) { + else if (jl_is_concrete_type(type)) { istype = builder.CreateICmpEQ(emit_typeof_boxed(x, ctx), literal_pointer_val(type)); } else { @@ -865,15 +865,15 @@ static void emit_typecheck(const jl_cgval_t &x, jl_value_t *type, const std::str } } -static void emit_leafcheck(Value *typ, const std::string &msg, jl_codectx_t *ctx) +static void emit_concrete_check(Value *typ, const std::string &msg, jl_codectx_t *ctx) { assert(typ->getType() == T_pjlvalue); emit_typecheck(mark_julia_type(typ, true, jl_any_type, ctx, false), (jl_value_t*)jl_datatype_type, msg, ctx); - Value *isleaf; - isleaf = builder.CreateConstInBoundsGEP1_32(LLVM37_param(T_int8) emit_bitcast(typ, T_pint8), offsetof(jl_datatype_t, isleaftype)); - isleaf = builder.CreateLoad(isleaf, tbaa_const); - isleaf = builder.CreateTrunc(isleaf, T_int1); - error_unless(isleaf, msg, ctx); + Value *isconcrete; + isconcrete = builder.CreateConstInBoundsGEP1_32(LLVM37_param(T_int8) emit_bitcast(typ, T_pint8), offsetof(jl_datatype_t, isconcrete)); + isconcrete = builder.CreateLoad(isconcrete, tbaa_const); + isconcrete = builder.CreateTrunc(isconcrete, T_int1); + error_unless(isconcrete, msg, ctx); } #define CHECK_BOUNDS 1 @@ -1240,7 +1240,7 @@ static Value *emit_n_varargs(jl_codectx_t *ctx) static bool arraytype_constshape(jl_value_t *ty) { - return (jl_is_array_type(ty) && jl_is_leaf_type(ty) && + return (jl_is_array_type(ty) && jl_is_concrete_type(ty) && jl_is_long(jl_tparam1(ty)) && jl_unbox_long(jl_tparam1(ty)) != 1); } @@ -1667,7 +1667,7 @@ static Value *boxed(const jl_cgval_t &vinfo, jl_codectx_t *ctx, bool gcrooted) if (vinfo.isboxed) return vinfo.V; - assert(jl_isbits(jt) && jl_is_leaf_type(jt) && "This type shouldn't have been unboxed."); + assert(jl_isbits(jt) && jl_is_concrete_type(jt) && "This type shouldn't have been unboxed."); Type *t = julia_type_to_llvm(jt); assert(!type_is_ghost(t)); // ghost values should have been handled by vinfo.constant above! Value *box = _boxed_special(vinfo, t, ctx); @@ -1816,7 +1816,7 @@ static bool might_need_root(jl_value_t *ex) static jl_cgval_t emit_new_struct(jl_value_t *ty, size_t nargs, jl_value_t **args, jl_codectx_t *ctx) { assert(jl_is_datatype(ty)); - assert(jl_is_leaf_type(ty)); + assert(jl_is_concrete_type(ty)); assert(nargs>0); jl_datatype_t *sty = (jl_datatype_t*)ty; size_t nf = jl_datatype_nfields(sty); diff --git a/src/codegen.cpp b/src/codegen.cpp index 0207d89eda480..36feb8b1005b2 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -453,7 +453,7 @@ struct jl_cgval_t { isboxed(isboxed), isghost(false), isimmutable(isboxed && jl_is_immutable_datatype(typ)), - tbaa(isboxed ? (jl_is_leaf_type(typ) ? + tbaa(isboxed ? (jl_is_concrete_type(typ) ? (jl_is_mutable(typ) ? tbaa_mutab : tbaa_immut) : tbaa_value) : nullptr) { @@ -658,7 +658,7 @@ static inline jl_cgval_t mark_julia_type(Value *v, bool isboxed, jl_value_t *typ // no need to explicitly load/store a constant/ghost value return ghostValue(typ); } - if (jl_is_type_type(typ) && jl_is_leaf_type(jl_tparam0(typ))) { + if (jl_is_type_type(typ) && jl_is_concrete_type(jl_tparam0(typ))) { // replace T::Type{T} with T jl_cgval_t constant(NULL, NULL, true, typ); constant.constant = jl_tparam0(typ); @@ -753,7 +753,7 @@ static void CreateTrap(IRBuilder<> &builder) static bool isbits_spec(jl_value_t *jt, bool allow_singleton = true) { - return jl_isbits(jt) && jl_is_leaf_type(jt) && + return jl_isbits(jt) && jl_is_concrete_type(jt) && (allow_singleton || (jl_datatype_size(jt) > 0) || (jl_datatype_nfields(jt) > 0)); } @@ -2050,7 +2050,7 @@ static Value *make_jlcall(ArrayRef args, jl_codectx_t *ctx) static void jl_add_method_root(jl_codectx_t *ctx, jl_value_t *val) { - if (jl_is_leaf_type(val) || jl_is_bool(val) || jl_is_symbol(val) || + if (jl_is_concrete_type(val) || jl_is_bool(val) || jl_is_symbol(val) || val == (jl_value_t*)jl_any_type || val == (jl_value_t*)jl_bottom_type) return; JL_GC_PUSH1(&val); @@ -2098,10 +2098,10 @@ static jl_cgval_t emit_getfield(jl_value_t *expr, jl_sym_t *name, jl_codectx_t * jl_datatype_t *sty = (jl_datatype_t*)expr_type(expr, ctx); JL_GC_PUSH1(&sty); - if (jl_is_type_type((jl_value_t*)sty) && jl_is_leaf_type(jl_tparam0(sty))) + if (jl_is_type_type((jl_value_t*)sty) && jl_is_concrete_type(jl_tparam0(sty))) sty = (jl_datatype_t*)jl_typeof(jl_tparam0(sty)); if (jl_is_structtype(sty) && sty != jl_module_type && sty->uid != 0 && - jl_is_leaf_type((jl_value_t*)sty)) { + jl_is_concrete_type((jl_value_t*)sty)) { unsigned idx = jl_field_index(sty, name, 0); if (idx != (unsigned)-1) { jl_cgval_t strct = emit_expr(expr, ctx); @@ -2126,7 +2126,7 @@ static jl_cgval_t emit_getfield(jl_value_t *expr, jl_sym_t *name, jl_codectx_t * Value *result = builder.CreateCall3(prepare_call(jlgetfield_func), V_null, myargs, ConstantInt::get(T_int32,2)); #endif - bool needsgcroot = true; // !arg1.isimmutable || !jl_is_leaf_type(arg1.typ) || !is_datatype_all_pointers((jl_datatype_t*)arg1.typ); // TODO: probably want this as a llvm pass + bool needsgcroot = true; // !arg1.isimmutable || !jl_is_concrete_type(arg1.typ) || !is_datatype_all_pointers((jl_datatype_t*)arg1.typ); // TODO: probably want this as a llvm pass jl_cgval_t ret = mark_julia_type(result, true, jl_any_type, ctx, needsgcroot); // (typ will be patched up by caller) return ret; } @@ -2210,12 +2210,12 @@ static Value *emit_bits_compare(const jl_cgval_t &arg1, const jl_cgval_t &arg2, static Value *emit_f_is(const jl_cgval_t &arg1, const jl_cgval_t &arg2, jl_codectx_t *ctx) { jl_value_t *rt1 = arg1.typ, *rt2 = arg2.typ; - bool isleaf = jl_is_leaf_type(rt1) && jl_is_leaf_type(rt2); - if (isleaf && rt1 != rt2 && !jl_is_type_type(rt1) && !jl_is_type_type(rt2)) - // disjoint leaf types are never equal (quick test) + bool isconcrete = jl_is_concrete_type(rt1) && jl_is_concrete_type(rt2); + if (isconcrete && rt1 != rt2 && !jl_is_type_type(rt1) && !jl_is_type_type(rt2)) + // disjoint concrete types are never equal (quick test) return ConstantInt::get(T_int1, 0); - bool ghost1 = arg1.isghost || (isleaf && jl_is_datatype_singleton((jl_datatype_t*)rt1)); - bool ghost2 = arg2.isghost || (isleaf && jl_is_datatype_singleton((jl_datatype_t*)rt2)); + bool ghost1 = arg1.isghost || (isconcrete && jl_is_datatype_singleton((jl_datatype_t*)rt1)); + bool ghost2 = arg2.isghost || (isconcrete && jl_is_datatype_singleton((jl_datatype_t*)rt2)); if (ghost1 || ghost2) { // comparing singleton objects if (ghost1 && ghost2) { @@ -2231,7 +2231,7 @@ static Value *emit_f_is(const jl_cgval_t &arg1, const jl_cgval_t &arg2, jl_codec if (jl_type_intersection(rt1, rt2) == (jl_value_t*)jl_bottom_type) // types are disjoint (exhaustive test) return ConstantInt::get(T_int1, 0); - bool isbits = isleaf && jl_isbits(rt1) && jl_types_equal(rt1, rt2); + bool isbits = isconcrete && jl_isbits(rt1) && jl_types_equal(rt1, rt2); if (isbits) { // whether this type is unique'd by value return emit_bits_compare(arg1, arg2, ctx); } @@ -2243,8 +2243,8 @@ static Value *emit_f_is(const jl_cgval_t &arg1, const jl_cgval_t &arg2, jl_codec if (jl_subtype(rt1, (jl_value_t*)jl_type_type) || jl_subtype(rt2, (jl_value_t*)jl_type_type)) // use typeseq for datatypes ptr_comparable = 0; - if ((jl_is_type_type(rt1) && jl_is_leaf_type(jl_tparam0(rt1))) || - (jl_is_type_type(rt2) && jl_is_leaf_type(jl_tparam0(rt2)))) // can compare leaf types by pointer + if ((jl_is_type_type(rt1) && jl_is_concrete_type(jl_tparam0(rt1))) || + (jl_is_type_type(rt2) && jl_is_concrete_type(jl_tparam0(rt2)))) // can compare concrete types by pointer ptr_comparable = 1; if (ptr_comparable) { assert(arg1.isboxed && arg2.isboxed); // only boxed types are valid for pointer comparison @@ -2405,7 +2405,7 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args, } if (ctx->source->inferred) { rt1 = expr_type(expr, ctx); - if (jl_is_tuple_type(rt1) && jl_is_leaf_type(rt1) && nargs == jl_datatype_nfields(rt1)) { + if (jl_is_tuple_type(rt1) && jl_is_concrete_type(rt1) && nargs == jl_datatype_nfields(rt1)) { *ret = emit_new_struct(rt1, nargs+1, args, ctx); JL_GC_POP(); return true; @@ -2618,7 +2618,7 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args, return true; } - if (fldt == (jl_value_t*)jl_long_type && jl_is_leaf_type((jl_value_t*)stt)) { + if (fldt == (jl_value_t*)jl_long_type && jl_is_concrete_type((jl_value_t*)stt)) { if ((jl_is_structtype(stt) || jl_is_tuple_type(stt)) && !jl_subtype((jl_value_t*)jl_module_type, (jl_value_t*)stt)) { size_t nfields = jl_datatype_nfields(stt); jl_cgval_t strct = emit_expr(args[1], ctx); @@ -2655,7 +2655,7 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args, jl_value_t *ft = jl_svecref(sty->types, idx); jl_value_t *rhst = expr_type(args[3], ctx); rt2 = rhst; - if (jl_is_leaf_type((jl_value_t*)sty) && jl_subtype(rhst, ft)) { + if (jl_is_concrete_type((jl_value_t*)sty) && jl_subtype(rhst, ft)) { // TODO: attempt better codegen for approximate types jl_cgval_t strct = emit_expr(args[1], ctx); // emit lhs *ret = emit_expr(args[3], ctx); @@ -2677,7 +2677,7 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args, jl_value_t *aty = expr_type(args[1], ctx); rt1 = aty; if (jl_is_type_type(aty)) { jl_value_t *tp0 = jl_tparam0(aty); - if (jl_is_leaf_type(tp0)) { + if (jl_is_concrete_type(tp0)) { emit_expr(args[1], ctx); assert(jl_is_datatype(tp0)); *ret = mark_julia_type(ConstantInt::get(T_size, jl_datatype_nfields(tp0)), false, jl_long_type, ctx); @@ -2685,7 +2685,7 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args, return true; } } - else if (jl_is_leaf_type(aty)) { + else if (jl_is_concrete_type(aty)) { jl_cgval_t arg1 = emit_expr(args[1], ctx); Value *sz; if (arg1.constant) { @@ -2738,7 +2738,7 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args, // exclude DataType, since each DataType has its own size, not sizeof(DataType). // this is issue #8798 sty != (jl_value_t*)jl_datatype_type) { - if (jl_is_leaf_type(sty) || + if (jl_is_concrete_type(sty) || (((jl_datatype_t*)sty)->name->names == jl_emptysvec && jl_datatype_size(sty) > 0)) { *ret = mark_julia_type(ConstantInt::get(T_size, jl_datatype_size(sty)), false, jl_long_type, ctx); JL_GC_POP(); @@ -2760,7 +2760,7 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args, } if (i > nargs) { jl_value_t *ty = static_eval(expr, ctx, true, true); - if (ty!=NULL && jl_is_leaf_type(ty)) { + if (ty!=NULL && jl_is_concrete_type(ty)) { if (jl_has_free_typevars(ty)) { // add root for types not cached. issue #7065 jl_add_method_root(ctx, ty); @@ -2774,7 +2774,7 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args, else if (f == jl_builtin_isdefined && nargs == 2) { jl_datatype_t *stt = (jl_datatype_t*)expr_type(args[1], ctx); - if (!jl_is_leaf_type((jl_value_t*)stt) || jl_is_array_type(stt) || + if (!jl_is_concrete_type((jl_value_t*)stt) || jl_is_array_type(stt) || stt == jl_module_type) { JL_GC_POP(); return false; @@ -3452,7 +3452,7 @@ static jl_cgval_t emit_expr(jl_value_t *expr, jl_codectx_t *ctx) // some intrinsics (e.g. typeassert) can return a wider type // than what's actually possible jl_value_t *expr_t = expr_type((jl_value_t*)ex, ctx); - if (res.typ != expr_t && res.isboxed && !jl_is_leaf_type(res.typ)) { + if (res.typ != expr_t && res.isboxed && !jl_is_concrete_type(res.typ)) { res = remark_julia_type(res, expr_t, ctx); } if (res.typ == jl_bottom_type || expr_t == jl_bottom_type) { @@ -3532,7 +3532,7 @@ static jl_cgval_t emit_expr(jl_value_t *expr, jl_codectx_t *ctx) size_t nargs = jl_array_len(ex->args); if (jl_is_type_type(ty) && jl_is_datatype(jl_tparam0(ty)) && - jl_is_leaf_type(jl_tparam0(ty))) { + jl_is_concrete_type(jl_tparam0(ty))) { assert(nargs <= jl_datatype_nfields(jl_tparam0(ty))+1); return emit_new_struct(jl_tparam0(ty),nargs,args,ctx); } @@ -4108,7 +4108,7 @@ static Function *jl_cfunction_object(jl_function_t *ff, jl_value_t *declrt, jl_t jl_error("cfunction: return type Ref should have an element type, not Ref{T}"); if (declrt == (jl_value_t*)jl_any_type) jl_error("cfunction: return type Ref{Any} is invalid. Use Any or Ptr{Any} instead."); - if (!jl_is_leaf_type(declrt)) + if (!jl_is_concrete_type(declrt)) jl_svecset(cfunc_sig, nargs + 1, declrt); // Ref{Abstract} is the same calling convention as Abstract crt = (jl_value_t*)jl_any_type; } @@ -4125,7 +4125,7 @@ static Function *jl_cfunction_object(jl_function_t *ff, jl_value_t *declrt, jl_t ati = jl_tparam0(ati); if (jl_is_typevar(ati)) jl_error("cfunction: argument type Ref should have an element type, not Ref{T}"); - if (ati != (jl_value_t*)jl_any_type && !jl_is_leaf_type(ati)) + if (ati != (jl_value_t*)jl_any_type && !jl_is_concrete_type(ati)) jl_svecset(cfunc_sig, i + 1, ati); // Ref{Abstract} is the same calling convention as Abstract } if (jl_is_pointer(ati) && jl_is_typevar(jl_tparam0(ati))) diff --git a/src/datatype.c b/src/datatype.c index 5052433517430..ed9bd48f8e321 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -85,7 +85,7 @@ jl_datatype_t *jl_new_uninitialized_datatype(void) jl_datatype_t *t = (jl_datatype_t*)jl_gc_alloc(ptls, sizeof(jl_datatype_t), jl_datatype_type); t->depth = 0; t->hasfreetypevars = 0; - t->isleaftype = 1; + t->isconcrete = 1; t->layout = NULL; return t; } @@ -228,7 +228,7 @@ void jl_compute_field_offsets(jl_datatype_t *st) for (size_t i = 0; i < nfields; i++) { jl_value_t *ty = jl_field_type(st, i); size_t fsz, al; - if (jl_isbits(ty) && jl_is_leaf_type(ty) && ((jl_datatype_t*)ty)->layout) { + if (jl_isbits(ty) && jl_is_concrete_type(ty) && ((jl_datatype_t*)ty)->layout) { fsz = jl_datatype_size(ty); // Should never happen if (__unlikely(fsz > max_size)) @@ -358,7 +358,7 @@ JL_DLLEXPORT jl_datatype_t *jl_new_datatype(jl_sym_t *name, jl_datatype_t *super } else { t->uid = jl_assign_type_uid(); - if (t->types != NULL && t->isleaftype) { + if (t->types != NULL && t->isconcrete) { static const jl_datatype_layout_t singleton_layout = {0, 1, 0, 0, 0}; if (fnames == jl_emptysvec) t->layout = &singleton_layout; @@ -732,7 +732,7 @@ JL_DLLEXPORT size_t jl_get_field_offset(jl_datatype_t *ty, int field) JL_DLLEXPORT size_t jl_get_alignment(jl_datatype_t *ty) { if (ty->layout == NULL) - jl_error("non-leaf type doesn't have an alignment"); + jl_error("non-concrete type doesn't have an alignment"); return ty->layout->alignment; } diff --git a/src/dump.c b/src/dump.c index 7959f4c390b60..04dba7dbe638e 100644 --- a/src/dump.c +++ b/src/dump.c @@ -605,7 +605,7 @@ static void jl_serialize_datatype(jl_serializer_state *s, jl_datatype_t *dt) int has_instance = (dt->instance != NULL); int has_layout = (dt->layout != NULL); write_uint8(s->s, dt->abstract | (dt->mutabl<<1) | (has_layout<<2) | (has_instance<<3) | - (dt->hasfreetypevars<<4) | (dt->isleaftype<<5)); + (dt->hasfreetypevars<<4) | (dt->isconcrete<<5)); write_int32(s->s, dt->depth); if (!dt->abstract) { write_uint16(s->s, dt->ninitialized); @@ -1400,7 +1400,7 @@ static jl_value_t *jl_deserialize_datatype(jl_serializer_state *s, int pos, jl_v int has_layout = (flags>>2)&1; int has_instance = (flags>>3)&1; dt->hasfreetypevars = (flags>>4)&1; - dt->isleaftype = (flags>>5)&1; + dt->isconcrete = (flags>>5)&1; dt->depth = depth; dt->types = NULL; dt->parameters = NULL; diff --git a/src/gf.c b/src/gf.c index 84a2bcb3923dc..c2f0a10bd0799 100644 --- a/src/gf.c +++ b/src/gf.c @@ -532,13 +532,13 @@ static jl_tupletype_t *join_tsig(jl_tupletype_t *tt, jl_tupletype_t *sig) // if the declared type was not Any or Union{Type, ...}, // then the match must been with UnionAll or DataType // and the result of matching the type signature - // needs to be corrected to the leaf type 'kind' + // needs to be corrected to the concrete type 'kind' jl_value_t *kind = jl_typeof(jl_tparam0(elt)); if (jl_subtype(kind, decl_i)) { if (!jl_subtype((jl_value_t*)jl_type_type, decl_i)) { // UnionAlls are problematic because they can be alternate // representations of any type. If we matched this method because - // it matched the leaf type UnionAll, then don't cache something + // it matched the concrete type UnionAll, then don't cache something // different since that doesn't necessarily actually apply. // // similarly, if we matched Type{T<:Any}::DataType, @@ -718,7 +718,7 @@ JL_DLLEXPORT int jl_is_cacheable_sig( // if the declared type was not Any or Union{Type, ...}, // then the match must been with TypeConstructor or DataType // and the result of matching the type signature - // needs to be corrected to the leaf type 'kind' + // needs to be corrected to the concrete type 'kind' jl_value_t *kind = jl_typeof(jl_tparam0(elt)); if (kind != (jl_value_t*)jl_tvar_type && jl_subtype(kind, decl_i)) { if (!jl_subtype((jl_value_t*)jl_type_type, decl_i)) @@ -800,7 +800,7 @@ JL_DLLEXPORT int jl_is_cacheable_sig( return 0; continue; } - else if (!jl_is_leaf_type(elt)) { + else if (!jl_is_concrete_type(elt)) { return 0; } } @@ -854,7 +854,7 @@ static jl_method_instance_t *cache_method(jl_methtable_t *mt, union jl_typemap_t // then specialize as (Any...) // // note: this also protects the work join_tsig did to correct `types` for the - // leaftype signatures TypeConstructor and DataType + // concrete type signatures TypeConstructor and DataType // (assuming those made an unlikely appearance in Varargs position) size_t j = i; int all_are_subtypes = 1; @@ -1449,7 +1449,7 @@ jl_tupletype_t *arg_type_tuple(jl_value_t **args, size_t nargs) else types[i] = jl_typeof(ai); } - // if `ai` has free type vars this will not be a leaf type. + // if `ai` has free type vars this will not be a concrete type. // TODO: it would be really nice to only dispatch and cache those as // `jl_typeof(ai)`, but that will require some redesign of the caching // logic. @@ -1491,7 +1491,7 @@ jl_method_instance_t *jl_method_lookup_by_type(jl_methtable_t *mt, jl_tupletype_ JL_UNLOCK(&mt->writelock); return linfo; } - if (jl_is_leaf_type((jl_value_t*)types)) + if (jl_is_concrete_type((jl_value_t*)types)) cache = 1; jl_method_instance_t *sf = jl_mt_assoc_by_type(mt, types, cache, inexact, allow_exec, world); if (cache) { @@ -1616,7 +1616,7 @@ jl_llvm_functions_t jl_compile_for_dispatch(jl_method_instance_t **pli, size_t w jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types, size_t world) { JL_TIMING(METHOD_LOOKUP_COMPILE); - if (!jl_is_leaf_type((jl_value_t*)types) || jl_has_free_typevars((jl_value_t*)types)) + if (!jl_is_concrete_type((jl_value_t*)types) || jl_has_free_typevars((jl_value_t*)types)) return NULL; jl_value_t *args = jl_unwrap_unionall((jl_value_t*)types); @@ -1734,9 +1734,9 @@ static int _compile_all_tvar_union(jl_tupletype_t *methsig, jl_svec_t *tvars) tvs = (jl_tvar_t**)jl_svec_data(tvars); tvarslen = jl_svec_len(tvars); if (tvarslen == 0) { - if (jl_is_leaf_type((jl_value_t*)methsig)) { + if (jl_is_concrete_type((jl_value_t*)methsig)) { // usually can create a specialized version of the function, - // if the signature is already a leaftype + // if the signature is already a concrete type if (jl_compile_hint(methsig)) { return 1; } @@ -1769,7 +1769,7 @@ static int _compile_all_tvar_union(jl_tupletype_t *methsig, jl_svec_t *tvars) if (sig == jl_bottom_type || tupletype_any_bottom(sig)) { goto getnext; // signature wouldn't be callable / is invalid -- skip it } - if (jl_is_leaf_type(sig)) { + if (jl_is_concrete_type(sig)) { if (jl_compile_hint((jl_tupletype_t*)sig)) { if (!jl_has_typevars((jl_value_t*)sig)) goto getnext; // success } @@ -1789,7 +1789,7 @@ static int _compile_all_tvar_union(jl_tupletype_t *methsig, jl_svec_t *tvars) } else { jl_value_t *ty = jl_svecref(ub->types, j); - if (!jl_is_leaf_type(ty)) + if (!jl_is_concrete_type(ty)) ty = (jl_value_t*)jl_new_typevar(tv->name, tv->lb, ty); env[2 * i + 1] = ty; idx[i] = j + 1; @@ -2133,7 +2133,7 @@ JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t **args, uint32_t nargs) /* search order: - check associative hash based on callsite address for leafsig match + check associative hash based on callsite address for concrete sig match look at concrete signatures if there is an exact match, return it otherwise look for a matching generic signature @@ -2169,8 +2169,8 @@ JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t **args, uint32_t nargs) jl_value_t *F = args[0]; mt = jl_gf_mtable(F); entry = jl_typemap_assoc_exact(mt->cache, args, nargs, jl_cachearg_offset(mt), world); - if (entry && entry->isleafsig && entry->simplesig == (void*)jl_nothing && entry->guardsigs == jl_emptysvec) { - // put the entry into the cache if it's valid for a leaftype lookup, + if (entry && entry->isconcretesig && entry->simplesig == (void*)jl_nothing && entry->guardsigs == jl_emptysvec) { + // put the entry into the cache if it's valid for a concrete type lookup, // using pick_which to slightly randomize where it ends up call_cache[cache_idx[++pick_which[cache_idx[0]] & 3]] = entry; } @@ -2326,7 +2326,7 @@ JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_methtable_t *mt, jl_tupletype_t *tt, size_t world) { - if (!jl_is_leaf_type((jl_value_t*)tt) || tupletype_has_datatype(tt, NULL)) + if (!jl_is_concrete_type((jl_value_t*)tt) || tupletype_has_datatype(tt, NULL)) return jl_nothing; jl_method_t *method = entry->func.method; @@ -2531,9 +2531,9 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio // the "limited" mode used by type inference. for (i = 0; i < len; i++) { jl_value_t *prior_ti = jl_svecref(jl_array_ptr_ref(closure->t, i), 0); - // TODO: should be possible to remove the `jl_is_leaf_type` check, + // TODO: should be possible to remove the `jl_is_concrete_type` check, // but we still need it in case an intersection was approximate. - if (jl_is_leaf_type(prior_ti) && jl_subtype(closure->match.ti, prior_ti)) { + if (jl_is_concrete_type(prior_ti) && jl_subtype(closure->match.ti, prior_ti)) { skip = 1; break; } @@ -2562,7 +2562,7 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio // if the queried type is a subtype, but not all tvars matched, then // this method is excluded by the static-parameters-must-have-values rule if (!matched_all_tvars((jl_value_t*)ml->sig, jl_svec_data(env), jl_svec_len(env))) - return_this_match = !jl_is_leaf_type(closure->match.type); + return_this_match = !jl_is_concrete_type(closure->match.type); else done = 1; // stop; signature fully covers queried type } diff --git a/src/interpreter.c b/src/interpreter.c index 36e072c76458d..db8f147559173 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -460,7 +460,7 @@ static jl_value_t *eval(jl_value_t *e, interpreter_state *s) } if (dt->name->names == jl_emptysvec) dt->layout = jl_void_type->layout; // reuse the same layout for all singletons - else if (jl_is_leaf_type((jl_value_t*)dt)) + else if (jl_is_concrete_type((jl_value_t*)dt)) jl_compute_field_offsets(dt); if (para == (jl_value_t*)jl_emptysvec && jl_is_datatype_make_singleton(dt)) { dt->instance = jl_gc_alloc(ptls, 0, dt); diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index f865217b7c69b..12d74f05367fb 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -459,7 +459,7 @@ static jl_cgval_t generic_bitcast(const jl_cgval_t *argv, jl_codectx_t *ctx) vx = emit_bitcast(vx, llvmt); } - if (jl_is_leaf_type(bt)) + if (jl_is_concrete_type(bt)) return mark_julia_type(vx, false, bt, ctx); else return mark_julia_type( @@ -605,7 +605,7 @@ static jl_cgval_t emit_pointerref(jl_cgval_t *argv, jl_codectx_t *ctx) true, ety, ctx); } - if (!jl_is_structtype(ety) || jl_is_array_type(ety) || !jl_is_leaf_type(ety)) { + if (!jl_is_structtype(ety) || jl_is_array_type(ety) || !jl_is_concrete_type(ety)) { emit_error("pointerref: invalid pointer type", ctx); return jl_cgval_t(); } @@ -666,7 +666,7 @@ static jl_cgval_t emit_pointerset(jl_cgval_t *argv, jl_codectx_t *ctx) Value *thePtr; if (!jl_isbits(ety) && ety != (jl_value_t*)jl_any_type) { - if (!jl_is_structtype(ety) || jl_is_array_type(ety) || !jl_is_leaf_type(ety)) { + if (!jl_is_structtype(ety) || jl_is_array_type(ety) || !jl_is_concrete_type(ety)) { emit_error("pointerset: invalid pointer type", ctx); return jl_cgval_t(); } diff --git a/src/jltypes.c b/src/jltypes.c index 037fbfaf21dd2..2d022272e221a 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -234,18 +234,18 @@ JL_DLLEXPORT int jl_has_typevar_from_unionall(jl_value_t *t, jl_unionall_t *ua) } -JL_DLLEXPORT int (jl_is_leaf_type)(jl_value_t *v) +JL_DLLEXPORT int (jl_is_concrete_type)(jl_value_t *v) { if (jl_is_datatype(v)) { - int isleaf = ((jl_datatype_t*)v)->isleaftype; + int isconcrete = ((jl_datatype_t*)v)->isconcrete; #ifdef NDEBUG - return isleaf; + return isconcrete; #else if (((jl_datatype_t*)v)->abstract) { int x = 0; if (jl_is_type_type(v)) x = !jl_has_free_typevars(jl_tparam0(v)); - assert(x == isleaf); + assert(x == isconcrete); return x; } jl_svec_t *t = ((jl_datatype_t*)v)->parameters; @@ -253,8 +253,8 @@ JL_DLLEXPORT int (jl_is_leaf_type)(jl_value_t *v) if (((jl_datatype_t*)v)->name == jl_tuple_typename) { for(int i=0; i < l; i++) { jl_value_t *p = jl_svecref(t,i); - if (!jl_is_leaf_type(p) && p != jl_bottom_type) { - assert(!isleaf); + if (!jl_is_concrete_type(p) && p != jl_bottom_type) { + assert(!isconcrete); return 0; } } @@ -262,12 +262,12 @@ JL_DLLEXPORT int (jl_is_leaf_type)(jl_value_t *v) else { for(int i=0; i < l; i++) { if (jl_has_free_typevars(jl_svecref(t, i))) { - assert(!isleaf); + assert(!isconcrete); return 0; } } } - assert(isleaf); + assert(isconcrete); return 1; #endif } @@ -610,7 +610,7 @@ static int is_cacheable(jl_datatype_t *type) if (jl_is_abstracttype(type)) return !jl_has_free_typevars((jl_value_t*)type); // ... or concrete types - return jl_is_leaf_type((jl_value_t*)type); + return jl_is_concrete_type((jl_value_t*)type); } static void cache_insert_type(jl_value_t *type, ssize_t insert_at, int ordered) @@ -846,7 +846,7 @@ void jl_precompute_memoized_dt(jl_datatype_t *dt) { int istuple = dt->name == jl_tuple_typename; size_t i, l = jl_nparams(dt); - dt->isleaftype = !dt->abstract || (jl_type_type != NULL && dt->name == jl_type_typename); + dt->isconcrete = !dt->abstract || (jl_type_type != NULL && dt->name == jl_type_typename); for (i = 0; i < l; i++) { jl_value_t *p = jl_tparam(dt, i); size_t d = jl_type_depth(p) + 1; @@ -854,8 +854,8 @@ void jl_precompute_memoized_dt(jl_datatype_t *dt) dt->depth = d; if (!dt->hasfreetypevars) dt->hasfreetypevars = jl_has_free_typevars(p); - if (dt->isleaftype) - dt->isleaftype = (istuple ? (jl_is_leaf_type(p) || p == jl_bottom_type) : + if (dt->isconcrete) + dt->isconcrete = (istuple ? (jl_is_concrete_type(p) || p == jl_bottom_type) : !dt->hasfreetypevars); } } @@ -949,7 +949,7 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i jl_value_t *pi = iparams[i]; if (pi == jl_bottom_type) continue; - if (jl_is_leaf_type(pi)) { + if (jl_is_concrete_type(pi)) { assert(jl_is_datatype(pi)); if (!((jl_datatype_t*)pi)->abstract) continue; @@ -1137,7 +1137,7 @@ static jl_tupletype_t *jl_apply_tuple_type_v_(jl_value_t **p, size_t np, jl_svec { int cacheable = 1; for(size_t i=0; i < np; i++) { - if (!jl_is_leaf_type(p[i])) + if (!jl_is_concrete_type(p[i])) cacheable = 0; } jl_datatype_t *ndt = (jl_datatype_t*)inst_datatype(jl_anytuple_type, params, p, np, @@ -1226,7 +1226,7 @@ static jl_value_t *inst_tuple_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_ iparams[i] = pi; if (ip_heap) jl_gc_wb(ip_heap, pi); - if (cacheable && !jl_is_leaf_type(pi)) + if (cacheable && !jl_is_concrete_type(pi)) cacheable = 0; } jl_value_t *result = inst_datatype((jl_datatype_t*)tt, ip_heap, iparams, ntp, cacheable, @@ -1518,7 +1518,7 @@ void jl_init_types(void) jl_symbol("llvm::DIType"), jl_symbol("depth"), jl_symbol("hasfreetypevars"), - jl_symbol("isleaftype")); + jl_symbol("isconcrete")); jl_datatype_type->types = jl_svec(16, jl_typename_type, jl_datatype_type, @@ -1652,7 +1652,7 @@ void jl_init_types(void) jl_anytuple_type->types = jl_anytuple_type->parameters; jl_anytuple_type->layout = NULL; jl_anytuple_type->hasfreetypevars = 0; - jl_anytuple_type->isleaftype = 0; + jl_anytuple_type->isconcrete = 0; jl_tvar_t *tttvar = tvar("T"); ((jl_datatype_t*)jl_type_type)->parameters = jl_svec(1, tttvar); @@ -1730,7 +1730,7 @@ void jl_init_types(void) jl_symbol("min_world"), jl_symbol("max_world"), jl_symbol("func"), - jl_symbol("isleafsig"), + jl_symbol("isconcretesig"), jl_symbol("issimplesig"), jl_symbol("va")), jl_svec(10, diff --git a/src/julia.h b/src/julia.h index 89ee52892a7d8..513940f8475b8 100644 --- a/src/julia.h +++ b/src/julia.h @@ -175,7 +175,7 @@ struct _jl_method_instance_t; // typedef TypeMap Union{TypeMapLevel, TypeMapEntry, Void} // it forms a roughly tree-shaped structure, consisting of nodes of TypeMapLevels // which split the tree when possible, for example based on the key into the tuple type at `offs` -// when key is a leaftype, (but only when the tree has enough entries for this to be +// when key is a concrete type (but only when the tree has enough entries for this to be // more efficient than storing them sorted linearly) // otherwise the leaf entries are stored sorted, linearly union jl_typemap_t { @@ -377,7 +377,7 @@ typedef struct _jl_datatype_t { void *ditype; // llvm::MDNode* to be used as llvm::DIType(ditype) int32_t depth; int8_t hasfreetypevars; - int8_t isleaftype; + int8_t isconcrete; } jl_datatype_t; typedef struct { @@ -423,8 +423,8 @@ typedef struct _jl_typemap_entry_t { jl_method_t *method; } func; // memoized properties of sig: - int8_t isleafsig; // isleaftype(sig) & !any(isType, sig) : unsorted and very fast - int8_t issimplesig; // all(isleaftype | isAny | isType | isVararg, sig) : sorted and fast + int8_t isconcretesig; // isconcrete(sig) & !any(isType, sig) : unsorted and very fast + int8_t issimplesig; // all(isconcrete | isAny | isType | isVararg, sig) : sorted and fast int8_t va; // isVararg(sig) } jl_typemap_entry_t; @@ -967,7 +967,7 @@ JL_DLLEXPORT int jl_egal(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT uintptr_t jl_object_id(jl_value_t *v); // type predicates and basic operations -JL_DLLEXPORT int jl_is_leaf_type(jl_value_t *v); +JL_DLLEXPORT int jl_is_concrete_type(jl_value_t *v); JL_DLLEXPORT int jl_has_free_typevars(jl_value_t *v); JL_DLLEXPORT int jl_has_typevar(jl_value_t *t, jl_tvar_t *v); JL_DLLEXPORT int jl_has_typevar_from_unionall(jl_value_t *t, jl_unionall_t *ua); @@ -985,11 +985,11 @@ jl_value_t *jl_unwrap_unionall(jl_value_t *v); jl_value_t *jl_rewrap_unionall(jl_value_t *t, jl_value_t *u); #ifdef NDEBUG -STATIC_INLINE int jl_is_leaf_type_(jl_value_t *v) +STATIC_INLINE int jl_is_concrete_type_(jl_value_t *v) { - return jl_is_datatype(v) && ((jl_datatype_t*)v)->isleaftype; + return jl_is_datatype(v) && ((jl_datatype_t*)v)->isconcrete; } -#define jl_is_leaf_type(v) jl_is_leaf_type_(v) +#define jl_is_concrete_type(v) jl_is_concrete_type_(v) #endif // type constructors diff --git a/src/method.c b/src/method.c index 40fe7ec9ff31e..70c8c3339bc2d 100644 --- a/src/method.c +++ b/src/method.c @@ -609,7 +609,7 @@ JL_DLLEXPORT void jl_method_def(jl_svec_t *argdata, if (ftype == NULL || !(jl_is_type_type((jl_value_t*)ftype) || (jl_is_datatype(ftype) && - (!ftype->abstract || jl_is_leaf_type((jl_value_t*)ftype)) && + (!ftype->abstract || jl_is_concrete_type((jl_value_t*)ftype)) && ftype->name->mt != NULL))) jl_error("cannot add methods to an abstract type"); mt = ftype->name->mt; diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index d107a3a898294..f1a644196956b 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -18,7 +18,7 @@ const unsigned int host_char_bit = 8; JL_DLLEXPORT jl_value_t *jl_bitcast(jl_value_t *ty, jl_value_t *v) { JL_TYPECHK(bitcast, datatype, ty); - if (!jl_is_leaf_type(ty) || !jl_is_primitivetype(ty)) + if (!jl_is_concrete_type(ty) || !jl_is_primitivetype(ty)) jl_error("bitcast: target type not a leaf primitive type"); if (!jl_is_primitivetype(jl_typeof(v))) jl_error("bitcast: value not a primitive type"); @@ -83,8 +83,8 @@ JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty) v == (jl_value_t*)jl_void_type ? (jl_value_t*)jl_voidpointer_type : // a common case (jl_value_t*)jl_apply_type1((jl_value_t*)jl_pointer_type, ty); - if (!jl_is_leaf_type(rt)) - jl_error("cglobal: type argument not a leaftype"); + if (!jl_is_concrete_type(rt)) + jl_error("cglobal: type argument not a concrete type"); if (jl_is_tuple(v) && jl_nfields(v) == 1) v = jl_fieldref(v, 0); diff --git a/src/subtype.c b/src/subtype.c index 0a7b136ff2b81..7f6639b7f53f7 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -197,9 +197,9 @@ static int obviously_unequal(jl_value_t *a, jl_value_t *b) { if (a == b) return 0; - if (jl_is_leaf_type(a) && !((jl_datatype_t*)a)->abstract) + if (jl_is_concrete_type(a) && !((jl_datatype_t*)a)->abstract) return 1; - if (jl_is_leaf_type(b) && !((jl_datatype_t*)b)->abstract) + if (jl_is_concrete_type(b) && !((jl_datatype_t*)b)->abstract) return 1; if (jl_is_unionall(a)) a = jl_unwrap_unionall(a); if (jl_is_unionall(b)) b = jl_unwrap_unionall(b); @@ -398,7 +398,7 @@ static int is_leaf_bound(jl_value_t *v) { if (v == jl_bottom_type) return 1; if (jl_is_datatype(v)) { - if (((jl_datatype_t*)v)->isleaftype) return 1; + if (((jl_datatype_t*)v)->isconcrete) return 1; if (((jl_datatype_t*)v)->abstract) { if (jl_is_type_type(v)) return 1;//!jl_has_free_typevars(jl_tparam0(v)); @@ -634,7 +634,7 @@ static int subtype_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_stenv_t *e, in } if (xi == lastx && ((yi == lasty && !jl_has_free_typevars(xi) && !jl_has_free_typevars(yi)) || - (yi == lasty && !vx && vy && jl_is_leaf_type(xi)))) { + (yi == lasty && !vx && vy && jl_is_concrete_type(xi)))) { // fast path for repeated elements } else if (e->Runions.depth == 0 && e->Lunions.depth == 0 && !jl_has_free_typevars(xi) && !jl_has_free_typevars(yi)) { @@ -755,7 +755,7 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param) // TODO this is not strictly correct, but we don't yet have any other way for // e.g. the argument `Int` to match a `::DataType` slot. Most correct would be: // Int isa DataType, Int isa Type{Int}, Type{Int} more specific than DataType, - // !(Type{Int} <: DataType), !isleaftype(Type{Int}), because non-DataTypes can + // !(Type{Int} <: DataType), !isconcrete(Type{Int}), because non-DataTypes can // be type-equal to `Int`. return jl_typeof(tp0) == (jl_value_t*)yd; } @@ -1007,7 +1007,7 @@ JL_DLLEXPORT int jl_isa(jl_value_t *x, jl_value_t *t) if (t == (jl_value_t*)jl_type_type) return 1; if (!jl_has_free_typevars(x)) { - if (jl_is_leaf_type(t)) { + if (jl_is_concrete_type(t)) { if (jl_is_type_type(t)) return jl_types_equal(x, jl_tparam0(t)); return 0; @@ -1039,7 +1039,7 @@ JL_DLLEXPORT int jl_isa(jl_value_t *x, jl_value_t *t) return 0; } } - if (jl_is_leaf_type(t)) + if (jl_is_concrete_type(t)) return 0; return jl_subtype(jl_typeof(x), t); } @@ -1913,7 +1913,7 @@ jl_value_t *jl_type_intersection_env_s(jl_value_t *a, jl_value_t *b, jl_svec_t * *ans = b; } else { - int lta = jl_is_leaf_type(a), ltb = jl_is_leaf_type(b); + int lta = jl_is_concrete_type(a), ltb = jl_is_concrete_type(b); if (lta && ltb) goto bot; jl_stenv_t e; @@ -1933,10 +1933,10 @@ jl_value_t *jl_type_intersection_env_s(jl_value_t *a, jl_value_t *b, jl_svec_t * else { sz = szb; // TODO: compute better `env` directly during intersection. - // we assume that if the intersection is a leaf type, we have + // we assume that if the intersection is a concrete type, we have // full information in `env`. however the intersection algorithm // does not yet provide that in all cases so use subtype. - if (szb > 0 && jl_is_leaf_type(*ans) && !jl_types_equal(b, (jl_value_t*)jl_type_type)) { + if (szb > 0 && jl_is_concrete_type(*ans) && !jl_types_equal(b, (jl_value_t*)jl_type_type)) { if (jl_subtype_env(*ans, b, env, szb)) { for(i=0; i < sz; i++) { if (jl_is_typevar(env[i])) { diff --git a/src/typemap.c b/src/typemap.c index eb5ee8aefcfd0..dc12a24d817ec 100644 --- a/src/typemap.c +++ b/src/typemap.c @@ -32,7 +32,7 @@ static int sig_match_by_type_leaf(jl_value_t **types, jl_tupletype_t *sig, size_ for(i=0; i < n; i++) { jl_value_t *decl = jl_field_type(sig, i); jl_value_t *a = types[i]; - if (jl_is_type_type(a)) // decl is not Type, because it wouldn't be leafsig + if (jl_is_type_type(a)) // decl is not Type, because it wouldn't be concrete sig a = jl_typeof(jl_tparam0(a)); if (!jl_types_equal(a, decl)) return 0; @@ -326,7 +326,7 @@ static union jl_typemap_t *mtcache_hash_bp(struct jl_ordereddict_t *pa, jl_value if (jl_is_datatype(ty)) { uintptr_t uid = ((jl_datatype_t*)ty)->uid; if (!uid || jl_is_kind(ty) || jl_has_free_typevars(ty)) - // be careful not to put non-leaf types or DataType/TypeConstructor in the cache here, + // be careful not to put non-concrete types or DataType/TypeConstructor in the cache here, // since they should have a lower priority and need to go into the sorted list return NULL; if (pa->values == (void*)jl_nothing) { @@ -409,7 +409,7 @@ int jl_typemap_visitor(union jl_typemap_t cache, jl_typemap_visitor_fptr fptr, v } } -// predicate to fast-test if this type is a leaf type that can exist in the cache +// predicate to fast-test if this type is a concrete type that can exist in the cache // and does not need a more expensive linear scan to find all intersections int is_cache_leaf(jl_value_t *ty) { @@ -434,10 +434,10 @@ static int jl_typemap_intersection_array_visitor(struct jl_ordereddict_t *a, jl_ if (tparam) t = jl_tparam0(t); } - // `t` is a leaftype, so intersection test becomes subtype + // `t` is a concrete type, so intersection test becomes subtype if (ty == (jl_value_t*)jl_any_type || // easy case: Any always matches (tparam - ? (jl_typeof(t) == ty || jl_isa(t, ty)) // (Type{t} <: ty), where is_leaf_type(t) => isa(t, ty) + ? (jl_typeof(t) == ty || jl_isa(t, ty)) // (Type{t} <: ty), where isconcrete(t) => isa(t, ty) : (t == ty || jl_subtype(t, ty)))) { if (!jl_typemap_intersection_visitor(ml, offs + 1, closure)) return 0; @@ -505,7 +505,7 @@ int jl_typemap_intersection_visitor(union jl_typemap_t map, int offs, jl_value_t *typetype = jl_is_type_type(ty) ? jl_tparam0(ty) : NULL; if (typetype && !jl_has_free_typevars(typetype)) { if (is_cache_leaf(typetype)) { - // direct lookup of leaf types + // direct lookup of concrete types union jl_typemap_t ml = mtcache_hash_lookup(&cache->targ, typetype, 1, offs); if (ml.unknown != jl_nothing) { if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0; @@ -521,7 +521,7 @@ int jl_typemap_intersection_visitor(union jl_typemap_t map, int offs, } if (cache->arg1.values != (void*)jl_nothing) { if (is_cache_leaf(ty)) { - // direct lookup of leaf types + // direct lookup of concrete types union jl_typemap_t ml = mtcache_hash_lookup(&cache->arg1, ty, 0, offs); if (ml.unknown != jl_nothing) { if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0; @@ -575,7 +575,7 @@ static jl_typemap_entry_t *jl_typemap_assoc_by_type_(jl_typemap_entry_t *ml, jl_ if (ismatch == 0) ; // nothing - else if (ml->isleafsig && !typesisva) + else if (ml->isconcretesig && !typesisva) ismatch = sig_match_by_type_leaf(jl_svec_data(types->parameters), ml->sig, lensig); else if (ml->issimplesig && !typesisva) @@ -732,7 +732,7 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(union jl_typemap_t ml_or_cache, jl_ jl_typemap_entry_t *jl_typemap_entry_assoc_exact(jl_typemap_entry_t *ml, jl_value_t **args, size_t n, size_t world) { // some manually-unrolled common special cases - while (ml->simplesig == (void*)jl_nothing && ml->guardsigs == jl_emptysvec && ml->isleafsig) { + while (ml->simplesig == (void*)jl_nothing && ml->guardsigs == jl_emptysvec && ml->isconcretesig) { // use a tight loop for a long as possible if (world >= ml->min_world && world <= ml->max_world) { if (n == jl_field_count(ml->sig) && jl_typeof(args[0]) == jl_tparam(ml->sig, 0)) { @@ -775,7 +775,7 @@ jl_typemap_entry_t *jl_typemap_entry_assoc_exact(jl_typemap_entry_t *ml, jl_valu } } - if (ml->isleafsig) { + if (ml->isconcretesig) { if (!sig_match_leaf(args, jl_svec_data(ml->sig->parameters), n)) continue; } @@ -886,7 +886,7 @@ static jl_typemap_level_t *jl_method_convert_list_to_cache(jl_typemap_entry_t *m static void jl_typemap_list_insert_(jl_typemap_entry_t **pml, jl_value_t *parent, jl_typemap_entry_t *newrec, const struct jl_typemap_info *tparams) { - if (*pml == (void*)jl_nothing || newrec->isleafsig || (tparams && tparams->unsorted)) { + if (*pml == (void*)jl_nothing || newrec->isconcretesig || (tparams && tparams->unsorted)) { newrec->next = *pml; jl_gc_wb(newrec, newrec->next); *pml = newrec; @@ -1007,26 +1007,26 @@ jl_typemap_entry_t *jl_typemap_insert(union jl_typemap_t *cache, jl_value_t *par // compute the complexity of this type signature newrec->va = jl_is_va_tuple((jl_datatype_t*)ttype); newrec->issimplesig = !jl_is_unionall(type); // a TypeVar environment needs an complex matching test - newrec->isleafsig = newrec->issimplesig && !newrec->va; // entirely leaf types don't need to be sorted + newrec->isconcretesig = newrec->issimplesig && !newrec->va; // entirely concrete types don't need to be sorted JL_GC_PUSH1(&newrec); assert(jl_is_tuple_type(ttype)); size_t i, l; for (i = 0, l = jl_field_count(ttype); i < l && newrec->issimplesig; i++) { jl_value_t *decl = jl_field_type(ttype, i); if (decl == (jl_value_t*)jl_datatype_type) - newrec->isleafsig = 0; // Type{} may have a higher priority than DataType + newrec->isconcretesig = 0; // Type{} may have a higher priority than DataType else if (decl == (jl_value_t*)jl_unionall_type) - newrec->isleafsig = 0; // Type{} may have a higher priority than UnionAll + newrec->isconcretesig = 0; // Type{} may have a higher priority than UnionAll else if (jl_is_type_type(decl)) - newrec->isleafsig = 0; // Type{} may need special processing to compute the match + newrec->isconcretesig = 0; // Type{} may need special processing to compute the match else if (jl_is_vararg_type(decl)) - newrec->isleafsig = 0; // makes iteration easier when the endpoints are the same + newrec->isconcretesig = 0; // makes iteration easier when the endpoints are the same else if (decl == (jl_value_t*)jl_any_type) - newrec->isleafsig = 0; // Any needs to go in the general cache - else if (!jl_is_leaf_type(decl)) // anything else can go through the general subtyping test - newrec->isleafsig = newrec->issimplesig = 0; + newrec->isconcretesig = 0; // Any needs to go in the general cache + else if (!jl_is_concrete_type(decl)) // anything else can go through the general subtyping test + newrec->isconcretesig = newrec->issimplesig = 0; } - // TODO: assert that guardsigs == jl_emptysvec && simplesig == jl_nothing if isleafsig and optimize with that knowledge? + // TODO: assert that guardsigs == jl_emptysvec && simplesig == jl_nothing if isconcretesig and optimize with that knowledge? jl_typemap_insert_generic(cache, parent, newrec, NULL, offs, tparams); JL_GC_POP(); return newrec; @@ -1054,7 +1054,7 @@ static void jl_typemap_list_insert_sorted(jl_typemap_entry_t **pml, jl_value_t * l = *pml; jl_value_t *pa = parent; while (l != (void*)jl_nothing) { - if (!l->isleafsig) { // quickly ignore all of the leafsig entries (these were handled by caller) + if (!l->isconcretesig) { // quickly ignore all of the concrete sig entries (these were handled by caller) if (jl_type_morespecific((jl_value_t*)newrec->sig, (jl_value_t*)l->sig)) { if (l->simplesig == (void*)jl_nothing || newrec->simplesig != (void*)jl_nothing || !jl_types_equal((jl_value_t*)l->sig, (jl_value_t*)newrec->sig)) { diff --git a/test/arrayops.jl b/test/arrayops.jl index b0c016417b02d..a0248d8a47e66 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -1825,7 +1825,7 @@ let A = zeros(Int, 2, 2), B = zeros(Float64, 2, 2) for f in [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42] - @test isleaftype(Base.return_types(f, ())[1]) + @test isconcrete(Base.return_types(f, ())[1]) end end diff --git a/test/core.jl b/test/core.jl index 9fc29b36fcb29..c9c5d809df66f 100644 --- a/test/core.jl +++ b/test/core.jl @@ -4170,7 +4170,7 @@ let a = Val{Val{TypeVar(:_, Int)}}, @test !isdefined(a, :instance) @test isdefined(b, :instance) - @test isleaftype(b) + @test isconcrete(b) end # A return type widened to Type{Union{T,Void}} should not confuse diff --git a/test/inference.jl b/test/inference.jl index 0f637df2ea25a..c26e9e49f2c49 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -193,8 +193,8 @@ end end let ast12474 = code_typed(f12474, Tuple{Float64}) - @test isleaftype(ast12474[1][2]) - @test all(isleaftype, ast12474[1][1].slottypes) + @test isconcrete(ast12474[1][2]) + @test all(isconcrete, ast12474[1][1].slottypes) end @@ -226,7 +226,7 @@ bar7810() = [Foo7810([(a,b) for a in 1:2]) for b in 3:4] # issue #11366 f11366{T}(x::Type{Ref{T}}) = Ref{x} -@test !isleaftype(Base.return_types(f11366, (Any,))[1]) +@test !isconcrete(Base.return_types(f11366, (Any,))[1]) let f(T) = Type{T} @@ -442,10 +442,10 @@ function is_typed_expr(e::Expr) return false end test_inferred_static(other::ANY) = true -test_inferred_static(slot::TypedSlot) = @test isleaftype(slot.typ) +test_inferred_static(slot::TypedSlot) = @test isconcrete(slot.typ) function test_inferred_static(expr::Expr) if is_typed_expr(expr) - @test isleaftype(expr.typ) + @test isconcrete(expr.typ) end for a in expr.args test_inferred_static(a) @@ -453,10 +453,10 @@ function test_inferred_static(expr::Expr) end function test_inferred_static(arrow::Pair) code, rt = arrow - @test isleaftype(rt) + @test isconcrete(rt) @test code.inferred - @test all(x->isleaftype(x), code.slottypes) - @test all(x->isleaftype(x), code.ssavaluetypes) + @test all(x->isconcrete(x), code.slottypes) + @test all(x->isconcrete(x), code.ssavaluetypes) for e in code.code test_inferred_static(e) end diff --git a/test/reflection.jl b/test/reflection.jl index 40c06c87306db..c1b096859127a 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -29,7 +29,7 @@ end function test_code_reflections(tester, freflect) test_code_reflection(freflect, ismatch, Tuple{Regex, AbstractString}, tester) # abstract type - test_code_reflection(freflect, +, Tuple{Int, Int}, tester) # leaftype signature + test_code_reflection(freflect, +, Tuple{Int, Int}, tester) # concrete type signature test_code_reflection(freflect, +, Tuple{Array{Float32}, Array{Float32}}, tester) # incomplete types test_code_reflection(freflect, Module, Tuple{}, tester) # Module() constructor (transforms to call) @@ -133,11 +133,11 @@ end @test isbits(Tuple{Vararg{Any, 0}}) # issue #16670 -@test isleaftype(Tuple{Int, Vararg{Int, 2}}) -@test !isleaftype(Tuple{Integer, Vararg{Int, 2}}) -@test !isleaftype(Tuple{Int, Vararg{Int}}) -@test isleaftype(Type{Tuple{Integer, Vararg{Int}}}) -@test isleaftype(Type{Vector}) +@test isconcrete(Tuple{Int, Vararg{Int, 2}}) +@test !isconcrete(Tuple{Integer, Vararg{Int, 2}}) +@test !isconcrete(Tuple{Int, Vararg{Int}}) +@test isconcrete(Type{Tuple{Integer, Vararg{Int}}}) +@test isconcrete(Type{Vector}) # issue #10165 i10165(::Type) = 0 From 471791d81bac585dac5d10cd1ef75cbc93a6f52e Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Wed, 22 Feb 2017 10:07:16 +0100 Subject: [PATCH 2/3] Add missing closing triple backticks in isconcrete() docstring --- base/reflection.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/base/reflection.jl b/base/reflection.jl index 51c7450da6978..c0ce88531a2c8 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -251,6 +251,7 @@ true julia> isconcrete(Vector{Complex{Float32}}) true +``` """ isconcrete(t::ANY) = (@_pure_meta; isa(t, DataType) && t.isconcrete) From 38134218d37579ae4623051832a55feab5d1092a Mon Sep 17 00:00:00 2001 From: Tony Kelman Date: Thu, 3 Aug 2017 21:24:04 -0700 Subject: [PATCH 3/3] fix the at-deprecate call --- base/deprecated.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/deprecated.jl b/base/deprecated.jl index 1be1ab7f3cdf2..cacf62a9ccaec 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1595,7 +1595,7 @@ end # issue #6466 # `write` on non-isbits arrays is deprecated in io.jl. -@deprecate isconcrete isconcrete +@deprecate isleaftype isconcrete # PR #22925 # also uncomment constructor tests in test/linalg/bidiag.jl