@@ -1490,25 +1490,26 @@ end
1490
1490
function abstract_invoke (interp:: AbstractInterpreter , (; fargs, argtypes):: ArgInfo , sv:: InferenceState )
1491
1491
ft′ = argtype_by_index (argtypes, 2 )
1492
1492
ft = widenconst (ft′)
1493
- ft === Bottom && return CallMeta (Bottom, false )
1493
+ ft === Bottom && return CallMeta (Bottom, false ), EFFECTS_THROWN
1494
1494
(types, isexact, isconcrete, istype) = instanceof_tfunc (argtype_by_index (argtypes, 3 ))
1495
- types === Bottom && return CallMeta (Bottom, false )
1496
- isexact || return CallMeta (Any, false )
1495
+ types === Bottom && return CallMeta (Bottom, false ), EFFECTS_THROWN
1496
+ isexact || return CallMeta (Any, false ), Effects ()
1497
1497
argtype = argtypes_to_type (argtype_tail (argtypes, 4 ))
1498
1498
nargtype = typeintersect (types, argtype)
1499
- nargtype === Bottom && return CallMeta (Bottom, false )
1500
- nargtype isa DataType || return CallMeta (Any, false ) # other cases are not implemented below
1501
- isdispatchelem (ft) || return CallMeta (Any, false ) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
1499
+ nargtype === Bottom && return CallMeta (Bottom, false ), EFFECTS_THROWN
1500
+ nargtype isa DataType || return CallMeta (Any, false ), Effects () # other cases are not implemented below
1501
+ isdispatchelem (ft) || return CallMeta (Any, false ), Effects () # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
1502
1502
ft = ft:: DataType
1503
1503
types = rewrap_unionall (Tuple{ft, unwrap_unionall (types). parameters... }, types):: Type
1504
1504
nargtype = Tuple{ft, nargtype. parameters... }
1505
1505
argtype = Tuple{ft, argtype. parameters... }
1506
1506
match, valid_worlds, overlayed = findsup (types, method_table (interp))
1507
- match === nothing && return CallMeta (Any, false )
1507
+ match === nothing && return CallMeta (Any, false ), Effects ()
1508
1508
update_valid_age! (sv, valid_worlds)
1509
1509
method = match. method
1510
1510
(ti, env:: SimpleVector ) = ccall (:jl_type_intersection_with_env , Any, (Any, Any), nargtype, method. sig):: SimpleVector
1511
1511
(; rt, edge) = result = abstract_call_method (interp, method, ti, env, false , sv)
1512
+ effects = result. edge_effects
1512
1513
edge != = nothing && add_backedge! (edge:: MethodInstance , sv)
1513
1514
match = MethodMatch (ti, env, method, argtype <: method.sig )
1514
1515
res = nothing
@@ -1526,10 +1527,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
1526
1527
const_result = nothing
1527
1528
if const_call_result != = nothing
1528
1529
if const_call_result. rt ⊑ rt
1529
- (; rt, const_result) = const_call_result
1530
+ (; rt, effects, const_result) = const_call_result
1530
1531
end
1531
1532
end
1532
- return CallMeta (from_interprocedural! (rt, sv, arginfo, sig), InvokeCallInfo (match, const_result))
1533
+ return CallMeta (from_interprocedural! (rt, sv, arginfo, sig), InvokeCallInfo (match, const_result)), effects
1533
1534
end
1534
1535
1535
1536
function invoke_rewrite (xs:: Vector{Any} )
@@ -1550,14 +1551,8 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
1550
1551
if f === _apply_iterate
1551
1552
return abstract_apply (interp, argtypes, sv, max_methods)
1552
1553
elseif f === invoke
1553
- call = abstract_invoke (interp, arginfo, sv)
1554
- if call. info === false
1555
- if call. rt === Bottom
1556
- tristate_merge! (sv, Effects (EFFECTS_TOTAL; nothrow= ALWAYS_FALSE))
1557
- else
1558
- tristate_merge! (sv, Effects ())
1559
- end
1560
- end
1554
+ call, effects = abstract_invoke (interp, arginfo, sv)
1555
+ tristate_merge! (sv, effects)
1561
1556
return call
1562
1557
elseif f === modifyfield!
1563
1558
tristate_merge! (sv, Effects ()) # TODO
0 commit comments