Skip to content

Commit

Permalink
fixup algorithm
Browse files Browse the repository at this point in the history
Had an issue where (S<:T<:S with innervar N) would add the (where N) to
each S instead of the whole expression, resulting to creation of
(Val{. where N}) instead of (Val{.} where N) later.
  • Loading branch information
vtjnash committed Apr 7, 2023
1 parent 38c0563 commit 68f1c50
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 51 deletions.
36 changes: 15 additions & 21 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -2908,18 +2908,10 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind
// of the type walk that now may have incomplete bounds: finish those now too
jl_varbinding_t *btemp = e->vars;
while (btemp != NULL) {
//if (btemp->depth0 == vb->depth0 && (jl_has_typevar(btemp->lb, var) || jl_has_typevar(btemp->ub, var))) {
// if (!jl_has_typevar(vb->lb, var) && !jl_has_typevar(vb->ub, var)) {
// if (btemp->innervars == NULL)
// btemp->innervars = jl_alloc_array_1d(jl_array_any_type, 0);
// jl_array_ptr_1d_push(btemp->innervars, (jl_value_t*)var);
// }
//}
if (btemp->depth0 == vb->depth0) {
if (jl_has_typevar(btemp->lb, var))
btemp->lb = jl_type_unionall((jl_tvar_t*)var, btemp->lb);
if (jl_has_typevar(btemp->ub, var))
btemp->ub = jl_type_unionall((jl_tvar_t*)var, btemp->ub);
if (btemp->depth0 == vb->depth0 && (jl_has_typevar(btemp->lb, var) || jl_has_typevar(btemp->ub, var))) {
if (btemp->innervars == NULL)
btemp->innervars = jl_alloc_array_1d(jl_array_any_type, 0);
jl_array_ptr_1d_push(btemp->innervars, (jl_value_t*)var);
}
btemp = btemp->prev;
}
Expand Down Expand Up @@ -3321,15 +3313,17 @@ static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) JL_NOT

static int has_typevar_via_env(jl_value_t *x, jl_tvar_t *t, jl_stenv_t *e)
{
jl_varbinding_t *temp = e->vars;
while (temp != NULL) {
if (temp->var == t)
break;
if (temp->lb == temp->ub &&
temp->lb == (jl_value_t *)t &&
temp->offset == 0 && jl_has_typevar(x, temp->var))
return 1;
temp = temp->prev;
if (e->Loffset == 0) {
jl_varbinding_t *temp = e->vars;
while (temp != NULL) {
if (temp->var == t)
break;
if (temp->lb == temp->ub &&
temp->lb == (jl_value_t *)t &&
jl_has_typevar(x, temp->var))
return 1;
temp = temp->prev;
}
}
return jl_has_typevar(x, t);
}
Expand Down
8 changes: 4 additions & 4 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ for (T, c) in (
(Core.TypeMapEntry, [:sig, :simplesig, :guardsigs, :min_world, :max_world, :func, :isleafsig, :issimplesig, :va]),
(Core.TypeMapLevel, []),
(Core.TypeName, [:name, :module, :names, :atomicfields, :constfields, :wrapper, :mt, :hash, :n_uninitialized, :flags]),
(DataType, [:name, :super, :parameters, :instance, :hash]),
(DataType, [:name, :super, :parameters, :freevars, :instance, :hash]),
(TypeVar, [:name, :ub, :lb]),
)
@test Set((fieldname(T, i) for i in 1:fieldcount(T) if isconst(T, i))) == Set(c)
Expand Down Expand Up @@ -5877,11 +5877,11 @@ function f_unused_undefined_sp(::T...) where T
end
@test_throws UndefVarError(:T) f_unused_undefined_sp()

# note: the constant `5` here should be > DataType.ninitialized.
# note: the constant `6` here should be > DataType.ninitialized.
# This tests that there's no crash due to accessing Type.body.layout.
let f(n) = isdefined(typeof(n), 5)
let f(n) = isdefined(typeof(n), 7)
@test f(0) === false
@test isdefined(Int, 5) === false
@test isdefined(Int, 7) === false
end

# @isdefined in a loop
Expand Down
36 changes: 10 additions & 26 deletions test/subtype.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1988,27 +1988,14 @@ let A = Tuple{Type{<:Union{Number, T}}, Ref{T}} where T,
end

# issue #39698
let T = Type{T} where T<:(AbstractArray{I}) where I<:(Base.IteratorsMD.CartesianIndex),
S = Type{S} where S<:(Base.IteratorsMD.CartesianIndices{A, B} where B<:Tuple{Vararg{Any, A}} where A)
I = typeintersect(T, S)
# This intersection returns B<:Tuple{Vararg{Any,N}}, while intersection with T
# should have added a constraint for it to be B<:Tuple{Vararg{OrdinalRange{Int64,Int64},N}}
@test_broken I <: T
@test I <: S
I2 = typeintersect(S, T)
@test_broken I2 <: T
@test I2 <: S
@test I == I2
@test !Base.has_free_typevars(I)
@test !Base.has_free_typevars(I2)
end
@testintersect(Type{T} where T<:(AbstractArray{I}) where I<:(Base.IteratorsMD.CartesianIndex),
Type{S} where S<:(Base.IteratorsMD.CartesianIndices{A, B} where B<:Tuple{Vararg{Any, A}} where A),
Type{S} where {N, S<:(Base.IteratorsMD.CartesianIndices{N, B} where B<:Tuple{Vararg{Any, N}})})

# issue #39948
let A = Tuple{Array{Pair{T, JT} where JT<:Ref{T}, 1} where T, Vector},
I = typeintersect(A, Tuple{Vararg{Vector{T}}} where T)
@test I <: A
@test !Base.has_free_typevars(I)
end
@testintersect(Tuple{Array{Pair{T, JT} where JT<:Ref{T}, 1} where T, Vector},
Tuple{Vararg{Vector{T}}} where T,
Tuple{Array{Pair{T, JT} where JT<:Ref{T}, 1}, Array{Pair{T, JT} where JT<:Ref{T}, 1}} where T)

# issue #8915
struct D8915{T<:Union{Float32,Float64}}
Expand Down Expand Up @@ -2233,13 +2220,10 @@ end
Val{Tuple{Tuple{Any, Vararg{Any, N}}}} where {N})

let A = Pair{NTuple{N, Int}, Val{N}} where N,
Bs = (Pair{<:Tuple{Int, Vararg{Int}}, <:Val},
Pair{Tuple{Int, Vararg{Int,N1}}, Val{N2}} where {N1,N2})
Cerr = Pair{Tuple{Int, Vararg{Int,N}}, Val{N}} where N
for B in Bs
@testintersect(A, B, !Cerr)
@testintersect(A, B, !Union{})
end
C = Pair{Tuple{Int, Vararg{Int,N1}}, Val{N2}} where {N1,N2},
B = Pair{<:Tuple{Int, Vararg{Int}}, <:Val}
@testintersect A B C
@testintersect A C C
end

# issue #43064
Expand Down

0 comments on commit 68f1c50

Please sign in to comment.