|
856 | 856 |
|
857 | 857 | struct InvokeCall
|
858 | 858 | types # ::Type
|
859 |
| - lookupsig # ::Type |
860 |
| - InvokeCall(@nospecialize(types), @nospecialize(lookupsig)) = new(types, lookupsig) |
| 859 | + InvokeCall(@nospecialize(types)) = new(types) |
861 | 860 | end
|
862 | 861 |
|
863 | 862 | struct ConstCallResult
|
@@ -2218,34 +2217,46 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
|
2218 | 2217 | ft′ = argtype_by_index(argtypes, 2)
|
2219 | 2218 | ft = widenconst(ft′)
|
2220 | 2219 | ft === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo()))
|
2221 |
| - (types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false) |
2222 |
| - isexact || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) |
2223 |
| - unwrapped = unwrap_unionall(types) |
2224 |
| - types === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo())) |
2225 |
| - if !(unwrapped isa DataType && unwrapped.name === Tuple.name) |
2226 |
| - return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) |
2227 |
| - end |
2228 |
| - argtype = argtypes_to_type(argtype_tail(argtypes, 4)) |
2229 |
| - nargtype = typeintersect(types, argtype) |
2230 |
| - nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) |
2231 |
| - nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below |
2232 |
| - isdispatchelem(ft) || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below |
2233 |
| - ft = ft::DataType |
2234 |
| - lookupsig = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type |
2235 |
| - nargtype = Tuple{ft, nargtype.parameters...} |
2236 |
| - argtype = Tuple{ft, argtype.parameters...} |
2237 |
| - matched, valid_worlds = findsup(lookupsig, method_table(interp)) |
2238 |
| - matched === nothing && return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) |
2239 |
| - update_valid_age!(sv, valid_worlds) |
2240 |
| - method = matched.method |
| 2220 | + types = argtype_by_index(argtypes, 3) |
| 2221 | + if types isa Const && types.val isa Method |
| 2222 | + method = types.val::Method |
| 2223 | + types = method # argument value |
| 2224 | + lookupsig = method.sig # edge kind |
| 2225 | + argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft)) |
| 2226 | + nargtype = typeintersect(lookupsig, argtype) |
| 2227 | + nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) |
| 2228 | + nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below |
| 2229 | + else |
| 2230 | + widenconst(types) >: Method && return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) |
| 2231 | + (types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false) |
| 2232 | + isexact || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) |
| 2233 | + unwrapped = unwrap_unionall(types) |
| 2234 | + types === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo())) |
| 2235 | + if !(unwrapped isa DataType && unwrapped.name === Tuple.name) |
| 2236 | + return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) |
| 2237 | + end |
| 2238 | + argtype = argtypes_to_type(argtype_tail(argtypes, 4)) |
| 2239 | + nargtype = typeintersect(types, argtype) |
| 2240 | + nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) |
| 2241 | + nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below |
| 2242 | + isdispatchelem(ft) || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below |
| 2243 | + ft = ft::DataType |
| 2244 | + lookupsig = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type |
| 2245 | + nargtype = Tuple{ft, nargtype.parameters...} |
| 2246 | + argtype = Tuple{ft, argtype.parameters...} |
| 2247 | + matched, valid_worlds = findsup(lookupsig, method_table(interp)) |
| 2248 | + matched === nothing && return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) |
| 2249 | + update_valid_age!(sv, valid_worlds) |
| 2250 | + method = matched.method |
| 2251 | + end |
2241 | 2252 | tienv = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
|
2242 | 2253 | ti = tienv[1]
|
2243 | 2254 | env = tienv[2]::SimpleVector
|
2244 | 2255 | mresult = abstract_call_method(interp, method, ti, env, false, si, sv)::Future
|
2245 | 2256 | match = MethodMatch(ti, env, method, argtype <: method.sig)
|
2246 | 2257 | ft′_box = Core.Box(ft′)
|
2247 | 2258 | lookupsig_box = Core.Box(lookupsig)
|
2248 |
| - invokecall = InvokeCall(types, lookupsig) |
| 2259 | + invokecall = InvokeCall(types) |
2249 | 2260 | return Future{CallMeta}(mresult, interp, sv) do result, interp, sv
|
2250 | 2261 | (; rt, exct, effects, edge, volatile_inf_result) = result
|
2251 | 2262 | local ft′ = ft′_box.contents
|
|
0 commit comments