Skip to content

Commit 682e6b1

Browse files
committed
Add constraint check on b in intersect_typevar
Fixes #11136
1 parent 9e8badc commit 682e6b1

File tree

2 files changed

+73
-48
lines changed

2 files changed

+73
-48
lines changed

src/jltypes.c

+12
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,18 @@ static jl_value_t *intersect_typevar(jl_tvar_t *a, jl_value_t *b,
739739
break;
740740
}
741741
}
742+
if (jl_is_typevar(b)) {
743+
for(i=0; i < penv->n; i+=2) {
744+
if (penv->data[i] == b && !jl_is_typevar(penv->data[i+1])) {
745+
jl_value_t *ti = jl_type_intersection((jl_value_t*)a, penv->data[i+1]);
746+
if (ti == (jl_value_t*)jl_bottom_type) {
747+
JL_GC_POP();
748+
return ti;
749+
}
750+
break;
751+
}
752+
}
753+
}
742754
extend((jl_value_t*)a, b, penv);
743755
if (jl_is_typevar(b)) {
744756
JL_GC_POP();

test/core.jl

+61-48
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
const Bottom = Union()
66

7+
function testintersect(a, b, result, cmp=is)
8+
@test cmp(typeintersect(a, b), result)
9+
@test cmp(typeintersect(b, a), result)
10+
end
11+
isnot(x,y) = !is(x,y)
12+
713
# basic type relationships
814
@test Int8 <: Integer
915
@test Int32 <: Integer
@@ -23,96 +29,96 @@ const Bottom = Union()
2329
@test Array{Int8,1} <: Array{Int8,1}
2430
@test !(Type{Bottom} <: Type{Int32})
2531
@test !(Vector{Float64} <: Vector{Union(Float64,Float32)})
26-
@test is(Bottom, typeintersect(Vector{Float64},Vector{Union(Float64,Float32)}))
32+
testintersect(Vector{Float64}, Vector{Union(Float64,Float32)}, Bottom)
2733

2834
@test !isa(Array,Type{Any})
2935
@test Type{Complex} <: DataType
3036
@test isa(Complex,Type{Complex})
3137
@test !(Type{Ptr{Bottom}} <: Type{Ptr})
3238
@test !(Type{Rational{Int}} <: Type{Rational})
3339
let T = TypeVar(:T,true)
34-
@test !is(Bottom, typeintersect(Array{Bottom},AbstractArray{T}))
35-
@test is(Bottom, typeintersect(Tuple{Type{Ptr{UInt8}},Ptr{Bottom}},
36-
Tuple{Type{Ptr{T}},Ptr{T}}))
40+
testintersect(Array{Bottom},AbstractArray{T}, Bottom, isnot)
41+
testintersect(Tuple{Type{Ptr{UInt8}},Ptr{Bottom}},
42+
Tuple{Type{Ptr{T}},Ptr{T}}, Bottom)
3743
@test !(Type{T} <: TypeVar)
3844

39-
@test isequal(typeintersect(Tuple{Range{Int},Tuple{Int,Int}},Tuple{AbstractArray{T},Dims}),
45+
testintersect(Tuple{Range{Int},Tuple{Int,Int}},Tuple{AbstractArray{T},Dims},
4046
Tuple{Range{Int},Tuple{Int,Int}})
4147

42-
@test isequal(typeintersect(Tuple{T, AbstractArray{T}}, Tuple{Number, Array{Int,1}}),
48+
testintersect(Tuple{T, AbstractArray{T}}, Tuple{Number, Array{Int,1}},
4349
Tuple{Int, Array{Int,1}})
4450

45-
@test isequal(typeintersect(Tuple{T, AbstractArray{T}}, Tuple{Int, Array{Number,1}}),
51+
testintersect(Tuple{T, AbstractArray{T}}, Tuple{Int, Array{Number,1}},
4652
Tuple{Int, Array{Number,1}})
4753

48-
@test isequal(typeintersect(Tuple{T, AbstractArray{T}},Tuple{Any, Array{Number,1}}),
49-
Tuple{Number, Array{Number,1}})
50-
@test !is(Bottom, typeintersect(Tuple{Array{T}, Array{T}}, Tuple{Array, Array{Any}}))
54+
testintersect(Tuple{T, AbstractArray{T}},Tuple{Any, Array{Number,1}},
55+
Tuple{Number, Array{Number,1}}, isequal)
56+
testintersect(Tuple{Array{T}, Array{T}}, Tuple{Array, Array{Any}}, Bottom, isnot)
5157
f47{T}(x::Vector{Vector{T}}) = 0
5258
@test_throws MethodError f47(Array(Vector,0))
5359
@test f47(Array(Vector{Int},0)) == 0
54-
@test typeintersect(Tuple{T,T}, Tuple{Union(Float64,Int64),Int64}) == Tuple{Int64,Int64}
55-
@test typeintersect(Tuple{T,T}, Tuple{Int64,Union(Float64,Int64)}) == Tuple{Int64,Int64}
60+
testintersect(Tuple{T,T}, Tuple{Union(Float64,Int64),Int64}, Tuple{Int64,Int64})
61+
testintersect(Tuple{T,T}, Tuple{Int64,Union(Float64,Int64)}, Tuple{Int64,Int64})
5662

5763
TT = TypeVar(:T)
5864
S = TypeVar(:S,true); N = TypeVar(:N,true); SN = TypeVar(:S,Number,true)
59-
@test typeintersect(Type{TypeVar(:T,Array{TT,1})},Type{Array{SN,N}}) == Type{Array{SN,1}}
65+
testintersect(Type{TypeVar(:T,Array{TT,1})},Type{Array{SN,N}}, Type{Array{SN,1}})
6066
# issue #5359
61-
@test typeintersect(Tuple{Type{Array{T,1}},Array{T,1}},
62-
Tuple{Type{AbstractVector},Vector{Int}}) === Bottom
67+
testintersect(Tuple{Type{Array{T,1}},Array{T,1}},
68+
Tuple{Type{AbstractVector},Vector{Int}}, Bottom)
6369
# issue #5559
64-
@test typeintersect(Tuple{Type{Vector{Complex128}}, AbstractVector},
65-
Tuple{Type{Array{T,N}}, Array{S,N}}) == Tuple{Type{Vector{Complex128}},Vector}
66-
@test typeintersect(Tuple{Type{Vector{Complex128}}, AbstractArray},
67-
Tuple{Type{Array{T,N}}, Array{S,N}}) == Tuple{Type{Vector{Complex128}},Vector}
70+
testintersect(Tuple{Type{Vector{Complex128}}, AbstractVector},
71+
Tuple{Type{Array{T,N}}, Array{S,N}}, Tuple{Type{Vector{Complex128}},Vector}, isequal)
72+
testintersect(Tuple{Type{Vector{Complex128}}, AbstractArray},
73+
Tuple{Type{Array{T,N}}, Array{S,N}}, Tuple{Type{Vector{Complex128}},Vector}, isequal)
6874

69-
@test typeintersect(Type{Array{T}}, Type{AbstractArray{T}}) === Bottom
75+
testintersect(Type{Array{T}}, Type{AbstractArray{T}}, Bottom)
7076

71-
@test typeintersect(Type{Tuple{Bool,Vararg{Int}}}, Type{Tuple{Vararg{T}}}) === Bottom
72-
@test typeintersect(Type{Tuple{Bool,Vararg{Int}}}, Type{Tuple{T,Vararg{T}}}) === Bottom
77+
testintersect(Type{Tuple{Bool,Vararg{Int}}}, Type{Tuple{Vararg{T}}}, Bottom)
78+
testintersect(Type{Tuple{Bool,Vararg{Int}}}, Type{Tuple{T,Vararg{T}}}, Bottom)
7379

74-
@test typeintersect(Tuple{Rational{T},T}, Tuple{Rational{Integer},Int}) === Tuple{Rational{Integer},Int}
80+
testintersect(Tuple{Rational{T},T}, Tuple{Rational{Integer},Int}, Tuple{Rational{Integer},Int})
7581

76-
@test typeintersect(Pair{T,Ptr{T}}, Pair{Ptr{S},S}) === Bottom
77-
@test typeintersect(Tuple{T,Ptr{T}}, Tuple{Ptr{S},S}) === Bottom
82+
testintersect(Pair{T,Ptr{T}}, Pair{Ptr{S},S}, Bottom)
83+
testintersect(Tuple{T,Ptr{T}}, Tuple{Ptr{S},S}, Bottom)
7884
end
7985
let N = TypeVar(:N,true)
80-
@test isequal(typeintersect(Tuple{NTuple{N,Integer},NTuple{N,Integer}},
81-
Tuple{Tuple{Integer,Integer}, Tuple{Vararg{Integer}}}),
86+
testintersect(Tuple{NTuple{N,Integer},NTuple{N,Integer}},
87+
Tuple{Tuple{Integer,Integer}, Tuple{Vararg{Integer}}},
8288
Tuple{Tuple{Integer,Integer}, Tuple{Integer,Integer}})
83-
@test isequal(typeintersect(Tuple{NTuple{N,Integer},NTuple{N,Integer}},
84-
Tuple{Tuple{Vararg{Integer}}, Tuple{Integer,Integer}}),
89+
testintersect(Tuple{NTuple{N,Integer},NTuple{N,Integer}},
90+
Tuple{Tuple{Vararg{Integer}}, Tuple{Integer,Integer}},
8591
Tuple{Tuple{Integer,Integer}, Tuple{Integer,Integer}})
8692
local A = typeintersect(Tuple{NTuple{N,Any},Array{Int,N}},
8793
Tuple{Tuple{Int,Vararg{Int}},Array})
8894
local B = Tuple{Tuple{Int,Vararg{Int}},Array{Int,N}}
8995
@test A<:B && B<:A
90-
@test isequal(typeintersect(Tuple{NTuple{N,Any},Array{Int,N}},
91-
Tuple{Tuple{Int,Vararg{Int}},Array{Int,2}}),
96+
testintersect(Tuple{NTuple{N,Any},Array{Int,N}},
97+
Tuple{Tuple{Int,Vararg{Int}},Array{Int,2}},
9298
Tuple{Tuple{Int,Int}, Array{Int,2}})
9399
end
94-
@test is(Bottom, typeintersect(Type{Any},Type{Complex}))
95-
@test is(Bottom, typeintersect(Type{Any},Type{TypeVar(:T,Real)}))
100+
testintersect(Type{Any},Type{Complex}, Bottom)
101+
testintersect(Type{Any},Type{TypeVar(:T,Real)}, Bottom)
96102
@test !(Type{Array{Integer}} <: Type{AbstractArray{Integer}})
97103
@test !(Type{Array{Integer}} <: Type{Array{TypeVar(:T,Integer)}})
98-
@test is(Bottom, typeintersect(Type{Function},UnionType))
99-
@test is(Type{Int32}, typeintersect(Type{Int32},DataType))
104+
testintersect(Type{Function},UnionType,Bottom)
105+
testintersect(Type{Int32}, DataType, Type{Int32})
100106
@test !(Type <: TypeVar)
101-
@test !is(Bottom, typeintersect(DataType, Type))
102-
@test !is(Bottom, typeintersect(UnionType, Type))
103-
@test !is(Bottom, typeintersect(DataType, Type{Int}))
104-
@test !is(Bottom, typeintersect(DataType, Type{TypeVar(:T,Int)}))
105-
@test !is(Bottom, typeintersect(DataType, Type{TypeVar(:T,Integer)}))
107+
testintersect(DataType, Type, Bottom, isnot)
108+
testintersect(UnionType, Type, Bottom, isnot)
109+
testintersect(DataType, Type{Int}, Bottom, isnot)
110+
testintersect(DataType, Type{TypeVar(:T,Int)}, Bottom, isnot)
111+
testintersect(DataType, Type{TypeVar(:T,Integer)}, Bottom, isnot)
106112

107-
@test typeintersect(Tuple{Vararg{Int}}, Tuple{Vararg{Bool}}) === Tuple{}
108-
@test typeintersect(Type{Tuple{Vararg{Int}}}, Type{Tuple{Vararg{Bool}}}) === Bottom
109-
@test typeintersect(Tuple{Bool,Vararg{Int}}, Tuple{Vararg{Bool}}) === Tuple{Bool,}
113+
testintersect(Tuple{Vararg{Int}}, Tuple{Vararg{Bool}}, Tuple{})
114+
testintersect(Type{Tuple{Vararg{Int}}}, Type{Tuple{Vararg{Bool}}}, Bottom)
115+
testintersect(Tuple{Bool,Vararg{Int}}, Tuple{Vararg{Bool}}, Tuple{Bool,})
110116

111117
let T = TypeVar(:T,Union(Float32,Float64))
112-
@test typeintersect(AbstractArray, Matrix{T}) == Matrix{T}
118+
testintersect(AbstractArray, Matrix{T}, Matrix{T})
113119
end
114120
let T = TypeVar(:T,Union(Float32,Float64),true)
115-
@test typeintersect(AbstractArray, Matrix{T}) == Matrix{T}
121+
testintersect(AbstractArray, Matrix{T}, Matrix{T})
116122
end
117123

118124
@test isa(Int,Type{TypeVar(:T,Number)})
@@ -146,7 +152,7 @@ end
146152

147153
# issue #2997
148154
let T = TypeVar(:T,Union(Float64,Array{Float64,1}),true)
149-
@test typeintersect(T,Real) === Float64
155+
testintersect(T,Real,Float64)
150156
end
151157

152158
# join
@@ -1361,7 +1367,7 @@ abstract IT4805{N, T}
13611367
let
13621368
T = TypeVar(:T,Int,true)
13631369
N = TypeVar(:N,true)
1364-
@test typeintersect(Type{IT4805{1,T}}, Type{TypeVar(:_,IT4805{N,Int})}) != Bottom
1370+
testintersect(Type{IT4805{1,T}}, Type{TypeVar(:_,IT4805{N,Int})}, Bottom, isnot)
13651371
end
13661372

13671373
let
@@ -2002,7 +2008,7 @@ abstract AbstractThing{T,N}
20022008
type ConcreteThing{T<:FloatingPoint,N} <: AbstractThing{T,N}
20032009
end
20042010

2005-
@test typeintersect(AbstractThing{TypeVar(:T,true),2}, ConcreteThing) == ConcreteThing{TypeVar(:T,FloatingPoint),2}
2011+
testintersect(AbstractThing{TypeVar(:T,true),2}, ConcreteThing, ConcreteThing{TypeVar(:T,FloatingPoint),2}, isequal)
20062012

20072013
# issue #8978
20082014
module I8978
@@ -2824,3 +2830,10 @@ function f11357()
28242830
x[i...]
28252831
end
28262832
@test f11357() === 1
2833+
2834+
# issue #11136
2835+
type A11136 end
2836+
type B11136 end
2837+
let T = TypeVar(:T, true), TB = TypeVar(:T, B11136, true)
2838+
testintersect(Tuple{T, T}, Tuple{A11136, TB}, Bottom)
2839+
end

0 commit comments

Comments
 (0)