From 5d2cf0a6381c687676cbf92a4e7bf8fab30af78e Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 30 Oct 2017 14:35:04 -0400 Subject: [PATCH] fix soundness of inferred typevar bounds from #24399 --- src/subtype.c | 4 +++- test/inference.jl | 15 +++++++++++++++ test/subtype.jl | 5 +++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/subtype.c b/src/subtype.c index 7b3f0061fb165..3bc44e33414d9 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -623,7 +623,9 @@ static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8 jl_value_t *oldval = e->envout[e->envidx]; // if we try to assign different variable values (due to checking // multiple union members), consider the value unknown. - if (!oldval || !jl_is_typevar(oldval) || !jl_is_long(val)) + if (oldval && !jl_egal(oldval, val)) + e->envout[e->envidx] = (jl_value_t*)u->var; + else e->envout[e->envidx] = fix_inferred_var_bound(u->var, val); // TODO: substitute the value (if any) of this variable into previous envout entries } diff --git a/test/inference.jl b/test/inference.jl index 0530d3012d002..eff28516302e6 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -1258,3 +1258,18 @@ let linfo = get_linfo(Base.convert, Tuple{Type{Int64}, Int32}), @test opt.min_valid === Core.Inference.min_world(opt.linfo) > 2 @test opt.nargs == 3 end + +# approximate static parameters due to unions +let T1 = Array{Float64}, T2 = Array{_1,2} where _1 + inference_test_copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a) + rt = Base.return_types(inference_test_copy, (Union{T1,T2},))[1] + @test rt >: T1 && rt >: T2 + + el(x::T) where {T} = eltype(T) + rt = Base.return_types(el, (Union{T1,Array{Float32,2}},))[1] + @test rt >: Union{Type{Float64}, Type{Float32}} + + g(x::Ref{T}) where {T} = T + rt = Base.return_types(g, (Union{Ref{Array{Float64}}, Ref{Array{Float32}}},))[1] + @test rt >: Union{Type{Array{Float64}}, Type{Array{Float32}}} +end diff --git a/test/subtype.jl b/test/subtype.jl index 10f7e4667ad5e..d740f68835075 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1229,3 +1229,8 @@ struct A23764{T, N, S} <: AbstractArray{Union{T, S}, N}; end struct A23764_2{T, N, S} <: AbstractArray{Union{Ref{T}, S}, N}; end @test Tuple{A23764_2{T, 1, Void} where T} <: Tuple{AbstractArray{T,N}} where {T,N} @test Tuple{A23764_2{T, 1, Void} where T} <: Tuple{AbstractArray{T,N} where {T,N}} + +# PR #24399 +let (t, e) = intersection_env(Tuple{Union{Int,Int8}}, Tuple{T} where T) + @test e[1] isa TypeVar +end