Skip to content

Commit 7f3cf66

Browse files
authored
Handle Core._expr method bodies (#22)
Fixes timholy/Revise.jl#398
1 parent ac92660 commit 7f3cf66

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ julia = "1"
1212

1313
[extras]
1414
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
15+
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
1516
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1617

1718
[targets]
18-
test = ["InteractiveUtils", "Test"]
19+
test = ["InteractiveUtils", "Parameters", "Test"]

src/LoweredCodeUtils.jl

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ end
365365
rename_framemethods!(frame::Frame) = rename_framemethods!(finish_and_return!, frame)
366366

367367
"""
368-
pctop, isgen = find_corrected_name(frame, pc, name, parentname)
368+
pctop, isgen = find_corrected_name(recurse, frame, pc, name, parentname)
369369
370370
Scans forward from `pc` in `frame` until a method is found that calls `name`.
371371
`pctop` points to the beginning of that method's signature.
@@ -374,16 +374,29 @@ Scans forward from `pc` in `frame` until a method is found that calls `name`.
374374
Alternatively, this returns `nothing` if `pc` does not appear to point to either
375375
a keyword or generated method.
376376
"""
377-
function find_corrected_name(frame, pc, name, parentname)
377+
function find_corrected_name(@nospecialize(recurse), frame, pc, name, parentname)
378378
stmt = pc_expr(frame, pc)
379379
while true
380+
pc0 = pc
380381
while !ismethod3(stmt)
381382
pc = next_or_nothing(frame, pc)
382383
pc === nothing && return nothing
383384
stmt = pc_expr(frame, pc)
384385
end
385386
body = stmt.args[3]
386-
if stmt.args[1] != name
387+
if stmt.args[1] != name && isa(body, SSAValue)
388+
# OK, we can't skip all the stuff that might define the body
389+
# See https://github.com/timholy/Revise.jl/issues/398
390+
pc = pc0
391+
stmt = pc_expr(frame, pc)
392+
while !ismethod3(stmt)
393+
pc = step_expr!(recurse, frame, stmt, true)
394+
pc === nothing && return nothing
395+
stmt = pc_expr(frame, pc)
396+
end
397+
body = @lookup(frame, stmt.args[3])
398+
end
399+
if stmt.args[1] != name && isa(body, CodeInfo)
387400
# This might be the GeneratedFunctionStub for a @generated method
388401
for (i, bodystmt) in enumerate(body.code)
389402
if isexpr(bodystmt, :meta) && bodystmt.args[1] == :generated
@@ -435,7 +448,7 @@ end
435448

436449
function get_running_name(@nospecialize(recurse), frame, pc, name, parentname)
437450
# Get the correct name (the one that's actively running)
438-
nameinfo = find_corrected_name(frame, pc, name, parentname)
451+
nameinfo = find_corrected_name(recurse, frame, pc, name, parentname)
439452
if nameinfo === nothing
440453
pc = skip_until(stmt->isexpr(stmt, :method, 3), frame, pc)
441454
pc = next_or_nothing(frame, pc)

test/runtests.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ using Test
88
@test isempty(detect_ambiguities(LoweredCodeUtils, JuliaInterpreter, Base, Core))
99

1010
module Lowering
11+
using Parameters
1112
struct Caller end
1213
struct Gen{T} end
1314
end
@@ -308,4 +309,19 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
308309
empty!(signatures)
309310
methoddefs!(signatures, frame; define=false)
310311
@test Tuple{typeof(Lowering.CustomMS)} signatures
312+
313+
# https://github.com/timholy/Revise.jl/issues/398
314+
ex = quote
315+
@with_kw struct Items
316+
n::Int
317+
items::Vector{Int} = [i for i=1:n]
318+
end
319+
end
320+
Core.eval(Lowering, ex)
321+
frame = JuliaInterpreter.prepare_thunk(Lowering, ex)
322+
dct = rename_framemethods!(frame)
323+
ks = collect(filter(k->startswith(String(k), "#Items#"), keys(dct)))
324+
@test length(ks) == 2
325+
@test dct[ks[1]] == dct[ks[2]]
326+
@test isdefined(Lowering, ks[1]) || isdefined(Lowering, ks[2])
311327
end

0 commit comments

Comments
 (0)