@@ -42,7 +42,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
42
42
arginfo:: ArgInfo , si:: StmtInfo , @nospecialize (atype),
43
43
sv:: AbsIntState , max_methods:: Int )
44
44
𝕃ₚ, 𝕃ᵢ = ipo_lattice (interp), typeinf_lattice (interp)
45
- ⊑ ₚ, ⊔ ₚ, ⊔ ᵢ = partialorder (𝕃ₚ), join (𝕃ₚ), join (𝕃ᵢ)
45
+ ⊑ ₚ, ⋤ ₚ, ⊔ ₚ, ⊔ ᵢ = partialorder (𝕃ₚ), strictneqpartialorder (𝕃ₚ), join (𝕃ₚ), join (𝕃ᵢ)
46
46
argtypes = arginfo. argtypes
47
47
matches = find_method_matches (interp, argtypes, atype; max_methods)
48
48
if isa (matches, FailedMethodMatch)
@@ -97,9 +97,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
97
97
else
98
98
add_remark! (interp, sv, " [constprop] Discarded because the result was wider than inference" )
99
99
end
100
- if ! (exct ⊑ ₚ const_call_result. exct)
101
- exct = const_call_result. exct
102
- (; const_result, edge) = const_call_result
100
+ if const_call_result. exct ⋤ exct
101
+ (; exct, const_result, edge) = const_call_result
103
102
else
104
103
add_remark! (interp, sv, " [constprop] Discarded exception type because result was wider than inference" )
105
104
end
@@ -154,7 +153,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
154
153
end
155
154
# Treat the exception type separately. Currently, constprop often cannot determine the exception type
156
155
# because consistent-cy does not apply to exceptions.
157
- if ! (this_exct ⊑ ₚ const_call_result. exct)
156
+ if const_call_result. exct ⋤ this_exct
158
157
this_exct = const_call_result. exct
159
158
(; const_result, edge) = const_call_result
160
159
else
@@ -2135,12 +2134,13 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
2135
2134
(types, isexact, isconcrete, istype) = instanceof_tfunc (argtype_by_index (argtypes, 3 ), false )
2136
2135
isexact || return CallMeta (Any, Any, Effects (), NoCallInfo ())
2137
2136
unwrapped = unwrap_unionall (types)
2138
- if types === Bottom || ! (unwrapped isa DataType) || unwrapped. name != = Tuple. name
2139
- return CallMeta (Bottom, Any, EFFECTS_THROWS, NoCallInfo ())
2137
+ types === Bottom && return CallMeta (Bottom, Any, EFFECTS_THROWS, NoCallInfo ())
2138
+ if ! (unwrapped isa DataType && unwrapped. name === Tuple. name)
2139
+ return CallMeta (Bottom, TypeError, EFFECTS_THROWS, NoCallInfo ())
2140
2140
end
2141
2141
argtype = argtypes_to_type (argtype_tail (argtypes, 4 ))
2142
2142
nargtype = typeintersect (types, argtype)
2143
- nargtype === Bottom && return CallMeta (Bottom, Any , EFFECTS_THROWS, NoCallInfo ())
2143
+ nargtype === Bottom && return CallMeta (Bottom, TypeError , EFFECTS_THROWS, NoCallInfo ())
2144
2144
nargtype isa DataType || return CallMeta (Any, Any, Effects (), NoCallInfo ()) # other cases are not implemented below
2145
2145
isdispatchelem (ft) || return CallMeta (Any, Any, Effects (), NoCallInfo ()) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
2146
2146
ft = ft:: DataType
@@ -2154,7 +2154,7 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
2154
2154
tienv = ccall (:jl_type_intersection_with_env , Any, (Any, Any), nargtype, method. sig):: SimpleVector
2155
2155
ti = tienv[1 ]; env = tienv[2 ]:: SimpleVector
2156
2156
result = abstract_call_method (interp, method, ti, env, false , si, sv)
2157
- (; rt, edge, effects, volatile_inf_result) = result
2157
+ (; rt, exct, edge, effects, volatile_inf_result) = result
2158
2158
match = MethodMatch (ti, env, method, argtype <: method.sig )
2159
2159
res = nothing
2160
2160
sig = match. spec_types
@@ -2168,20 +2168,28 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
2168
2168
# argtypes′[i] = t ⊑ a ? t : a
2169
2169
# end
2170
2170
𝕃ₚ = ipo_lattice (interp)
2171
+ ⊑ , ⋤ , ⊔ = partialorder (𝕃ₚ), strictneqpartialorder (𝕃ₚ), join (𝕃ₚ)
2171
2172
f = singleton_type (ft′)
2172
2173
invokecall = InvokeCall (types, lookupsig)
2173
2174
const_call_result = abstract_call_method_with_const_args (interp,
2174
2175
result, f, arginfo, si, match, sv, invokecall)
2175
2176
const_result = volatile_inf_result
2176
2177
if const_call_result != = nothing
2177
- if ⊑ (𝕃ₚ, const_call_result. rt, rt)
2178
+ if const_call_result. rt ⊑ rt
2178
2179
(; rt, effects, const_result, edge) = const_call_result
2179
2180
end
2181
+ if const_call_result. exct ⋤ exct
2182
+ (; exct, const_result, edge) = const_call_result
2183
+ end
2180
2184
end
2181
2185
rt = from_interprocedural! (interp, rt, sv, arginfo, sig)
2182
2186
info = InvokeCallInfo (match, const_result)
2183
2187
edge != = nothing && add_invoke_backedge! (sv, lookupsig, edge)
2184
- return CallMeta (rt, Any, effects, info)
2188
+ if ! match. fully_covers
2189
+ effects = Effects (effects; nothrow= false )
2190
+ exct = exct ⊔ TypeError
2191
+ end
2192
+ return CallMeta (rt, exct, effects, info)
2185
2193
end
2186
2194
2187
2195
function invoke_rewrite (xs:: Vector{Any} )
@@ -2202,16 +2210,16 @@ end
2202
2210
2203
2211
function abstract_throw (interp:: AbstractInterpreter , argtypes:: Vector{Any} , :: AbsIntState )
2204
2212
na = length (argtypes)
2205
- 𝕃ᵢ = typeinf_lattice (interp)
2213
+ ⊔ = join ( typeinf_lattice (interp) )
2206
2214
if na == 2
2207
2215
argtype2 = argtypes[2 ]
2208
2216
if isvarargtype (argtype2)
2209
- exct = tmerge (𝕃ᵢ, unwrapva (argtype2), ArgumentError)
2217
+ exct = unwrapva (argtype2) ⊔ ArgumentError
2210
2218
else
2211
2219
exct = argtype2
2212
2220
end
2213
2221
elseif na == 3 && isvarargtype (argtypes[3 ])
2214
- exct = tmerge (𝕃ᵢ, argtypes[2 ], ArgumentError)
2222
+ exct = argtypes[2 ] ⊔ ArgumentError
2215
2223
else
2216
2224
exct = ArgumentError
2217
2225
end
@@ -2339,35 +2347,38 @@ function abstract_call_opaque_closure(interp::AbstractInterpreter,
2339
2347
ocargsig′ = unwrap_unionall (ocargsig)
2340
2348
ocargsig′ isa DataType || return CallMeta (Any, Any, Effects (), NoCallInfo ())
2341
2349
ocsig = rewrap_unionall (Tuple{Tuple, ocargsig′. parameters... }, ocargsig)
2342
- hasintersect (sig, ocsig) || return CallMeta (Union{}, TypeError, EFFECTS_THROWS, NoCallInfo ())
2350
+ hasintersect (sig, ocsig) || return CallMeta (Union{}, Union{MethodError, TypeError} , EFFECTS_THROWS, NoCallInfo ())
2343
2351
ocmethod = closure. source:: Method
2344
2352
result = abstract_call_method (interp, ocmethod, sig, Core. svec (), false , si, sv)
2345
- (; rt, edge, effects, volatile_inf_result) = result
2353
+ (; rt, exct, edge, effects, volatile_inf_result) = result
2346
2354
match = MethodMatch (sig, Core. svec (), ocmethod, sig <: ocsig )
2347
2355
𝕃ₚ = ipo_lattice (interp)
2348
- ⊑ ₚ = ⊑ (𝕃ₚ)
2356
+ ⊑ , ⋤ , ⊔ = partialorder (𝕃ₚ), strictneqpartialorder (𝕃ₚ), join (𝕃ₚ)
2349
2357
const_result = volatile_inf_result
2350
2358
if ! result. edgecycle
2351
2359
const_call_result = abstract_call_method_with_const_args (interp, result,
2352
2360
nothing , arginfo, si, match, sv)
2353
2361
if const_call_result != = nothing
2354
- if const_call_result. rt ⊑ ₚ rt
2362
+ if const_call_result. rt ⊑ rt
2355
2363
(; rt, effects, const_result, edge) = const_call_result
2356
2364
end
2365
+ if const_call_result. exct ⋤ exct
2366
+ (; exct, const_result, edge) = const_call_result
2367
+ end
2357
2368
end
2358
2369
end
2359
2370
if check # analyze implicit type asserts on argument and return type
2360
- ftt = closure. typ
2361
- (aty, rty) = (unwrap_unionall (ftt):: DataType ). parameters
2362
- rty = rewrap_unionall (rty isa TypeVar ? rty. lb : rty, ftt)
2363
- if ! (rt ⊑ ₚ rty && tuple_tfunc (𝕃ₚ, arginfo. argtypes[2 : end ]) ⊑ ₚ rewrap_unionall (aty, ftt))
2371
+ rty = (unwrap_unionall (tt):: DataType ). parameters[2 ]
2372
+ rty = rewrap_unionall (rty isa TypeVar ? rty. ub : rty, tt)
2373
+ if ! (rt ⊑ rty && sig ⊑ ocsig)
2364
2374
effects = Effects (effects; nothrow= false )
2375
+ exct = exct ⊔ TypeError
2365
2376
end
2366
2377
end
2367
2378
rt = from_interprocedural! (interp, rt, sv, arginfo, match. spec_types)
2368
2379
info = OpaqueClosureCallInfo (match, const_result)
2369
2380
edge != = nothing && add_backedge! (sv, edge)
2370
- return CallMeta (rt, Any , effects, info)
2381
+ return CallMeta (rt, exct , effects, info)
2371
2382
end
2372
2383
2373
2384
function most_general_argtypes (closure:: PartialOpaque )
0 commit comments