Skip to content

Commit

Permalink
add missing innervars handling to merge_env (#47877)
Browse files Browse the repository at this point in the history
Otherwise, we would write NULL here immediately when handling
intersect_all, and may fail to restore this array correctly.
  • Loading branch information
vtjnash authored Dec 20, 2022
1 parent 61afe7b commit 70c1e45
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 17 deletions.
10 changes: 9 additions & 1 deletion src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -3217,14 +3217,22 @@ static int merge_env(jl_stenv_t *e, jl_value_t **root, jl_savedenv_t *se, int co
int n = 0;
jl_varbinding_t *v = e->vars;
jl_value_t *b1 = NULL, *b2 = NULL;
JL_GC_PUSH2(&b1, &b2);
JL_GC_PUSH2(&b1, &b2); // clang-sagc does not understand that *root is rooted already
while (v != NULL) {
b1 = jl_svecref(*root, n);
b2 = v->lb;
jl_svecset(*root, n, simple_meet(b1, b2));
b1 = jl_svecref(*root, n+1);
b2 = v->ub;
jl_svecset(*root, n+1, simple_join(b1, b2));
b1 = jl_svecref(*root, n+2);
b2 = (jl_value_t*)v->innervars;
if (b2) {
if (b1)
jl_array_ptr_1d_append((jl_array_t*)b2, (jl_array_t*)b1);
else
jl_svecset(*root, n+2, b2);
}
n = n + 3;
v = v->prev;
}
Expand Down
110 changes: 94 additions & 16 deletions test/subtype.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1181,51 +1181,121 @@ ftwoparams(::TwoParams{<:Real,<:Real}) = 3
# a bunch of cases found by fuzzing
let a = Tuple{Float64,T7} where T7,
b = Tuple{S5,Tuple{S5}} where S5
@test typeintersect(a, b) <: b
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test I1 <: a
@test I2 <: a
@test I1 <: b
@test I2 <: b
end
let a = Tuple{T1,T1} where T1,
b = Tuple{Val{S2},S6} where S2 where S6
@test typeintersect(a, b) == typeintersect(b, a)
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test I1 <: a
@test I2 <: a
@test I1 <: b
@test I2 <: b
end
let a = Val{Tuple{T1,T1}} where T1,
b = Val{Tuple{Val{S2},S6}} where S2 where S6
@testintersect(a, b, Val{Tuple{Val{T},Val{T}}} where T)
end
let a = Tuple{Float64,T3,T4} where T4 where T3,
b = Tuple{S2,Tuple{S3},S3} where S2 where S3
@test typeintersect(a, b) == typeintersect(b, a)
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test I1 <: a
@test I2 <: a
@test_broken I1 <: b
@test_broken I2 <: b
end
let a = Tuple{T1,Tuple{T1}} where T1,
b = Tuple{Float64,S3} where S3
@test typeintersect(a, b) <: a
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test I1 <: a
@test I2 <: a
@test I1 <: b
@test I2 <: b
end
let a = Tuple{5,T4,T5} where T4 where T5,
b = Tuple{S2,S3,Tuple{S3}} where S2 where S3
@test typeintersect(a, b) == typeintersect(b, a)
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test I1 <: a
@test I2 <: a
@test_broken I1 <: b
@test_broken I2 <: b
end
let a = Tuple{T2,Tuple{T4,T2}} where T4 where T2,
b = Tuple{Float64,Tuple{Tuple{S3},S3}} where S3
@test typeintersect(a, b) <: b
end
let a = Tuple{Tuple{T2,4},T6} where T2 where T6,
b = Tuple{Tuple{S2,S3},Tuple{S2}} where S2 where S3
@test typeintersect(a, b) == typeintersect(b, a)
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test I1 <: a
@test I2 <: a
@test_broken I1 <: b
@test_broken I2 <: b
end
let a = Tuple{T3,Int64,Tuple{T3}} where T3,
b = Tuple{S3,S3,S4} where S4 where S3
@test_broken typeintersect(a, b) <: a
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test_broken I1 <: a
@test I2 <: a
@test I1 <: b
@test I2 <: b
end
let a = Tuple{T1,Val{T2},T2} where T2 where T1,
b = Tuple{Float64,S1,S2} where S2 where S1
@test typeintersect(a, b) == typeintersect(b, a)
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test_broken I1 <: a
@test_broken I2 <: a
@test I1 <: b
@test I2 <: b
end
let a = Tuple{T1,Val{T2},T2} where T2 where T1,
b = Tuple{Float64,S1,S2} where S2 where S1
@test_broken typeintersect(a, b) <: a
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test_broken I1 <: a
@test_broken I2 <: a
@test I1 <: b
@test I2 <: b
end
let a = Tuple{Float64,T1} where T1,
b = Tuple{S1,Tuple{S1}} where S1
@test typeintersect(a, b) <: b
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test I1 <: I2
@test I2 <: I1
@test I1 <: a
@test I2 <: a
@test I1 <: b
@test I2 <: b
end
let a = Tuple{Val{T1},T2,T2} where T2 where T1,
b = Tuple{Val{Tuple{S2}},S3,Float64} where S2 where S3
Expand All @@ -1234,12 +1304,20 @@ end
let a = Tuple{T1,T2,T2} where T1 where T2,
b = Tuple{Val{S2},S2,Float64} where S2,
x = Tuple{Val{Float64},Float64,Float64}
@test x <: typeintersect(a, b)
end
let a = Val{Tuple{T1,Val{T2},Val{Int64},Tuple{Tuple{T3,5,Float64},T4,T2,T5}}} where T1 where T5 where T4 where T3 where T2,
b = Val{Tuple{Tuple{S1,5,Float64},Val{S2},S3,Tuple{Tuple{Val{Float64},5,Float64},2,Float64,S4}}} where S2 where S3 where S1 where S4
@test_skip typeintersect(b, a)
end
I1 = typeintersect(a, b)
I2 = typeintersect(b, a)
@test x <: I1
@test x <: I2
@test I1 <: I2
@test I2 <: I1
@test I1 <: a
@test I2 <: a
@test_broken I1 <: b
@test_broken I2 <: b
end
@testintersect(Val{Tuple{T1,Val{T2},Val{Int64},Tuple{Tuple{T3,5,Float64},T4,T2,T5}}} where T1 where T5 where T4 where T3 where T2,
Val{Tuple{Tuple{S1,5,Float64},Val{S2},S3,Tuple{Tuple{Val{Float64},5,Float64},2,Float64,S4}}} where S2 where S3 where S1 where S4,
Val{Tuple{Tuple{S1, 5, Float64}, Val{Float64}, Val{Int64}, Tuple{Tuple{Val{Float64}, 5, Float64}, 2, Float64, T5}}} where {T5, S1})

# issue #20992
abstract type A20992{T,D,d} end
Expand Down

0 comments on commit 70c1e45

Please sign in to comment.