Skip to content

Commit 3744a02

Browse files
aviateskKristofferC
authored andcommitted
inference: add missing LimitedAccuracy handlings (#42034)
I found we need to handle `LimitedAccuracy` (i.e. collect its limitations into the current frame and unwrap its type) whenever we do inter-procedural inference. Especially, we need to handle it where we use `abstract_call_method` and `abstract_call_method_with_const_args`. Otherwise we may encounter nested `LimitedAccuracy`, which is really not expected. So this commit also adds the assertion that checks we never form nested `LimitedAccuracy`. I encountered errors due to this when analyzing JET itself by JET, probably because its codebase makes heavy use of `invoke`. I couldn't pack them up as simple test cases though. (cherry picked from commit 6341fa5)
1 parent 5e99551 commit 3744a02

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
211211
info = ConstCallInfo(info, const_results)
212212
end
213213

214-
if rettype isa LimitedAccuracy
215-
union!(sv.pclimitations, rettype.causes)
216-
rettype = rettype.typ
217-
end
214+
rettype = collect_limitations!(rettype, sv)
218215
# if we have argument refinement information, apply that now to get the result
219216
if is_lattice_bool(rettype) && conditionals !== nothing && fargs !== nothing
220217
slot = 0
@@ -1177,9 +1174,9 @@ function abstract_invoke(interp::AbstractInterpreter, argtypes::Vector{Any}, sv:
11771174
# end
11781175
const_rt, const_result = abstract_call_method_with_const_args(interp, result, argtype_to_function(ft′), argtypes′, match, sv, false)
11791176
if const_rt !== rt && const_rt rt
1180-
return CallMeta(const_rt, InvokeCallInfo(match, const_result))
1177+
return CallMeta(collect_limitations!(const_rt, sv), InvokeCallInfo(match, const_result))
11811178
else
1182-
return CallMeta(rt, InvokeCallInfo(match, nothing))
1179+
return CallMeta(collect_limitations!(rt, sv), InvokeCallInfo(match, nothing))
11831180
end
11841181
end
11851182

@@ -1296,7 +1293,7 @@ function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::Part
12961293
info = ConstCallInfo(info, Union{Nothing,InferenceResult}[const_result])
12971294
end
12981295
end
1299-
return CallMeta(rt, info)
1296+
return CallMeta(collect_limitations!(rt, sv), info)
13001297
end
13011298

13021299
function most_general_argtypes(closure::PartialOpaque)

base/compiler/typelattice.jl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,18 @@ end
9696
struct LimitedAccuracy
9797
typ
9898
causes::IdSet{InferenceState}
99-
LimitedAccuracy(@nospecialize(typ), causes::IdSet{InferenceState}) =
100-
new(typ, causes)
99+
function LimitedAccuracy(@nospecialize(typ), causes::IdSet{InferenceState})
100+
@assert !isa(typ, LimitedAccuracy) "malformed LimitedAccuracy"
101+
return new(typ, causes)
102+
end
103+
end
104+
105+
@inline function collect_limitations!(@nospecialize(typ), sv::InferenceState)
106+
if isa(typ, LimitedAccuracy)
107+
union!(sv.pclimitations, typ.causes)
108+
return typ.typ
109+
end
110+
return typ
101111
end
102112

103113
struct NotFound end

0 commit comments

Comments
 (0)