@@ -204,7 +204,9 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
204204 if seen ≠ napplicable
205205 # there is unanalyzed candidate, widen type and effects to the top
206206 rettype = Any
207- all_effects = Effects ()
207+ # there may be unanalyzed effects within unseen dispatch candidate,
208+ # but we can still ignore nonoverlayed effect here since we already accounted for it
209+ all_effects = merge_effects (all_effects, EFFECTS_UNKNOWN)
208210 elseif isa (matches, MethodMatches) ? (! matches. fullmatch || any_ambig (matches)) :
209211 (! all (matches. fullmatches) || any_ambig (matches))
210212 # Account for the fact that we may encounter a MethodError with a non-covered or ambiguous signature.
@@ -1304,21 +1306,32 @@ function ssa_def_slot(@nospecialize(arg), sv::InferenceState)
13041306 return arg
13051307end
13061308
1309+ struct AbstractIterationResult
1310+ cti:: Vector{Any}
1311+ info:: MaybeAbstractIterationInfo
1312+ ai_effects:: Effects
1313+ end
1314+ AbstractIterationResult (cti:: Vector{Any} , info:: MaybeAbstractIterationInfo ) =
1315+ AbstractIterationResult (cti, info, EFFECTS_TOTAL)
1316+
13071317# `typ` is the inferred type for expression `arg`.
13081318# if the expression constructs a container (e.g. `svec(x,y,z)`),
13091319# refine its type to an array of element types.
13101320# Union of Tuples of the same length is converted to Tuple of Unions.
13111321# returns an array of types
13121322function precise_container_type (interp:: AbstractInterpreter , @nospecialize (itft), @nospecialize (typ),
13131323 sv:: Union{InferenceState, IRCode} )
1314- if isa (typ, PartialStruct) && typ. typ. name === Tuple. name
1315- return typ. fields, nothing
1324+ if isa (typ, PartialStruct)
1325+ widet = typ. typ
1326+ if isa (widet, DataType) && widet. name === Tuple. name
1327+ return AbstractIterationResult (typ. fields, nothing )
1328+ end
13161329 end
13171330
13181331 if isa (typ, Const)
13191332 val = typ. val
13201333 if isa (val, SimpleVector) || isa (val, Tuple)
1321- return Any[ Const (val[i]) for i in 1 : length (val) ], nothing # avoid making a tuple Generator here!
1334+ return AbstractIterationResult ( Any[ Const (val[i]) for i in 1 : length (val) ], nothing ) # avoid making a tuple Generator here!
13221335 end
13231336 end
13241337
@@ -1333,12 +1346,12 @@ function precise_container_type(interp::AbstractInterpreter, @nospecialize(itft)
13331346 if isa (tti, Union)
13341347 utis = uniontypes (tti)
13351348 if any (@nospecialize (t) -> ! isa (t, DataType) || ! (t <: Tuple ) || ! isknownlength (t), utis)
1336- return Any[Vararg{Any}], nothing
1349+ return AbstractIterationResult ( Any[Vararg{Any}], nothing , EFFECTS_UNKNOWN′)
13371350 end
13381351 ltp = length ((utis[1 ]:: DataType ). parameters)
13391352 for t in utis
13401353 if length ((t:: DataType ). parameters) != ltp
1341- return Any[Vararg{Any}], nothing
1354+ return AbstractIterationResult ( Any[Vararg{Any}], nothing )
13421355 end
13431356 end
13441357 result = Any[ Union{} for _ in 1 : ltp ]
@@ -1349,12 +1362,12 @@ function precise_container_type(interp::AbstractInterpreter, @nospecialize(itft)
13491362 result[j] = tmerge (result[j], rewrap_unionall (tps[j], tti0))
13501363 end
13511364 end
1352- return result, nothing
1365+ return AbstractIterationResult ( result, nothing )
13531366 elseif tti0 <: Tuple
13541367 if isa (tti0, DataType)
1355- return Any[ p for p in tti0. parameters ], nothing
1368+ return AbstractIterationResult ( Any[ p for p in tti0. parameters ], nothing )
13561369 elseif ! isa (tti, DataType)
1357- return Any[Vararg{Any}], nothing
1370+ return AbstractIterationResult ( Any[Vararg{Any}], nothing )
13581371 else
13591372 len = length (tti. parameters)
13601373 last = tti. parameters[len]
@@ -1363,12 +1376,14 @@ function precise_container_type(interp::AbstractInterpreter, @nospecialize(itft)
13631376 if va
13641377 elts[len] = Vararg{elts[len]}
13651378 end
1366- return elts, nothing
1379+ return AbstractIterationResult ( elts, nothing )
13671380 end
1368- elseif tti0 === SimpleVector || tti0 === Any
1369- return Any[Vararg{Any}], nothing
1381+ elseif tti0 === SimpleVector
1382+ return AbstractIterationResult (Any[Vararg{Any}], nothing )
1383+ elseif tti0 === Any
1384+ return AbstractIterationResult (Any[Vararg{Any}], nothing , EFFECTS_UNKNOWN′)
13701385 elseif tti0 <: Array
1371- return Any[Vararg{eltype (tti0)}], nothing
1386+ return AbstractIterationResult ( Any[Vararg{eltype (tti0)}], nothing )
13721387 else
13731388 return abstract_iteration (interp, itft, typ, sv)
13741389 end
@@ -1379,7 +1394,7 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
13791394 if isa (itft, Const)
13801395 iteratef = itft. val
13811396 else
1382- return Any[Vararg{Any}], nothing
1397+ return AbstractIterationResult ( Any[Vararg{Any}], nothing , EFFECTS_UNKNOWN′)
13831398 end
13841399 @assert ! isvarargtype (itertype)
13851400 call = abstract_call_known (interp, iteratef, ArgInfo (nothing , Any[itft, itertype]), StmtInfo (true ), sv)
@@ -1389,7 +1404,7 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
13891404 # WARNING: Changes to the iteration protocol must be reflected here,
13901405 # this is not just an optimization.
13911406 # TODO : this doesn't realize that Array, SimpleVector, Tuple, and NamedTuple do not use the iterate protocol
1392- stateordonet === Bottom && return Any[Bottom], AbstractIterationInfo (CallMeta[CallMeta (Bottom, call. effects, info)])
1407+ stateordonet === Bottom && return AbstractIterationResult ( Any[Bottom], AbstractIterationInfo (CallMeta[CallMeta (Bottom, call. effects, info)], true ) )
13931408 valtype = statetype = Bottom
13941409 ret = Any[]
13951410 calls = CallMeta[call]
@@ -1399,7 +1414,7 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
13991414 # length iterators, or interesting prefix
14001415 while true
14011416 if stateordonet_widened === Nothing
1402- return ret, AbstractIterationInfo (calls)
1417+ return AbstractIterationResult ( ret, AbstractIterationInfo (calls, true ) )
14031418 end
14041419 if Nothing <: stateordonet_widened || length (ret) >= InferenceParams (interp). MAX_TUPLE_SPLAT
14051420 break
@@ -1411,7 +1426,7 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
14111426 # If there's no new information in this statetype, don't bother continuing,
14121427 # the iterator won't be finite.
14131428 if ⊑ (typeinf_lattice (interp), nstatetype, statetype)
1414- return Any[Bottom], nothing
1429+ return AbstractIterationResult ( Any[Bottom], AbstractIterationInfo (calls, false ), EFFECTS_THROWS)
14151430 end
14161431 valtype = getfield_tfunc (typeinf_lattice (interp), stateordonet, Const (1 ))
14171432 push! (ret, valtype)
@@ -1441,7 +1456,7 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
14411456 # ... but cannot terminate
14421457 if ! may_have_terminated
14431458 # ... and cannot have terminated prior to this loop
1444- return Any[Bottom], nothing
1459+ return AbstractIterationResult ( Any[Bottom], AbstractIterationInfo (calls, false ), EFFECTS_UNKNOWN′)
14451460 else
14461461 # iterator may have terminated prior to this loop, but not during it
14471462 valtype = Bottom
@@ -1451,13 +1466,15 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
14511466 end
14521467 valtype = tmerge (valtype, nounion. parameters[1 ])
14531468 statetype = tmerge (statetype, nounion. parameters[2 ])
1454- stateordonet = abstract_call_known (interp, iteratef, ArgInfo (nothing , Any[Const (iteratef), itertype, statetype]), StmtInfo (true ), sv). rt
1469+ call = abstract_call_known (interp, iteratef, ArgInfo (nothing , Any[Const (iteratef), itertype, statetype]), StmtInfo (true ), sv)
1470+ push! (calls, call)
1471+ stateordonet = call. rt
14551472 stateordonet_widened = widenconst (stateordonet)
14561473 end
14571474 if valtype != = Union{}
14581475 push! (ret, Vararg{valtype})
14591476 end
1460- return ret, nothing
1477+ return AbstractIterationResult ( ret, AbstractIterationInfo (calls, false ))
14611478end
14621479
14631480# do apply(af, fargs...), where af is a function value
@@ -1488,13 +1505,9 @@ function abstract_apply(interp::AbstractInterpreter, argtypes::Vector{Any}, si::
14881505 infos′ = Vector{MaybeAbstractIterationInfo}[]
14891506 for ti in (splitunions ? uniontypes (aargtypes[i]) : Any[aargtypes[i]])
14901507 if ! isvarargtype (ti)
1491- cti_info = precise_container_type (interp, itft, ti, sv)
1492- cti = cti_info[1 ]:: Vector{Any}
1493- info = cti_info[2 ]:: MaybeAbstractIterationInfo
1508+ (;cti, info, ai_effects) = precise_container_type (interp, itft, ti, sv)
14941509 else
1495- cti_info = precise_container_type (interp, itft, unwrapva (ti), sv)
1496- cti = cti_info[1 ]:: Vector{Any}
1497- info = cti_info[2 ]:: MaybeAbstractIterationInfo
1510+ (;cti, info, ai_effects) = precise_container_type (interp, itft, unwrapva (ti), sv)
14981511 # We can't represent a repeating sequence of the same types,
14991512 # so tmerge everything together to get one type that represents
15001513 # everything.
@@ -1507,6 +1520,12 @@ function abstract_apply(interp::AbstractInterpreter, argtypes::Vector{Any}, si::
15071520 end
15081521 cti = Any[Vararg{argt}]
15091522 end
1523+ effects = merge_effects (effects, ai_effects)
1524+ if info != = nothing
1525+ for call in info. each
1526+ effects = merge_effects (effects, call. effects)
1527+ end
1528+ end
15101529 if any (@nospecialize (t) -> t === Bottom, cti)
15111530 continue
15121531 end
0 commit comments