diff --git a/base/base.jl b/base/base.jl index 93b08d9cb5c0e..ba6105d8a9166 100644 --- a/base/base.jl +++ b/base/base.jl @@ -66,7 +66,7 @@ ccall(:jl_get_system_hooks, Void, ()) ==(w::WeakRef, v) = isequal(w.value, v) ==(w, v::WeakRef) = isequal(w, v.value) -function finalizer(o::ANY, f::Union(Function,Ptr)) +function finalizer(o::ANY, f::Union{Function,Ptr}) if isimmutable(o) error("objects of type ", typeof(o), " cannot be finalized") end diff --git a/base/boot.jl b/base/boot.jl index 397f20aabaea5..b95d541127e42 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -30,7 +30,7 @@ # pointerfree::Bool #end -#type UnionType <: Type +#type Union <: Type # types::Tuple #end @@ -126,7 +126,7 @@ import Core.Intrinsics.ccall export # key types Any, DataType, Vararg, ANY, NTuple, - Tuple, Type, TypeConstructor, TypeName, TypeVar, Union, UnionType, Void, + Tuple, Type, TypeConstructor, TypeName, TypeVar, Union, Void, SimpleVector, AbstractArray, DenseArray, # special objects Box, Function, IntrinsicFunction, LambdaStaticData, Method, MethodTable, @@ -249,7 +249,7 @@ immutable UTF8String <: AbstractString data::Array{UInt8,1} end -typealias ByteString Union(ASCIIString,UTF8String) +typealias ByteString Union{ASCIIString,UTF8String} include(fname::ByteString) = ccall(:jl_load_, Any, (Any,), fname) @@ -262,14 +262,14 @@ type WeakRef end TypeVar(n::Symbol) = - ccall(:jl_new_typevar, Any, (Any, Any, Any), n, Union(), Any)::TypeVar + ccall(:jl_new_typevar, Any, (Any, Any, Any), n, Union{}, Any)::TypeVar TypeVar(n::Symbol, ub::ANY) = (isa(ub,Bool) ? - ccall(:jl_new_typevar_, Any, (Any, Any, Any, Any), n, Union(), Any, ub)::TypeVar : - ccall(:jl_new_typevar, Any, (Any, Any, Any), n, Union(), ub::Type)::TypeVar) + ccall(:jl_new_typevar_, Any, (Any, Any, Any, Any), n, Union{}, Any, ub)::TypeVar : + ccall(:jl_new_typevar, Any, (Any, Any, Any), n, Union{}, ub::Type)::TypeVar) TypeVar(n::Symbol, lb::ANY, ub::ANY) = (isa(ub,Bool) ? - ccall(:jl_new_typevar_, Any, (Any, Any, Any, Any), n, Union(), lb::Type, ub)::TypeVar : + ccall(:jl_new_typevar_, Any, (Any, Any, Any, Any), n, Union{}, lb::Type, ub)::TypeVar : ccall(:jl_new_typevar, Any, (Any, Any, Any), n, lb::Type, ub::Type)::TypeVar) TypeVar(n::Symbol, lb::ANY, ub::ANY, b::Bool) = ccall(:jl_new_typevar_, Any, (Any, Any, Any, Any), n, lb::Type, ub::Type, b)::TypeVar diff --git a/base/deepcopy.jl b/base/deepcopy.jl index 0f7fb648773bc..96b1a1ccf2ce4 100644 --- a/base/deepcopy.jl +++ b/base/deepcopy.jl @@ -8,7 +8,7 @@ deepcopy(x) = deepcopy_internal(x, ObjectIdDict()) deepcopy_internal(x::Union(Symbol,LambdaStaticData,TopNode,QuoteNode, - DataType,UnionType,Task), + DataType,Union,Task), stackdict::ObjectIdDict) = x deepcopy_internal(x::Tuple, stackdict::ObjectIdDict) = ntuple(i->deepcopy_internal(x[i], stackdict), length(x)) diff --git a/base/deprecated.jl b/base/deprecated.jl index 1daa2fe2a91f4..b3dd9b98049a2 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -527,3 +527,6 @@ end function start_timer(t, d, r) error("start_timer is deprecated. Use Timer(callback, delay, repeat) instead.") end + +const UnionType = Union +export UnionType diff --git a/base/essentials.jl b/base/essentials.jl index ade50ed982d28..ec23969930b86 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -2,9 +2,11 @@ abstract IO -typealias Callable Union(Function,DataType) +typealias Callable Union{Function,DataType} -const Bottom = Union() +const Bottom = Union{} + +call(::Type{Union}, args...) = Union{args...} # The real @inline macro is not available until after array.jl, so this # internal macro splices the meta Expr directly into the function body. diff --git a/base/inference.jl b/base/inference.jl index ceace446355a2..c36f780e5a261 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -36,7 +36,7 @@ type CallStack recurred::Bool cycleid::Int result - prev::Union(EmptyCallStack,CallStack) + prev::Union{EmptyCallStack,CallStack} sv::StaticVarInfo CallStack(ast, mod, types::ANY, prev) = new(ast, mod, types, false, 0, Bottom, prev) @@ -145,7 +145,7 @@ add_tfunc(getfield(Core.Intrinsics,:ccall), 3, IInf, if isa(t,DataType) && is((t::DataType).name,Ref.name) t = t.parameters[1] if is(t,Any) - return Union() # a return type of Box{Any} is invalid + return Union{} # a return type of Box{Any} is invalid end return t end @@ -158,19 +158,13 @@ add_tfunc(eval(Core.Intrinsics,:cglobal), 1, 2, isType(t[1]) ? Ptr{t[1].parameters[1]} : Ptr)) add_tfunc(eval(Core.Intrinsics,:select_value), 3, 3, # TODO: return Bottom if cnd is definitely not a Bool - (cnd, x, y)->Union(x,y)) + (cnd, x, y)->Union{x,y}) add_tfunc(is, 2, 2, cmp_tfunc) add_tfunc(issubtype, 2, 2, cmp_tfunc) add_tfunc(isa, 2, 2, cmp_tfunc) add_tfunc(isdefined, 1, IInf, (args...)->Bool) add_tfunc(Core.sizeof, 1, 1, x->Int) add_tfunc(nfields, 1, 1, x->Int) -add_tfunc(Union, 0, IInf, - (args...)->(if all(isType,args) - Type{Union(map(t->t.parameters[1],args)...)} - else - Type - end)) add_tfunc(_expr, 1, IInf, (args...)->Expr) add_tfunc(method_exists, 2, 2, cmp_tfunc) add_tfunc(applicable, 1, IInf, (f, args...)->Bool) @@ -196,8 +190,8 @@ const typeof_tfunc = function (t) else Type{TypeVar(:_,t)} end - elseif isa(t,UnionType) - Union(map(typeof_tfunc, t.types)...) + elseif isa(t,Union) + Union{map(typeof_tfunc, t.types)...} elseif isa(t,TypeVar) Type{t} else @@ -215,12 +209,12 @@ function limit_type_depth(t::ANY, d::Int, cov::Bool, vars) return t end inexact = !cov && d > MAX_TYPE_DEPTH - if isa(t,UnionType) + if isa(t,Union) t === Bottom && return t if d > MAX_TYPE_DEPTH R = Any else - R = Union(map(x->limit_type_depth(x, d+1, cov, vars), t.types)...) + R = Union{map(x->limit_type_depth(x, d+1, cov, vars), t.types)...} end elseif isa(t,DataType) P = t.parameters @@ -254,7 +248,7 @@ const getfield_tfunc = function (A, s0, name) return Any, false end end - if isa(s,UnionType) + if isa(s,Union) return reduce(tmerge, Bottom, map(t->getfield_tfunc(A, t, name)[1], s.types)), false end if !isa(s,DataType) @@ -376,17 +370,30 @@ has_typevars(t::ANY) = ccall(:jl_has_typevars, Cint, (Any,), t)!=0 # TODO: handle e.g. apply_type(T, R::Union(Type{Int32},Type{Float64})) const apply_type_tfunc = function (A, args...) if !isType(args[1]) - return Type + return Any end headtype = args[1].parameters[1] - if isa(headtype,UnionType) || isa(headtype,TypeVar) + if isa(headtype,Union) || isa(headtype,TypeVar) return args[1] end + largs = length(args) + if headtype === Union + largs == 1 && return Type{Bottom} + largs == 2 && return args[2] + args = args[2:end] + if all(isType, args) + return Type{Union{map(t->t.parameters[1],args)...}} + else + return Any + end + elseif Union <: headtype + return Any + end istuple = (headtype === Tuple) uncertain = false lA = length(A) tparams = svec() - for i=2:max(lA,length(args)) + for i=2:max(lA,largs) ai = args[i] if isType(ai) aip1 = ai.parameters[1] @@ -563,10 +570,10 @@ const isconstantref = isconstantfunc const limit_tuple_depth = t->limit_tuple_depth_(t,0) const limit_tuple_depth_ = function (t,d::Int) - if isa(t,UnionType) + if isa(t,Union) # also limit within Union types. # may have to recur into other stuff in the future too. - return Union(map(x->limit_tuple_depth_(x,d+1), t.types)...) + return Union{map(x->limit_tuple_depth_(x,d+1), t.types)...} end if !(isa(t,DataType) && t.name === Tuple.name) return t @@ -1088,7 +1095,7 @@ end typealias VarTable ObjectIdDict type StateUpdate - var::Union(Symbol,GenSym) + var::Union{Symbol,GenSym} vtype state::VarTable end @@ -1130,7 +1137,7 @@ function type_too_complex(t::ANY, d) if d > MAX_TYPE_DEPTH return true end - if isa(t,UnionType) + if isa(t,Union) p = t.types elseif isa(t,DataType) p = t.parameters @@ -1158,7 +1165,7 @@ function tmerge(typea::ANY, typeb::ANY) end return Tuple end - u = Union(typea, typeb) + u = Union{typea, typeb} if length(u.types) > MAX_TYPEUNION_LEN || type_too_complex(u, 0) # don't let type unions get too big # TODO: something smarter, like a common supertype @@ -1169,7 +1176,7 @@ end issubstate(a::VarState,b::VarState) = (a.typ <: b.typ && a.undef <= b.undef) -function smerge(sa::Union(NotFound,VarState), sb::Union(NotFound,VarState)) +function smerge(sa::Union{NotFound,VarState}, sb::Union{NotFound,VarState}) is(sa, NF) && return sb is(sb, NF) && return sa issubstate(sa,sb) && return sb @@ -1183,7 +1190,7 @@ schanged(n::ANY, o::ANY) = is(o,NF) || (!is(n,NF) && !issubstate(n, o)) stupdate(state::Tuple{}, changes::VarTable, vars) = copy(changes) stupdate(state::Tuple{}, changes::StateUpdate, vars) = stupdate(ObjectIdDict(), changes, vars) -function stupdate(state::ObjectIdDict, changes::Union(StateUpdate,VarTable), vars) +function stupdate(state::ObjectIdDict, changes::Union{StateUpdate,VarTable}, vars) for i = 1:length(vars) v = vars[i] newtype = changes[v] @@ -1195,7 +1202,7 @@ function stupdate(state::ObjectIdDict, changes::Union(StateUpdate,VarTable), var state end -function stchanged(new::Union(StateUpdate,VarTable), old, vars) +function stchanged(new::Union{StateUpdate,VarTable}, old, vars) if is(old,()) return true end @@ -1680,7 +1687,7 @@ function typeinf_uncached(linfo::LambdaStaticData, atypes::ANY, sparams::SimpleV end for i = 1:length(gensym_types) if gensym_types[i] === NF - gensym_types[i] = Union() + gensym_types[i] = Union{} end end @@ -1883,7 +1890,7 @@ end function sym_replace(e::ANY, from1, from2, to1, to2) if isa(e,Symbol) || isa(e,GenSym) - return _sym_repl(e::Union(Symbol,GenSym), from1, from2, to1, to2, e) + return _sym_repl(e::Union{Symbol,GenSym}, from1, from2, to1, to2, e) end if isa(e,SymbolNode) e2 = _sym_repl(e.name, from1, from2, to1, to2, e) @@ -1907,7 +1914,7 @@ function sym_replace(e::ANY, from1, from2, to1, to2) if isa(e2, SymbolNode) e2 = e2.name end - e.args[1] = e2::Union(Symbol,GenSym) + e.args[1] = e2::Union{Symbol,GenSym} end e.args[2] = sym_replace(e.args[2], from1, from2, to1, to2) elseif e.head !== :line @@ -1918,7 +1925,7 @@ function sym_replace(e::ANY, from1, from2, to1, to2) return e end -function _sym_repl(s::Union(Symbol,GenSym), from1, from2, to1, to2, deflt) +function _sym_repl(s::Union{Symbol,GenSym}, from1, from2, to1, to2, deflt) for i=1:length(from1) if is(from1[i],s) return to1[i] @@ -1979,7 +1986,7 @@ function resolve_globals(e::ANY, locals, args, from, to, env1, env2) # remove_redundant_temp_vars can only handle Symbols # on the LHS of assignments, so we make sure not to put # something else there - e2 = resolve_globals(e.args[1]::Union(Symbol,GenSym), locals, args, from, to, env1, env2) + e2 = resolve_globals(e.args[1]::Union{Symbol,GenSym}, locals, args, from, to, env1, env2) if isa(e2, GlobalRef) # abort when trying to inline a function which assigns to a global # variable in a different module, since `Mod.X=V` isn't allowed @@ -1989,7 +1996,7 @@ function resolve_globals(e::ANY, locals, args, from, to, env1, env2) # resolve_globals(e.args[2], locals, args, from, to, env1, env2)) # e.typ = e2.typ else - e.args[1] = e2::Union(Symbol,GenSym) + e.args[1] = e2::Union{Symbol,GenSym} e.args[2] = resolve_globals(e.args[2], locals, args, from, to, env1, env2) end elseif !is(e.head,:line) @@ -2236,12 +2243,6 @@ function inlineable(f::ANY, e::Expr, atype::ANY, sv::StaticVarInfo, enclosing_as isleaftype(e.typ.parameters[1]) return (e.typ.parameters[1],()) end - if is(f,Union) - union = e.typ.parameters[1] - if isa(union,UnionType) && all(isleaftype, (union::UnionType).types) - return (union,()) - end - end end if isa(f,IntrinsicFunction) return NF diff --git a/base/operators.jl b/base/operators.jl index 541a5c231bfe6..493af62589de0 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -174,7 +174,7 @@ eltype(x) = eltype(typeof(x)) # copying immutable things copy(x::Union(Symbol,Number,AbstractString,Function,Tuple,LambdaStaticData, - TopNode,QuoteNode,DataType,UnionType)) = x + TopNode,QuoteNode,DataType,Union)) = x # function pipelining |>(x, f::Callable) = f(x) diff --git a/base/promotion.jl b/base/promotion.jl index 1ffcf73a55506..b5d7e5ce930ee 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -19,9 +19,9 @@ function typejoin(a::ANY, b::ANY) if isa(b,TypeVar) return typejoin(a, b.ub) end - if isa(a,UnionType) || isa(b,UnionType) - u = Union(a, b) - if !isa(u,UnionType) + if isa(a,Union) || isa(b,Union) + u = Union{a, b} + if !isa(u,Union) return u end return reduce(typejoin, Bottom, u.types) diff --git a/base/reducedim.jl b/base/reducedim.jl index 1e5a11cfec8cd..886eeb69f94d3 100644 --- a/base/reducedim.jl +++ b/base/reducedim.jl @@ -92,7 +92,7 @@ reducedim_initarray0{T}(A::AbstractArray, region, v0::T) = reducedim_initarray0( # # The current scheme is basically following Steven G. Johnson's original implementation # -promote_union(T::UnionType) = promote_type(T.types...) +promote_union(T::Union) = promote_type(T.types...) promote_union(T) = T function reducedim_init{S}(f, op::AddFun, A::AbstractArray{S}, region) T = promote_union(S) diff --git a/base/reflection.jl b/base/reflection.jl index 5bab76809afea..0a1dd17bdccaa 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -143,8 +143,8 @@ function _methods(f::ANY,t::Array,i,lim::Integer,matching::Array{Any,1}) append!(matching, new::Array{Any,1}) else ti = t[i] - if isa(ti, UnionType) - for ty in (ti::UnionType).types + if isa(ti, Union) + for ty in (ti::Union).types t[i] = ty if _methods(f,t,i-1,lim,matching) === false t[i] = ty diff --git a/base/serialize.jl b/base/serialize.jl index 1cc7695dac4de..0b9837536a618 100644 --- a/base/serialize.jl +++ b/base/serialize.jl @@ -13,7 +13,7 @@ export serialize, deserialize const TAGS = Any[ Symbol, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128, Float32, Float64, Char, Ptr, - DataType, UnionType, Function, + DataType, Union, Function, Tuple, Array, Expr, #LongSymbol, LongTuple, LongExpr, Symbol, Tuple, Expr, # dummy entries, intentionally shadowed by earlier ones @@ -613,9 +613,9 @@ function deserialize_expr(s::SerializationState, len) e end -function deserialize(s::SerializationState, ::Type{UnionType}) +function deserialize(s::SerializationState, ::Type{Union}) types = deserialize(s) - Union(types...) + Union{types...} end function deserialize_datatype(s::SerializationState) diff --git a/base/show.jl b/base/show.jl index c9c233414c17b..8500192c03a65 100644 --- a/base/show.jl +++ b/base/show.jl @@ -67,9 +67,9 @@ function show(io::IO, x::IntrinsicFunction) print(io, "(intrinsic function #", box(Int32,unbox(IntrinsicFunction,x)), ")") end -function show(io::IO, x::UnionType) +function show(io::IO, x::Union) print(io, "Union") - show_delim_array(io, x.types, '(', ',', ')', false) + show_delim_array(io, x.types, '{', ',', '}', false) end show(io::IO, x::TypeConstructor) = show(io, x.body) @@ -812,7 +812,7 @@ xdump(fn::Function, io::IO, x::Array, n::Int, indent) = show(io, x); println(io)) # Types -xdump(fn::Function, io::IO, x::UnionType, n::Int, indent) = println(io, x) +xdump(fn::Function, io::IO, x::Union, n::Int, indent) = println(io, x) function xdump(fn::Function, io::IO, x::DataType, n::Int, indent) println(io, x, "::", typeof(x), " ", " <: ", super(x)) fields = fieldnames(x) @@ -857,7 +857,7 @@ function dumptype(io::IO, x, n::Int, indent) length(t.parameters) > 0 ? "{$targs}" : "", " = ", t) end - elseif isa(t, UnionType) + elseif isa(t, Union) if any(tt -> string(x.name) == typargs(tt), t.types) println(io, indent, " ", s, " = ", t) end diff --git a/examples/juliatypes.jl b/examples/juliatypes.jl index 631775baceb90..43073a7627d9e 100644 --- a/examples/juliatypes.jl +++ b/examples/juliatypes.jl @@ -449,8 +449,8 @@ xlate(t) = xlate(t, ObjectIdDict()) xlate(t, env) = t -function xlate(t::UnionType, env) - if t === Union() +function xlate(t::Union, env) + if t === Union{} return BottomT end UnionT(map(x->xlate(x,env), t.types)...) diff --git a/examples/typetree.jl b/examples/typetree.jl index 1a19118521e5d..91992ec876e6f 100644 --- a/examples/typetree.jl +++ b/examples/typetree.jl @@ -28,17 +28,17 @@ function add_ttnode(subtypes::Dict{String, TTNode}, sname::String, t::Type) end # Get a string name for the type -typ_name(t::UnionType) = string(t) +typ_name(t::Union) = string(t) typ_name(t::TypeConstructor) = string(t) typ_name(t) = string(t.name) # Store a type and its type hierarchy chain # Recurse till we reach the top level type -function store_type(sname::String, t::UnionType) - suptype = UnionType +function store_type(sname::String, t::Union) + suptype = Union tnode = TTNode(sname, t) - # store unions under UnionType type + # store unions under Union type subtypes = store_type(typ_name(suptype), suptype) add_ttnode(subtypes, sname, tnode) diff --git a/src/alloc.c b/src/alloc.c index 856d21dc6a979..6db4157e04198 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -651,15 +651,6 @@ jl_datatype_t *jl_new_bitstype(jl_value_t *name, jl_datatype_t *super, return bt; } -jl_uniontype_t *jl_new_uniontype(jl_svec_t *types) -{ - jl_uniontype_t *t = (jl_uniontype_t*)newobj((jl_value_t*)jl_uniontype_type,NWORDS(sizeof(jl_uniontype_t))); - // don't make unions of 1 type; Union(T)==T - assert(jl_svec_len(types) != 1); - t->types = types; - return t; -} - // type constructor ----------------------------------------------------------- jl_typector_t *jl_new_type_ctor(jl_svec_t *params, jl_value_t *body) diff --git a/src/builtin_proto.h b/src/builtin_proto.h index b7dab952dac32..e4bb2187ff9c9 100644 --- a/src/builtin_proto.h +++ b/src/builtin_proto.h @@ -31,7 +31,6 @@ JL_CALLABLE(jl_f_arrayset); JL_CALLABLE(jl_f_arraysize); JL_CALLABLE(jl_f_instantiate_type); JL_CALLABLE(jl_f_typevar); -JL_CALLABLE(jl_f_union); JL_CALLABLE(jl_f_methodexists); JL_CALLABLE(jl_f_applicable); JL_CALLABLE(jl_f_invoke); diff --git a/src/builtins.c b/src/builtins.c index 28179840ff7a3..499837ba176de 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -967,10 +967,16 @@ JL_CALLABLE(jl_trampoline) JL_CALLABLE(jl_f_instantiate_type) { JL_NARGSV(instantiate_type, 1); - if (!jl_is_datatype(args[0])) + if (args[0] == (jl_value_t*)jl_uniontype_type) { + size_t i; + for(i=1; i < nargs; i++) { + if (!jl_is_type(args[i]) && !jl_is_typevar(args[i])) + jl_error("invalid union type"); + } + } + else if (!jl_is_datatype(args[0])) { JL_TYPECHK(instantiate_type, typector, args[0]); - if (args[0] == (jl_value_t*)jl_anytuple_type) - return (jl_value_t*)jl_apply_tuple_type_v(&args[1], nargs-1); + } return jl_apply_type_(args[0], &args[1], nargs-1); } @@ -983,26 +989,6 @@ DLLEXPORT jl_value_t *jl_new_type_constructor(jl_svec_t *p, jl_value_t *t) return tc; } -JL_CALLABLE(jl_f_union) -{ - if (nargs == 0) return (jl_value_t*)jl_bottom_type; - if (nargs == 1) return args[0]; - size_t i; - jl_svec_t *argt = jl_alloc_svec_uninit(nargs); - for(i=0; i < nargs; i++) { - if (!jl_is_type(args[i]) && !jl_is_typevar(args[i])) { - jl_error("invalid union type"); - } - else { - jl_svecset(argt, i, args[i]); - } - } - JL_GC_PUSH1(&argt); - jl_value_t *u = jl_type_union(argt); - JL_GC_POP(); - return u; -} - // generic function reflection ------------------------------------------------ static void jl_check_type_tuple(jl_value_t *t, jl_sym_t *name, const char *ctx) @@ -1178,7 +1164,6 @@ void jl_init_primitives(void) add_builtin_func("throw", jl_f_throw); add_builtin_func("tuple", jl_f_tuple); add_builtin_func("svec", jl_f_svec); - add_builtin_func("Union", jl_f_union); add_builtin_func("method_exists", jl_f_methodexists); add_builtin_func("applicable", jl_f_applicable); add_builtin_func("invoke", jl_f_invoke); @@ -1211,7 +1196,7 @@ void jl_init_primitives(void) add_builtin("Vararg", (jl_value_t*)jl_vararg_type); add_builtin("Type", (jl_value_t*)jl_type_type); add_builtin("DataType", (jl_value_t*)jl_datatype_type); - add_builtin("UnionType", (jl_value_t*)jl_uniontype_type); + add_builtin("Union", (jl_value_t*)jl_uniontype_type); add_builtin("SimpleVector", (jl_value_t*)jl_simplevector_type); add_builtin("Module", (jl_value_t*)jl_module_type); @@ -1251,18 +1236,18 @@ void jl_init_primitives(void) // toys for debugging --------------------------------------------------------- -static size_t jl_show_svec(JL_STREAM *out, jl_svec_t *t, char *head) +static size_t jl_show_svec(JL_STREAM *out, jl_svec_t *t, char *head, char *opn, char *cls) { size_t i, n=0, len = jl_svec_len(t); n += jl_printf(out, "%s", head); - n += jl_printf(out, "("); + n += jl_printf(out, "%s", opn); for (i = 0; i < len; i++) { jl_value_t *v = jl_svecref(t,i); n += jl_static_show(out, v); if (i != len-1) n += jl_printf(out, ", "); } - n += jl_printf(out, ")"); + n += jl_printf(out, "%s", cls); return n; } @@ -1293,7 +1278,7 @@ size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, int depth) n += jl_static_show_x(out, (jl_value_t*)li->module, depth); if (li->specTypes) { n += jl_printf(out, "."); - n += jl_show_svec(out, li->specTypes->parameters, li->name->name); + n += jl_show_svec(out, li->specTypes->parameters, li->name->name, "(", ")"); } else { n += jl_printf(out, ".%s(?)", li->name->name); @@ -1304,7 +1289,7 @@ size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, int depth) //jl_static_show(out, !jl_is_expr(li->ast) ? jl_uncompress_ast(li, li->ast) : li->ast); } else if (jl_is_svec(v)) { - n += jl_show_svec(out, (jl_svec_t*)v, "svec"); + n += jl_show_svec(out, (jl_svec_t*)v, "svec", "(", ")"); } else if (jl_is_datatype(v)) { jl_datatype_t *dv = (jl_datatype_t*)v; @@ -1391,8 +1376,7 @@ size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, int depth) n += jl_printf(out, "\"%s\"", jl_iostr_data(v)); } else if (jl_is_uniontype(v)) { - n += jl_printf(out, "Union"); - n += jl_show_svec(out, ((jl_uniontype_t*)v)->types, ""); + n += jl_show_svec(out, ((jl_uniontype_t*)v)->types, "Union", "{", "}"); } else if (jl_is_typector(v)) { n += jl_static_show_x(out, ((jl_typector_t*)v)->body, depth); diff --git a/src/codegen.cpp b/src/codegen.cpp index 1eefa0d47f3d1..ffef3bfac18e4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5177,7 +5177,6 @@ static void init_julia_llvm_env(Module *m) builtin_func_map[jl_f_throw] = jlcall_func_to_llvm("jl_f_throw", (void*)&jl_f_throw, m); builtin_func_map[jl_f_tuple] = jlcall_func_to_llvm("jl_f_tuple", (void*)&jl_f_tuple, m); builtin_func_map[jl_f_svec] = jlcall_func_to_llvm("jl_f_svec", (void*)&jl_f_svec, m); - builtin_func_map[jl_f_union] = jlcall_func_to_llvm("jl_f_union", (void*)&jl_f_union, m); builtin_func_map[jl_f_methodexists] = jlcall_func_to_llvm("jl_f_methodexists", (void*)&jl_f_methodexists, m); builtin_func_map[jl_f_applicable] = jlcall_func_to_llvm("jl_f_applicable", (void*)&jl_f_applicable, m); builtin_func_map[jl_f_invoke] = jlcall_func_to_llvm("jl_f_invoke", (void*)&jl_f_invoke, m); diff --git a/src/dump.c b/src/dump.c index 73309f9b3485d..a5558d658d20f 100644 --- a/src/dump.c +++ b/src/dump.c @@ -62,21 +62,14 @@ static htable_t fptr_to_id; // (reverse of fptr_to_id) static jl_fptr_t id_to_fptrs[] = { NULL, NULL, - jl_f_throw, jl_f_is, - jl_f_no_function, jl_f_typeof, - jl_f_subtype, jl_f_isa, - jl_f_typeassert, jl_f_apply, - jl_f_top_eval, jl_f_isdefined, - jl_f_tuple, jl_f_svec, + jl_f_throw, jl_f_is, jl_f_no_function, jl_f_typeof, + jl_f_subtype, jl_f_isa, jl_f_typeassert, jl_f_apply, + jl_f_top_eval, jl_f_isdefined, jl_f_tuple, jl_f_svec, jl_f_get_field, jl_f_set_field, jl_f_field_type, jl_f_nfields, - jl_f_arraylen, jl_f_arrayref, - jl_f_arrayset, jl_f_arraysize, - jl_f_instantiate_type, jl_f_kwcall, - jl_trampoline, jl_f_union, - jl_f_methodexists, jl_f_applicable, - jl_f_invoke, jl_apply_generic, - jl_unprotect_stack, - jl_f_sizeof, jl_f_new_expr, + jl_f_arraylen, jl_f_arrayref, jl_f_arrayset, jl_f_arraysize, + jl_f_instantiate_type, jl_f_kwcall, jl_trampoline, + jl_f_methodexists, jl_f_applicable, jl_f_invoke, + jl_apply_generic, jl_unprotect_stack, jl_f_sizeof, jl_f_new_expr, NULL }; // pointers to non-AST-ish objects in a compressed tree diff --git a/src/jltypes.c b/src/jltypes.c index c1b7ca63ca219..a7f207cd05496 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -173,13 +173,14 @@ static int type_eqv_(jl_value_t *a, jl_value_t *b); // --- type union --- -static int count_union_components(jl_svec_t *types) +static int count_union_components(jl_value_t **types, size_t n) { size_t i, c=0; - for(i=0; i < jl_svec_len(types); i++) { - jl_value_t *e = jl_svecref(types,i); + for(i=0; i < n; i++) { + jl_value_t *e = types[i]; if (jl_is_uniontype(e)) { - c += count_union_components(((jl_uniontype_t*)e)->types); + jl_svec_t *ts = ((jl_uniontype_t*)e)->types; + c += count_union_components(jl_svec_data(ts), jl_svec_len(ts)); } else { c++; @@ -188,13 +189,14 @@ static int count_union_components(jl_svec_t *types) return c; } -static void flatten_type_union(jl_svec_t *types, jl_value_t **out, size_t *idx) +static void flatten_type_union(jl_value_t **types, size_t n, jl_value_t **out, size_t *idx) { size_t i; - for(i=0; i < jl_svec_len(types); i++) { - jl_value_t *e = jl_svecref(types,i); + for(i=0; i < n; i++) { + jl_value_t *e = types[i]; if (jl_is_uniontype(e)) { - flatten_type_union(((jl_uniontype_t*)e)->types, out, idx); + jl_svec_t *ts = ((jl_uniontype_t*)e)->types; + flatten_type_union(jl_svec_data(ts), jl_svec_len(ts), out, idx); } else { out[*idx] = e; @@ -220,13 +222,13 @@ static int union_elt_morespecific(const void *a, const void *b) // type definitions. (issue #2365) int inside_typedef = 0; -jl_svec_t *jl_compute_type_union(jl_svec_t *types) +static jl_svec_t *jl_compute_type_union(jl_value_t **types, size_t ntypes) { - size_t n = count_union_components(types); + size_t n = count_union_components(types, ntypes); jl_value_t **temp; JL_GC_PUSHARGS(temp, n+1); size_t idx=0; - flatten_type_union(types, temp, &idx); + flatten_type_union(types, ntypes, temp, &idx); assert(idx == n); size_t i, j, ndel=0; for(i=0; i < n; i++) { @@ -263,17 +265,24 @@ jl_svec_t *jl_compute_type_union(jl_svec_t *types) return result; } -jl_value_t *jl_type_union(jl_svec_t *types) +jl_value_t *jl_type_union_v(jl_value_t **ts, size_t n) { - types = jl_compute_type_union(types); - if (jl_svec_len(types) == 1) - return jl_svecref(types, 0); - if (jl_svec_len(types) == 0) - return (jl_value_t*)jl_bottom_type; + if (n == 0) return (jl_value_t*)jl_bottom_type; + if (n == 1) return ts[0]; + jl_svec_t *types = jl_compute_type_union(ts, n); + if (jl_svec_len(types) == 0) return (jl_value_t*)jl_bottom_type; + if (jl_svec_len(types) == 1) return jl_svecref(types, 0); JL_GC_PUSH1(&types); - jl_value_t *tu = (jl_value_t*)jl_new_uniontype(types); + jl_uniontype_t *tu = (jl_uniontype_t*)newobj((jl_value_t*)jl_uniontype_type,NWORDS(sizeof(jl_uniontype_t))); + tu->types = types; + gc_wb(tu, types); JL_GC_POP(); - return tu; + return (jl_value_t*)tu; +} + +jl_value_t *jl_type_union(jl_svec_t *types) +{ + return jl_type_union_v(jl_svec_data(types), jl_svec_len(types)); } // --- type intersection --- @@ -1647,6 +1656,8 @@ jl_value_t *jl_apply_type_(jl_value_t *tc, jl_value_t **params, size_t n) { if (tc == (jl_value_t*)jl_anytuple_type) return (jl_value_t*)jl_apply_tuple_type_v(params, n); + if (tc == (jl_value_t*)jl_uniontype_type) + return (jl_value_t*)jl_type_union_v(params, n); if (n == 0) { if (jl_is_typector(tc)) return (jl_value_t*)((jl_typector_t*)tc)->body; @@ -3168,7 +3179,7 @@ void jl_init_types(void) jl_nothing = newstruct(jl_void_type); jl_void_type->instance = jl_nothing; - jl_uniontype_type = jl_new_datatype(jl_symbol("UnionType"), + jl_uniontype_type = jl_new_datatype(jl_symbol("Union"), jl_type_type, jl_emptysvec, jl_svec(1, jl_symbol("types")), jl_svec(1, jl_simplevector_type), diff --git a/src/julia.h b/src/julia.h index ef99d104f3163..0f465615938bc 100644 --- a/src/julia.h +++ b/src/julia.h @@ -907,7 +907,8 @@ DLLEXPORT int jl_has_typevars(jl_value_t *v); DLLEXPORT int jl_subtype(jl_value_t *a, jl_value_t *b, int ta); int jl_type_morespecific(jl_value_t *a, jl_value_t *b); DLLEXPORT int jl_types_equal(jl_value_t *a, jl_value_t *b); -jl_value_t *jl_type_union(jl_svec_t *types); +DLLEXPORT jl_value_t *jl_type_union(jl_svec_t *types); +jl_value_t *jl_type_union_v(jl_value_t **ts, size_t n); jl_value_t *jl_type_intersection_matching(jl_value_t *a, jl_value_t *b, jl_svec_t **penv, jl_svec_t *tvars); DLLEXPORT jl_value_t *jl_type_intersection(jl_value_t *a, jl_value_t *b); @@ -924,7 +925,6 @@ DLLEXPORT jl_tupletype_t *jl_apply_tuple_type(jl_svec_t *params); DLLEXPORT jl_tupletype_t *jl_apply_tuple_type_v(jl_value_t **p, size_t np); jl_value_t *jl_apply_type_(jl_value_t *tc, jl_value_t **params, size_t n); jl_value_t *jl_instantiate_type_with(jl_value_t *t, jl_value_t **env, size_t n); -DLLEXPORT jl_uniontype_t *jl_new_uniontype(jl_svec_t *types); jl_datatype_t *jl_new_abstracttype(jl_value_t *name, jl_datatype_t *super, jl_svec_t *parameters); DLLEXPORT jl_datatype_t *jl_new_uninitialized_datatype(size_t nfields);