diff --git a/base/reflection.jl b/base/reflection.jl index f4a5ca4c7c4b6..ebbca5c178661 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -675,12 +675,17 @@ struct type with no fields. issingletontype(@nospecialize(t)) = (@_pure_meta; isa(t, DataType) && isdefined(t, :instance)) """ - typeintersect(T, S) + typeintersect(T::Type, S::Type) Compute a type that contains the intersection of `T` and `S`. Usually this will be the smallest such type or one close to it. """ -typeintersect(@nospecialize(a), @nospecialize(b)) = (@_pure_meta; ccall(:jl_type_intersection, Any, (Any, Any), a, b)) +function typeintersect(@nospecialize(a), @nospecialize(b)) + @_pure_meta + isa(a, Type) || throw(TypeError(:typeintersect, Type, typeof(a))) + isa(b, Type) || throw(TypeError(:typeintersect, Type, typeof(b))) + return ccall(:jl_type_intersection, Any, (Any, Any), a, b) +end morespecific(@nospecialize(a), @nospecialize(b)) = ccall(:jl_type_morespecific, Cint, (Any, Any), a, b) != 0 diff --git a/src/subtype.c b/src/subtype.c index eb668645552d7..c43d307e6d421 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -1258,7 +1258,6 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param) } if (jl_is_unionall(y)) return subtype_unionall(x, (jl_unionall_t*)y, e, 1, param); - assert(!jl_is_vararg(x) && !jl_is_vararg(y)); if (jl_is_datatype(x) && jl_is_datatype(y)) { if (x == y) return 1; if (y == (jl_value_t*)jl_any_type) return 1; @@ -3107,7 +3106,6 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa } if (jl_is_unionall(y)) return intersect_unionall(x, (jl_unionall_t*)y, e, 1, param); - assert(!jl_is_vararg(x) && !jl_is_vararg(y)); if (jl_is_datatype(x) && jl_is_datatype(y)) { jl_datatype_t *xd = (jl_datatype_t*)x, *yd = (jl_datatype_t*)y; if (param < 2) { diff --git a/test/subtype.jl b/test/subtype.jl index 3eca685aee84c..1372abed70a86 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1976,3 +1976,9 @@ end @testintersect(Tuple{Type{Pair{_A, S} where S<:AbstractArray{<:_A, 2}}, Dict} where _A, Tuple{Type{Pair{_A, S} where S<:AbstractArray{<:_A, 2}} where _A, Union{Array, Pair}}, Bottom) + +# https://github.com/JuliaLang/julia/issues/44735 +@test_throws TypeError(:typeintersect, Type, Core.TypeofVararg) typeintersect(Vararg{Int}, Int) +@test_throws TypeError(:typeintersect, Type, Core.TypeofVararg) typeintersect(Int, Vararg{Int}) +@test_throws TypeError(:typeintersect, Type, Int) typeintersect(1, Int) +@test_throws TypeError(:typeintersect, Type, Int) typeintersect(Int, 1)