diff --git a/base/inference.jl b/base/inference.jl index 026f5c43a3f08..f76dfb1e973ae 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -63,6 +63,11 @@ immutable Const Const(v::ANY) = new(v) end +function rewrap(t::ANY, u::ANY) + isa(t, Const) && return t + rewrap_unionall(t, u) +end + type InferenceState sp::SimpleVector # static parameters label_counter::Int # index of the current highest label for this function @@ -149,9 +154,9 @@ type InferenceState end s_types[1][la] = VarState(Tuple, false) else - s_types[1][la] = VarState(rewrap_unionall(tuple_tfunc(limit_tuple_depth(params, - tupletype_tail(atypes, la))), - linfo.specTypes), + s_types[1][la] = VarState(rewrap(tuple_tfunc(limit_tuple_depth(params, + tupletype_tail(atypes, la))), + linfo.specTypes), false) end la -= 1 @@ -572,8 +577,8 @@ function getfield_tfunc(s00::ANY, name) end s = DataType # typeof(p1) elseif isa(s,Union) - return rewrap_unionall(tmerge(getfield_tfunc(s.a, name), getfield_tfunc(s.b, name)), - s00) + return rewrap(tmerge(getfield_tfunc(s.a, name), getfield_tfunc(s.b, name)), + s00) elseif isa(s,Const) sv = s.val if isa(name, Const) diff --git a/base/weakkeydict.jl b/base/weakkeydict.jl index cf7b89626c005..cd6128dea8d34 100644 --- a/base/weakkeydict.jl +++ b/base/weakkeydict.jl @@ -55,8 +55,7 @@ function WeakKeyDict(kv) try Base.associative_with_eltype((K, V) -> WeakKeyDict{K, V}, kv, eltype(kv)) catch e - if any(x->isempty(methods(x, (typeof(kv),))), [start, next, done]) || - !all(x->isa(x,Union{Tuple,Pair}),kv) + if !applicable(start, kv) || !all(x->isa(x,Union{Tuple,Pair}),kv) throw(ArgumentError("WeakKeyDict(kv): kv needs to be an iterator of tuples or pairs")) else rethrow(e) diff --git a/src/jltypes.c b/src/jltypes.c index 8858784830c32..eb16fa4b5ff0d 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -309,6 +309,10 @@ JL_DLLEXPORT jl_value_t *jl_type_union(jl_value_t **ts, size_t n) JL_DLLEXPORT jl_tvar_t *jl_new_typevar(jl_sym_t *name, jl_value_t *lb, jl_value_t *ub) { + if (lb != jl_bottom_type && !jl_is_type(lb) && !jl_is_typevar(lb)) + jl_type_error_rt("TypeVar", "lower bound", (jl_value_t*)jl_type_type, lb); + if (ub != (jl_value_t*)jl_any_type && !jl_is_type(ub) && !jl_is_typevar(ub)) + jl_type_error_rt("TypeVar", "upper bound", (jl_value_t*)jl_type_type, ub); jl_ptls_t ptls = jl_get_ptls_states(); jl_tvar_t *tv = (jl_tvar_t*)jl_gc_alloc(ptls, sizeof(jl_tvar_t), jl_tvar_type); tv->name = name; @@ -319,6 +323,8 @@ JL_DLLEXPORT jl_tvar_t *jl_new_typevar(jl_sym_t *name, jl_value_t *lb, jl_value_ JL_DLLEXPORT jl_value_t *jl_type_unionall(jl_tvar_t *v, jl_value_t *body) { + if (!jl_is_type(body) && !jl_is_typevar(body)) + jl_type_error_rt("UnionAll", "", (jl_value_t*)jl_type_type, body); // normalize `T where T<:S` => S if (body == (jl_value_t*)v) return v->ub; diff --git a/test/core.jl b/test/core.jl index dc74a02275633..921108360940f 100644 --- a/test/core.jl +++ b/test/core.jl @@ -10,6 +10,12 @@ f47{T}(x::Vector{Vector{T}}) = 0 @test_throws MethodError f47(Array{Vector}(0)) @test f47(Array{Vector{Int}}(0)) == 0 +# checking unionall and typevar components +@test_throws TypeError ([] where T) +@test_throws TypeError ([T] where T) +@test_throws TypeError (Array{T} where T<:[]) +@test_throws TypeError (Array{T} where T>:[]) + # issue #8652 args_morespecific(a, b) = ccall(:jl_type_morespecific, Cint, (Any,Any), a, b) != 0 let diff --git a/test/dict.jl b/test/dict.jl index a0c7a51a6eb2f..0501d9803c92b 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -443,6 +443,11 @@ d = Dict(:a=>"a") @test_throws ArgumentError Dict([1]) @test_throws ArgumentError Dict([(1,2),0]) +# test Dict constructor's argument checking (for an iterable of pairs or tuples) +# make sure other errors can propagate when the nature of the iterator is not the problem +@test_throws InexactError Dict(convert(Int,1.5) for i=1:1) +@test_throws InexactError WeakKeyDict(convert(Int,1.5) for i=1:1) + # ImmutableDict import Base.ImmutableDict let d = ImmutableDict{String, String}(),