@@ -1966,14 +1966,32 @@ function finish(me::InferenceState)
19661966 nothing
19671967end
19681968
1969- function eval_annotate (e:: ANY , vtypes:: ANY , sv:: InferenceState , undefs)
1969+ function record_slot_type! (id, vt:: ANY , slottypes)
1970+ if vt != = Bottom
1971+ otherTy = slottypes[id]
1972+ if otherTy === Bottom
1973+ slottypes[id] = vt
1974+ elseif otherTy != = Any && ! typeseq (otherTy, vt)
1975+ slottypes[id] = Any
1976+ end
1977+ end
1978+ end
1979+
1980+ function eval_annotate (e:: ANY , vtypes:: ANY , sv:: InferenceState , undefs, pass)
19701981 if isa (e, Slot)
1971- t = abstract_eval (e, vtypes, sv)
1972- s = vtypes[e. id]
1973- if s. undef
1974- undefs[e. id] = true
1982+ id = (e:: Slot ). id
1983+ s = vtypes[id]
1984+ vt = widenconst (s. typ)
1985+ if pass == 1
1986+ # first pass: find used-undef variables and type-constant variables
1987+ if s. undef
1988+ undefs[id] = true
1989+ end
1990+ record_slot_type! (id, vt, sv. linfo. slottypes)
1991+ return e
19751992 end
1976- return t === sv. linfo. slottypes[e. id] ? e : TypedSlot (e. id, t)
1993+ # second pass: add type annotations where needed
1994+ return vt === sv. linfo. slottypes[id] ? e : TypedSlot (id, vt)
19771995 end
19781996
19791997 if ! isa (e,Expr)
@@ -1985,14 +2003,14 @@ function eval_annotate(e::ANY, vtypes::ANY, sv::InferenceState, undefs)
19852003 if is (head,:static_typeof ) || is (head,:line ) || is (head,:const )
19862004 return e
19872005 elseif is (head,:(= ))
1988- e. args[2 ] = eval_annotate (e. args[2 ], vtypes, sv, undefs)
2006+ e. args[2 ] = eval_annotate (e. args[2 ], vtypes, sv, undefs, pass )
19892007 return e
19902008 end
19912009 i0 = is (head,:method ) ? 2 : 1
19922010 for i= i0: length (e. args)
19932011 subex = e. args[i]
19942012 if ! (isa (subex,Number) || isa (subex,AbstractString))
1995- e. args[i] = eval_annotate (subex, vtypes, sv, undefs)
2013+ e. args[i] = eval_annotate (subex, vtypes, sv, undefs, pass )
19962014 end
19972015 end
19982016 return e
@@ -2013,38 +2031,31 @@ end
20132031# annotate types of all symbols in AST
20142032function type_annotate! (linfo:: LambdaInfo , states:: Array{Any,1} , sv:: ANY , nargs)
20152033 nslots = length (states[1 ])
2016- for i = 1 : nslots
2034+ nargs = linfo. nargs
2035+ for i = 1 : nargs
2036+ linfo. slottypes[i] = widenconst (states[1 ][i]. typ)
2037+ end
2038+ for i = nargs+ 1 : nslots
20172039 linfo. slottypes[i] = Bottom
20182040 end
20192041 undefs = fill (false , nslots)
20202042 body = linfo. code:: Array{Any,1}
20212043 nexpr = length (body)
2022- for i= 1 : nexpr
2023- # identify variables always used as the same type
2024- st_i = states[i]
2025- if st_i != = ()
2026- for j = 1 : nslots
2027- vt = widenconst (st_i[j]. typ)
2028- if vt != = Bottom
2029- otherTy = linfo. slottypes[j]
2030- if otherTy === Bottom
2031- linfo. slottypes[j] = vt
2032- elseif otherTy != = Any && ! typeseq (otherTy, vt)
2033- linfo. slottypes[j] = Any
2034- end
2035- end
2036- end
2037- end
2038- end
20392044 i = 1
20402045 optimize = sv. optimize:: Bool
20412046 while i <= nexpr
20422047 st_i = states[i]
2048+ expr = body[i]
20432049 if st_i != = ()
20442050 # st_i === () => unreached statement (see issue #7836)
2045- body[i] = eval_annotate (body[i], st_i, sv, undefs)
2051+ eval_annotate (expr, st_i, sv, undefs, 1 )
2052+ if isa (expr, Expr) && expr. head == :(= ) && i < nexpr && isa (expr. args[1 ],Slot) && states[i+ 1 ] != = ()
2053+ # record type of assigned slot by looking at the next statement.
2054+ # this is needed in case the slot is never used (which makes eval_annotate miss it).
2055+ id = expr. args[1 ]. id
2056+ record_slot_type! (id, widenconst (states[i+ 1 ][id]. typ), linfo. slottypes)
2057+ end
20462058 elseif optimize
2047- expr = body[i]
20482059 if isa (expr, Expr) && expr_cannot_delete (expr:: Expr )
20492060 i += 1
20502061 continue
@@ -2058,6 +2069,12 @@ function type_annotate!(linfo::LambdaInfo, states::Array{Any,1}, sv::ANY, nargs)
20582069 end
20592070 i += 1
20602071 end
2072+ for i = 1 : nexpr
2073+ st_i = states[i]
2074+ if st_i != = ()
2075+ body[i] = eval_annotate (body[i], st_i, sv, undefs, 2 )
2076+ end
2077+ end
20612078
20622079 # mark used-undef variables
20632080 for i = 1 : nslots
0 commit comments