Skip to content

Commit 8b103cf

Browse files
committed
correct precise_container_types to handle TypeConstructor correctly
1 parent e261293 commit 8b103cf

File tree

4 files changed

+29
-19
lines changed

4 files changed

+29
-19
lines changed

base/essentials.jl

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,28 @@ macro generated(f)
4141
end
4242
end
4343

44+
argtail(x, rest...) = rest
45+
tail(x::Tuple) = argtail(x...)
4446

45-
tuple_type_head(::Type{Union{}}) = throw(MethodError(tuple_type_head, (Union{},)))
46-
function tuple_type_head{T<:Tuple}(::Type{T})
47+
tuple_type_head(T::TypeConstructor) = tuple_type_head(T.body)
48+
function tuple_type_head(T::DataType)
4749
@_pure_meta
48-
T.parameters[1]
50+
T.name === Tuple.name || throw(MethodError(tuple_type_head, (T,)))
51+
return T.parameters[1]
4952
end
50-
51-
isvarargtype(t::ANY) = isa(t,DataType)&&is((t::DataType).name,Vararg.name)
52-
isvatuple(t::DataType) = (n = length(t.parameters); n > 0 && isvarargtype(t.parameters[n]))
53-
unwrapva(t::ANY) = isvarargtype(t) ? t.parameters[1] : t
54-
55-
function tuple_type_tail{T<:Tuple}(::Type{T})
53+
tuple_type_tail(T::TypeConstructor) = tuple_type_tail(T.body)
54+
function tuple_type_tail(T::DataType)
5655
@_pure_meta
56+
T.name === Tuple.name || throw(MethodError(tuple_type_tail, (T,)))
5757
if isvatuple(T) && length(T.parameters) == 1
5858
return T
5959
end
60-
Tuple{argtail(T.parameters...)...}
60+
return Tuple{argtail(T.parameters...)...}
6161
end
6262

63-
argtail(x, rest...) = rest
64-
tail(x::Tuple) = argtail(x...)
63+
isvarargtype(t::ANY) = isa(t, DataType) && is((t::DataType).name, Vararg.name)
64+
isvatuple(t::DataType) = (n = length(t.parameters); n > 0 && isvarargtype(t.parameters[n]))
65+
unwrapva(t::ANY) = isvarargtype(t) ? t.parameters[1] : t
6566

6667
convert{T<:Tuple{Any,Vararg{Any}}}(::Type{T}, x::Tuple{Any, Vararg{Any}}) =
6768
tuple(convert(tuple_type_head(T),x[1]), convert(tuple_type_tail(T), tail(x))...)

base/inference.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -873,16 +873,19 @@ function precise_container_types(args, types, vtypes::VarTable, sv)
873873
ai = args[i]
874874
ti = types[i]
875875
tti = widenconst(ti)
876-
if isa(ai,Expr) && ai.head === :call && (abstract_evals_to_constant(ai.args[1], svec, vtypes, sv) ||
877-
abstract_evals_to_constant(ai.args[1], tuple, vtypes, sv))
876+
if isa(tti, TypeConstructor)
877+
tti = tti.body
878+
end
879+
if isa(ai, Expr) && ai.head === :call && (abstract_evals_to_constant(ai.args[1], svec, vtypes, sv) ||
880+
abstract_evals_to_constant(ai.args[1], tuple, vtypes, sv))
878881
aa = ai.args
879882
result[i] = Any[ (isa(aa[j],Expr) ? aa[j].typ : abstract_eval(aa[j],vtypes,sv)) for j=2:length(aa) ]
880883
if _any(isvarargtype, result[i])
881884
return nothing
882885
end
883-
elseif isa(ti, Union)
886+
elseif isa(tti, Union)
884887
return nothing
885-
elseif ti Tuple
888+
elseif tti <: Tuple
886889
if i == n
887890
if isvatuple(tti) && length(tti.parameters) == 1
888891
result[i] = Any[Vararg{tti.parameters[1].parameters[1]}]
@@ -894,7 +897,7 @@ function precise_container_types(args, types, vtypes::VarTable, sv)
894897
else
895898
return nothing
896899
end
897-
elseif tiAbstractArray && i==n
900+
elseif tti <: AbstractArray && i == n
898901
result[i] = Any[Vararg{eltype(tti)}]
899902
else
900903
return nothing
@@ -1264,7 +1267,7 @@ function tmerge(typea::ANY, typeb::ANY)
12641267
typea, typeb = widenconst(typea), widenconst(typeb)
12651268
typea === typeb && return typea
12661269
if (typea <: Tuple) && (typeb <: Tuple)
1267-
if length(typea.parameters) == length(typeb.parameters) && !isvatuple(typea) && !isvatuple(typeb)
1270+
if isa(typea, DataType) && isa(typeb, DataType) && length(typea.parameters) == length(typeb.parameters) && !isvatuple(typea) && !isvatuple(typeb)
12681271
return typejoin(typea, typeb)
12691272
end
12701273
return Tuple

base/tuple.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ first(t::Tuple) = t[1]
4141
# eltype
4242

4343
eltype(::Type{Tuple{}}) = Bottom
44-
eltype{T,_}(::Type{NTuple{_,T}}) = T
44+
eltype{T}(::Type{Tuple{Vararg{T}}}) = T
4545

4646
# front (the converse of tail: it skips the last entry)
4747

test/inference.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,9 @@ end
252252
let g() = Int <: Real ? 1 : ""
253253
@test Base.return_types(g, Tuple{}) == [Int]
254254
end
255+
256+
typealias NInt{N} Tuple{Vararg{Int, N}}
257+
@test Base.eltype(NInt) === Int
258+
fNInt(x::NInt) = (x...)
259+
gNInt() = fNInt(x)
260+
@test Base.return_types(gNInt, ()) == Any[NInt]

0 commit comments

Comments
 (0)