| 
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