|
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