Repository: JuliaDebug/Cthulhu.jl
Pull request #186 (2021-08-01 10:21:47)

Get Revise working again
This also deletes some currently-unused code.
Does anyone use `unwrapconst` in debugging?


Patch:
diff --git a/src/Cthulhu.jl b/src/Cthulhu.jl
index 420ba7b..e8121b1 100644
--- a/src/Cthulhu.jl
+++ b/src/Cthulhu.jl
@@ -358,7 +358,8 @@ function _descend(interp::CthulhuInterpreter, mi::MethodInstance; override::Unio
             if mod !== nothing
                 revise = getfield(mod, :revise)::Function
                 revise()
-                mi = first_method_instance(mi.specTypes)
+                mi = get_specialization(mi.specTypes)
+                do_typeinf!(interp, mi)
             end
         elseif toggle === :edit
             edit(whereis(mi.def)...)
diff --git a/src/backedges.jl b/src/backedges.jl
index c535bb2..4d7208a 100644
--- a/src/backedges.jl
+++ b/src/backedges.jl
@@ -1,6 +1,6 @@
 # A lightly-modified version of the same function in Base
 # Highlights argument types with color specified by highlighter(typ)
-function show_tuple_as_call(@nospecialize(highlighter), io::IO, name::Symbol, @nospecialize(sig::Type), demangle=false #=, kwargs=nothing =#)
+function show_tuple_as_call(@nospecialize(highlighter), io::IO, name::Symbol, @nospecialize(sig::Type), demangle=false, kwargs=nothing)
     if sig === Tuple
         print(io, demangle ? Base.demangle_function_name(name) : name, "(...)")
         return
@@ -34,16 +34,16 @@ function show_tuple_as_call(@nospecialize(highlighter), io::IO, name::Symbol, @n
         first = false
         printstyled(env_io, "::", sig[i], color=highlighter(sig[i]))
     end
-    # if kwargs !== nothing
-    #     print(io, "; ")
-    #     first = true
-    #     for (k, t) in kwargs
-    #         first || print(io, ", ")
-    #         first = false
-    #         print(io, k, "::")
-    #         show(io, t)
-    #     end
-    # end
+    if kwargs !== nothing
+        print(io, "; ")
+        first = true
+        for (k, t) in kwargs
+            first || print(io, ", ")
+            first = false
+            print(io, k, "::")
+            show(io, t)
+        end
+    end
     print(io, ")")
     Base.show_method_params(io, tv)
     nothing
@@ -89,7 +89,7 @@ nextnode(mi, edge) = edge
 instance(sfs::Vector{StackTraces.StackFrame}) = sfs[end].linfo
 method(sfs::Vector{StackTraces.StackFrame}) = method(instance(sfs))
 
-instance(ipframes::Vector{IPFrames}) = isempty(ipframes) ? nothing : instance(ipframes[1].sfs)
+instance(ipframes::Vector{IPFrames}) = instance(ipframes[1].sfs)
 backedges(ipframes::Vector{IPFrames}) = (ret = ipframes[2:end]; isempty(ret) ? () : (ret,))
 
 function callstring(io, mi)
@@ -97,7 +97,6 @@ function callstring(io, mi)
     return String(take!(io))
 end
 function callstring(io, sfs::Vector{StackTraces.StackFrame})
-    isempty(sfs) && return ""
     for i = 1:length(sfs)-1
         sf = sfs[i]
         print(io, sf.func, " at ", sf.file, ':', sf.line, " => ")
@@ -105,7 +104,7 @@ function callstring(io, sfs::Vector{StackTraces.StackFrame})
     sf = sfs[end]
     return callstring(io, instance(sfs)) * string(" at ", sf.file, ':', sf.line)
 end
-callstring(io, ipframes::Vector{IPFrames}) = isempty(ipframes) ? "" : callstring(io, ipframes[1].sfs)
+callstring(io, ipframes::Vector{IPFrames}) = callstring(io, ipframes[1].sfs)
 
 struct Data{T}
     callstr::String
diff --git a/src/reflection.jl b/src/reflection.jl
index 736ee88..0433c64 100644
--- a/src/reflection.jl
+++ b/src/reflection.jl
@@ -12,22 +12,6 @@ const sptypes_from_meth_instance = Core.Compiler.sptypes_from_meth_instance
 const may_invoke_generator = Base.may_invoke_generator
 code_for_method(method, metharg, methsp, world, force=false) = Core.Compiler.specialize_method(method, metharg, methsp, force)
 
-# https://github.com/JuliaLang/julia/pull/36318
-_id(x) = x.id
-_id(x::Core.Argument) = x.n
-const SlotOrArgument = Union{Core.Argument,Core.Slot}
-
-function unwrapconst(a)
-    if isa(a, Const)
-        a = Core.Typeof(a.val)
-    elseif isa(a, Core.Compiler.PartialStruct)
-        a = a.typ
-    elseif isa(a, Core.Compiler.MaybeUndef)
-        a = a.typ
-    end
-    return a
-end
-
 transform(::Val, callsite) = callsite
 function transform(::Val{:CuFunction}, callsite, callexpr, CI, mi, slottypes; params=nothing, kwargs...)
     sptypes = sptypes_from_meth_instance(mi)
@@ -218,24 +202,6 @@ end
 const CompilerParams = Core.Compiler.NativeInterpreter
 current_params() = CompilerParams()
 
-function first_method_instance(@nospecialize(F), @nospecialize(TT); params=current_params())
-    sig = Base.signature_type(F, TT)
-    first_method_instance(sig; params=params)
-end
-
-function first_method_instance(@nospecialize(sig); params=current_params())
-    ci = callinfo(sig, Any, 1, params=params)
-    if ci isa Union{GeneratedCallInfo, FailedCallInfo, MultiCallInfo}
-        if ci isa MultiCallInfo
-            @warn "expected single CallInfo got multiple" ci
-        end
-        return nothing
-    else
-        @assert ci isa MICallInfo
-        return get_mi(ci)
-    end
-end
-
 function callinfo(sig, rt, max_methods=-1; params=current_params())
     methds = Base._methods_by_ftype(sig, max_methods, params.world)
     (methds === false || length(methds) < 1) && return FailedCallInfo(sig, rt)


Test patch:
diff --git a/test/runtests.jl b/test/runtests.jl
index 88bf16c..e9b2ecf 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -411,27 +411,12 @@ fst5(x) = fst4(x)
     root = Cthulhu.treelist(mi)
     @test occursin("Vararg", root.data.callstr)
 
-    # Test highlighting and other printing
-    mi = Cthulhu.get_specialization(:, Tuple{T, T} where T<:Integer)
-    root = Cthulhu.treelist(mi)
-    @test occursin("\e[31m::T\e[39m", root.data.callstr)
-    mi = Cthulhu.get_specialization(Vector{Int}, Tuple{typeof(undef), Int})
-    io = IOBuffer()
-    @test Cthulhu.callstring(io, mi) == "Vector{$Int}(::UndefInitializer, ::$Int)"
-    mi = Cthulhu.get_specialization(similar, Tuple{Type{Vector{T}}, Dims{1}} where T)
-    @test occursin(r"31m::Type", Cthulhu.callstring(io, mi))
-
     # treelist for stacktraces
     tree = Cthulhu.treelist(fst5(1.0))
     @test match(r"fst1 at .*:\d+ => fst2 at .*:\d+ => fst3\(::Float64\) at .*:\d+", tree.data.callstr) !== nothing
     @test length(tree.children) == 1
     child = tree.children[1]
     @test match(r" fst4 at .*:\d+ => fst5\(::Float64\) at .*:\d+", child.data.callstr) !== nothing
-
-    # issue #184
-    tree = Cthulhu.treelist(similar(fst5(1.0), 0))
-    @test isempty(tree.data.callstr)
-    @test isempty(Cthulhu.callstring(io, similar(stacktrace(fst5(1.0)), 0)))
 end
 
 @testset "ascend" begin