@@ -151,6 +151,28 @@ non-concrete call sites in a toplevel frame created by `JET.virtual_process`.
151151"""
152152CC. bail_out_toplevel_call (:: LSAnalyzer , :: CC.InferenceState ) = false
153153
154+ function CC. abstract_call_gf_by_type (analyzer:: LSAnalyzer ,
155+ @nospecialize (func), arginfo:: CC.ArgInfo , si:: CC.StmtInfo , @nospecialize (atype), sv:: CC.InferenceState ,
156+ max_methods:: Int )
157+ ret = @invoke CC. abstract_call_gf_by_type (analyzer:: ToplevelAbstractAnalyzer ,
158+ func:: Any , arginfo:: CC.ArgInfo , si:: CC.StmtInfo , atype:: Any , sv:: CC.InferenceState , max_methods:: Int )
159+ if ! should_analyze (analyzer, sv)
160+ return ret
161+ end
162+ atype′ = Ref {Any} (atype)
163+ function after_abstract_call_gf_by_type (analyzer′:: LSAnalyzer , sv′:: CC.InferenceState )
164+ ret′ = ret[]
165+ report_method_error! (analyzer′, sv′, ret′, arginfo, atype′[])
166+ return true
167+ end
168+ if isready (ret)
169+ after_abstract_call_gf_by_type (analyzer, sv)
170+ else
171+ push! (sv. tasks, after_abstract_call_gf_by_type)
172+ end
173+ return ret
174+ end
175+
154176# TODO Better to factor out and share it with `JET.JETAnalyzer`
155177function CC. abstract_eval_globalref (analyzer:: LSAnalyzer ,
156178 g:: GlobalRef , saw_latestworld:: Bool , sv:: CC.InferenceState )
185207# analysis
186208# ========
187209
210+ # MethodErrorReport
211+ # -----------------
212+
213+ @jetreport struct MethodErrorReport <: InferenceErrorReport
214+ @nospecialize t # ::Union{Type, Vector{Type}}
215+ union_split:: Int
216+ end
217+ function JETInterface. print_report_message (io:: IO , report:: MethodErrorReport )
218+ print (io, " no matching method found " )
219+ if report. union_split == 0
220+ print_callsig (io, report. t)
221+ else
222+ ts = report. t:: Vector{Any}
223+ nts = length (ts)
224+ for i = 1 : nts
225+ print_callsig (io, ts[i])
226+ i == nts || print (io, " , " )
227+ end
228+ print (io, " (" , nts, ' /' , report. union_split, " union split)" )
229+ end
230+ end
231+ function print_callsig (io, @nospecialize (t))
232+ print (io, ' `' )
233+ Base. show_tuple_as_call (io, Symbol (" " ), t)
234+ print (io, ' `' )
235+ end
236+ inference_error_report_stack_impl (r:: MethodErrorReport ) = length (r. vst): - 1 : 1
237+ inference_error_report_severity_impl (r:: MethodErrorReport ) = DiagnosticSeverity. Warning
238+
239+ function report_method_error! (analyzer:: LSAnalyzer ,
240+ sv:: CC.InferenceState , call:: CC.CallMeta , arginfo:: CC.ArgInfo , @nospecialize (atype))
241+ info = call. info
242+ if isa (info, CC. ConstCallInfo)
243+ info = info. call
244+ end
245+ if isa (info, CC. MethodMatchInfo)
246+ report_method_error! (analyzer, sv, info, atype)
247+ elseif isa (info, CC. UnionSplitInfo)
248+ report_method_error_for_union_split! (analyzer, sv, info, arginfo)
249+ end
250+ end
251+
252+ function report_method_error! (analyzer:: LSAnalyzer , sv:: CC.InferenceState , info:: CC.MethodMatchInfo , @nospecialize (atype))
253+ if CC. isempty (info. results)
254+ report = MethodErrorReport (sv, atype, 0 )
255+ add_new_report! (analyzer, sv. result, report)
256+ return true
257+ end
258+ return false
259+ end
260+
261+ function report_method_error_for_union_split! (analyzer:: LSAnalyzer , sv:: CC.InferenceState , info:: CC.UnionSplitInfo , arginfo:: CC.ArgInfo )
262+ # check each match for union-split signature
263+ split_argtypes = empty_matches = nothing
264+ reported = false
265+ for (i, matchinfo) in enumerate (info. split)
266+ if CC. isempty (matchinfo. results)
267+ if isnothing (split_argtypes)
268+ split_argtypes = CC. switchtupleunion (CC. typeinf_lattice (analyzer), arginfo. argtypes)
269+ end
270+ argtypes′ = split_argtypes[i]:: Vector{Any}
271+ if empty_matches === nothing
272+ empty_matches = (Any[], length (info. split))
273+ end
274+ sig_n = CC. argtypes_to_type (argtypes′)
275+ push! (empty_matches[1 ], sig_n)
276+ end
277+ end
278+ if empty_matches != = nothing
279+ add_new_report! (analyzer, sv. result, MethodErrorReport (sv, empty_matches... ))
280+ reported |= true
281+ end
282+ return reported
283+ end
284+
188285# UndefVarErrorReport
189286# -------------------
190287
@@ -278,7 +375,7 @@ function LSAnalyzer(entry::AnalysisEntry,
278375 # Enable the `assume_bindings_static` option to terminate analysis a bit earlier when
279376 # there are undefined bindings detected. Note that this option will cause inference
280377 # cache inconsistency until JuliaLang/julia#40399 is merged. But the analysis cache of
281- # JETAnalyzer has the same problem already anyway, so enabling this option does not
378+ # LSAnalyzer has the same problem already anyway, so enabling this option does not
282379 # make the situation worse.
283380 jetconfigs[:assume_bindings_static ] = true
284381 state = AnalyzerState (world; jetconfigs... )
0 commit comments