Skip to content

Commit

Permalink
more thorough type_goto. fixes JuliaLang#7810
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Aug 3, 2014
1 parent b4f633f commit 0457c7a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 19 deletions.
53 changes: 35 additions & 18 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1333,10 +1333,6 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
toprec = false

s = { () for i=1:n }
recpts = IntSet() # statements that depend recursively on our value
W = IntSet()
# initial set of pc
push!(W,1)
# initial types
s[1] = ObjectIdDict()
for v in vars
Expand Down Expand Up @@ -1386,10 +1382,19 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
sv = StaticVarInfo(sparams, cenv, vars, label_counter(body))
frame.sv = sv

recpts = IntSet() # statements that depend recursively on our value
W = IntSet()

@label typeinf_top

old_s1 = nothing

# exception handlers
cur_hand = ()
handler_at = { () for i=1:n }

push!(W,1) # initial set of pc

while !isempty(W)
pc = first(W)
while true
Expand Down Expand Up @@ -1442,26 +1447,24 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
end
end
elseif is(hd,:type_goto)
l = findlabel(labels,stmt.args[1])
for i = 2:length(stmt.args)
var = stmt.args[i]
if isa(var,SymbolNode)
var = var.name
end
# type_goto provides a special update rule for the
# listed vars: it feeds types directly to the
# target statement as long as they are *different*,
# not !issubtype like usual. this is because we want
# the specific type inferred at the point of the
# type_goto, not just any type containing it.
# Otherwise "None" doesn't work; see issue #3821
# Store types that need to be fed back via type_goto
# in position s[1]. After finishing inference, if any
# of these types changed, start over with the fed-back
# types known from the beginning.
# See issue #3821 (using !typeseq instead of !subtype),
# and issue #7810.
vt = changes[var]
ot = get(s[l],var,NF)
if ot === NF || !typeseq(vt,ot)
# l+1 is the statement after the label, where the
# static_typeof occurs.
push!(W, l+1)
s[l+1][var] = vt
ot = s[1][var]
if !typeseq(vt,ot)
if old_s1 === nothing
old_s1 = copy(s[1])
end
s[1][var] = vt
end
end
elseif is(hd,:return)
Expand Down Expand Up @@ -1515,6 +1518,20 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
end
end
end

if old_s1 !== nothing
# if any type_gotos changed, clear state and restart.
for (v_,t_) in s[1]
if !typeseq(t_, old_s1[v_])
for ll = 2:length(s)
s[ll] = ()
end
empty!(W)
@goto typeinf_top
end
end
end

#print("\n",ast,"\n")
#if dbg print("==> ", frame.result,"\n") end
if (toprec && typeseq(curtype, frame.result)) || !isa(frame.prev,CallStack)
Expand Down
8 changes: 7 additions & 1 deletion test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1804,6 +1804,12 @@ i7652() = a7652.(1) = 3.0
i7652()
@test a7652.a == 3


# issue #7679
@test map(f->f(), { ()->i for i=1:3 }) == {1,2,3}

# issue #7810
type Foo7810{T<:AbstractVector}
v::T
end
bar7810() = [Foo7810([(a,b) for a in 1:2]) for b in 3:4]
@test Base.return_types(bar7810,())[1] == Array{Foo7810{Array{(Int64,Int64),1}},1}

0 comments on commit 0457c7a

Please sign in to comment.