-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KeyError: key :S not found
in map_ssas_to_source
#404
Labels
bug
Something isn't working
TypedSyntax
An issue or pull request relating to the TypedSyntax.jl subpackage
Comments
I recognize this is one of the CodeTracking bugs identified in #401, where it finds the wrong method: julia> mi = badmis[end-7]
MethodInstance for (Vector)(::Vector{S}) where S
julia> mi.def
(Array{T, N} where T)(x::AbstractArray{S, N}) where {S, N}
@ Core boot.jl:498
julia> definition(String, mi.def)
("Array{T,1}() where {T} = Array{T,1}(undef, 0)", 496) Clearly not the same method. There's work on improving CodeTracking going on in timholy/CodeTracking.jl#108 |
KeyError: key :S not found
in map_ssas_to_source
Would it be helpful to have another MRE? |
This MRE passes on julia 1.11, but fails on 1.10. Error first, then the source file at the end: (@v1.10) pkg> st
Status `~/.julia/environments/v1.10/Project.toml`
[69d22d85] About v1.0.1
[1520ce14] AbstractTrees v0.4.5
⌃ [6e4b80f9] BenchmarkTools v1.5.0
[a2441757] Coverage v1.6.1
[f68482b8] Cthulhu v2.16.2
[31a5f54b] Debugger v0.7.10
[ab62b9b5] DeepDiffs v1.2.0
⌃ [fb4d412d] FixedPointDecimals v0.5.3
[c27321d9] Glob v1.3.1
[92ed2492] HeapSnapshotUtils v0.1.0 `https://github.com/RelationalAI/HeapSnapshotUtils.jl#main`
[7ec9b9c5] Humanize v1.0.0
⌃ [5903a43b] Infiltrator v1.8.3
[70703baa] JuliaSyntax v0.4.10
[1fcbbee2] LookingGlass v0.3.3 `~/.julia/dev/LookingGlass`
[bdcacae8] LoopVectorization v0.12.171
[1914dd2f] MacroTools v0.5.15
[85b6ec6f] MethodAnalysis v0.4.13
⌃ [e4faabce] PProf v3.1.3
⌃ [14b8a8f1] PkgTemplates v0.7.52
⌃ [c46f51b8] ProfileView v1.8.0
[92933f4c] ProgressMeter v1.10.2
[9c30249a] RAI v0.2.9
[817f1d60] ReTestItems v1.29.0
⌃ [295af30f] Revise v3.7.1
[aa65fe97] SnoopCompile v3.0.2 `~/work/jl_depots/raicode2/dev/SnoopCompile`
[e2b509da] SnoopCompileCore v3.0.0 `~/.julia/dev/SnoopCompile/SnoopCompileCore`
[ac92255e] Speculator v0.2.0
[1e6cf692] TestEnv v1.102.0 `~/work/jl_depots/raicode2/dev/TestEnv`
⌃ [e689c965] Tracy v0.1.3
Info Packages marked with ⌃ have new versions available and may be upgradable.
(@v1.10) pkg> add MacroTools
julia> Revise.includet("Onions/src/cthluhu-mre.jl")
julia> @descend cmp(RelNumber(1), RelNumber(2))
cmp(a::RelNumber, b::RelNumber) @ Main ~/Documents/play/rel-interpreter/Onions/src/cthluhu-mre.jl:222
222 function Base.cmp::Core.Const(cmp)(a::RelNumber::RelNumber, b::RelNumber::RelNumber)::Int64
223 return peel(b::RelNumber)::Int64 do bv; cmp_inner(a, bv) ; end
224 end
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [w]arn, [h]ide type-stable statements, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native, [j]ump to source always.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
• peel(b::RelNumber)
↩
ERROR: KeyError: key Symbol("#53#T") not found
Stacktrace:
[1] getindex
@ ./dict.jl:498 [inlined]
[2] map_ssas_to_source(src::Core.CodeInfo, mi::Core.MethodInstance, rootnode::JuliaSyntax.SyntaxNode, Δline::Int64)
@ TypedSyntax ~/.julia/packages/TypedSyntax/eS4sW/src/node.jl:816
[3] tsn_and_mappings(mi::Core.MethodInstance, src::Core.CodeInfo, rt::Any, sourcetext::SubString{…}, lineno::Int64; warn::Bool, strip_macros::Bool, kwargs::@Kwargs{})
@ TypedSyntax ~/.julia/packages/TypedSyntax/eS4sW/src/node.jl:54
[4] tsn_and_mappings(mi::Core.MethodInstance, src::Core.CodeInfo, rt::Any; warn::Bool, strip_macros::Bool, kwargs::@Kwargs{})
@ TypedSyntax ~/.julia/packages/TypedSyntax/eS4sW/src/node.jl:39
[5] tsn_and_mappings
@ ~/.julia/packages/TypedSyntax/eS4sW/src/node.jl:32 [inlined]
[6] #get_typed_sourcetext#23
@ ~/.julia/packages/Cthulhu/dysgf/src/reflection.jl:377 [inlined]
[7] get_typed_sourcetext
@ ~/.julia/packages/Cthulhu/dysgf/src/reflection.jl:376 [inlined]
[8] find_callsites(interp::Cthulhu.CthulhuInterpreter, CI::Core.CodeInfo, stmt_infos::Vector{…}, mi::Core.MethodInstance, slottypes::Vector{…}, optimize::Bool, annotate_source::Bool, pc2excts::Nothing)
@ Cthulhu ~/.julia/packages/Cthulhu/dysgf/src/reflection.jl:33
[9]
@ Cthulhu ~/.julia/packages/Cthulhu/dysgf/src/Cthulhu.jl:571
[10]
@ Cthulhu ~/.julia/packages/Cthulhu/dysgf/src/Cthulhu.jl:722
[11] _descend
@ ~/.julia/packages/Cthulhu/dysgf/src/Cthulhu.jl:472 [inlined]
[12] _descend
@ ~/.julia/packages/Cthulhu/dysgf/src/Cthulhu.jl:875 [inlined]
[13] #_descend#128
@ ~/.julia/packages/Cthulhu/dysgf/src/Cthulhu.jl:891 [inlined]
[14] __descend_with_error_handling(args::Any; terminal::Any, kwargs...)
@ Cthulhu ~/.julia/packages/Cthulhu/dysgf/src/Cthulhu.jl:275
[15] _descend_with_error_handling(f::Any, argtypes::Any; kwargs::@Kwargs{iswarn::Bool})
@ Cthulhu ~/.julia/packages/Cthulhu/dysgf/src/Cthulhu.jl:264
[16] descend(::Any, ::Vararg{Any}; kwargs::@Kwargs{})
@ Cthulhu ~/.julia/packages/Cthulhu/dysgf/src/Cthulhu.jl:318
[17] top-level scope
@ REPL[6]:1
Some type information was truncated. Use `show(err)` to see complete types. Whereas on 1.11, this works fine: julia> @descend cmp(RelNumber(1), RelNumber(2))
cmp(a::RelNumber, b::RelNumber) @ Main ~/Documents/play/rel-interpreter/Onions/src/cthluhu-mre.jl:222
222 function Base.cmp::Core.Const(cmp)(a::RelNumber::RelNumber, b::RelNumber::RelNumber)::Int64
223 return peel(b::RelNumber)::Int64 do bv; cmp_inner(a, bv) ; end
224 end
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [w]arn, [h]ide type-stable statements, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native, [j]ump to source always.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
• peel(b::RelNumber)
↩
peel(func::var"#120#F", x::var"#53#T") where {var"#120#F", var"#53#T"<:RelNumber} @ Main ~/Documents/play/rel-interpreter/Onions/src/cthluhu-mre.jl:108
108 function (Onions.peel(
109 func::var"#10#11"{RelNumber}::F,
110 x::RelNumber::T
111 ) where {F, T<:$(esc(namify(T)))})::Int64
112 tag::UInt8 = getfield(x::RelNumber, :tag)::UInt8
113 return $(ifelse(
114 [(:(tag === $(UInt8(i))), :(func(unsafe_getproperty(x, Val($(QuoteNode(f)))))))
115 for (i, f) in enumerate(namify.(fields))],
116 # It is _super_ perf-sensitive to outline the assertion-failure here.
117 # From 35μs to 5μs for peel benchmark. In any case, this is expected to
118 # be unreachable for a well-formed union instance.
119 :(tag_not_found(T, tag::UInt8)::Bool)
120 ))
121 end
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [w]arn, [h]ide type-stable statements, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native, [j]ump to source always.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
• %9 = < concrete eval > Val(::Core.Const(:i8))::Core.Const(Val{:i8}())
%10 = unsafe_getproperty(::RelNumber,::Val{:i8})::Int8
%11 = #10(::Int8)::Int64
%19 = < concrete eval > Val(::Core.Const(:i16))::Core.Const(Val{:i16}())
%20 = unsafe_getproperty(::RelNumber,::Val{:i16})::Int16
%21 = #10(::Int16)::Int64
%29 = < concrete eval > Val(::Core.Const(:i32))::Core.Const(Val{:i32}())
%30 = unsafe_getproperty(::RelNumber,::Val{:i32})::Int32
%31 = #10(::Int32)::Int64
v %39 = < concrete eval > Val(::Core.Const(:i64))::Core.Const(Val{:i64}())
(@v1.11) pkg> st
Status `~/.julia/environments/v1.11/Project.toml`
[6e4b80f9] BenchmarkTools v1.6.0
⌃ [f68482b8] Cthulhu v2.16.1
[31a5f54b] Debugger v0.7.10
[1914dd2f] MacroTools v0.5.15
⌃ [e4faabce] PProf v3.1.3
[817f1d60] ReTestItems v1.29.0
[295af30f] Revise v3.7.2
Info Packages marked with ⌃ have new versions available and may be upgradable. MRE file for the above: module Onions
export @union
isonion(::Type) = false
using MacroTools
using MacroTools: @capture, @q
function fieldtype(ex)
@capture(ex, _::T_ | _)
return something(T, Any)
end
params(ex) = isexpr(ex, :curly) ? ex.args[2:end] : []
function freetypevars(ex)
if isexpr(ex, Symbol)
[ex]
elseif !isexpr(ex)
[]
elseif isexpr(ex, :(.))
freetypevars(ex.args[1])
elseif isexpr(ex, :curly, :tuple)
reduce(vcat, freetypevars.(ex.args))
else
error("unrecognised type expression $ex")
end
end
function ifelse(clauses, default=nothing)
return foldr(((cond, body), els) -> Expr(:if, cond, body, els), clauses; init=default)
end
@noinline throw_not_set(::Type{T}, f) where {T} =
error("Field $f is not active for type $(T)")
@noinline tag_not_found(::Type{T}, tag) where {T} =
error("Malformed instance of union type $(T): Unexpected tag value: $(tag)")
function field end
function fields end
function fieldidx end
function unsafe_getproperty end
function _ueq end
# Peel the field with the given type. Implemented by the user.
# E.g. peel_as(Int, x) gets the Int field of x
# TODO (azreika): bit of a hack to make migration smoother
function peel_as end
macro union(ex)
@capture(ex, struct T_ <: ParentType_
fields__
end | struct T_
fields__
end) || error("@union struct ...")
types = Dict(namify(f) => fieldtype(f) for f in fields)
fields = namify.(fields)
if isnothing(ParentType)
ParentType = Any
end
@assert length(fields) >= 1 || error("Union must have at least one field")
forbidden = [namify(T), namify.(params(T))...]
unboxed = filter(x -> isdisjoint(freetypevars(types[x]), forbidden), fields)
type = @q struct $(esc(T)) <: $(esc(ParentType))
tag::UInt8
bits::Storage
ptrs::P($(esc(namify(T))), $(esc.(params(T))...))
$([
@q function $(esc(T))(::Val{$(QuoteNode(f))}, value) where {$(esc.(params(T))...)}
f_val = convert($(esc(types[f])), value)
if $(f in unboxed) && isbitstype($(esc(types[f])))
new($(UInt8(i)), f_val, nothing)
else
new($(UInt8(i)), nothing, f_val)
end
end
for (i, f) in enumerate(fields)
]...)
end
:(let
types = Dict($([:($(QuoteNode(f)) => $(esc(types[f]))) for f in unboxed]...))
unboxed = [f for (f, T) in types if isbitstype(T)]
Storage = Union{Nothing, [types[f] for f in unboxed]...}
P($(esc(namify(T))), $(esc.(params(T))...)) = Union{Nothing,$([:($(QuoteNode(f)) in unboxed ? Union{} : $(esc(types[f]))) for f in fields]...)}
$type
$(esc(T))(; kw...) where {$(esc.(params(T))...)} = $(esc(T))(Val(only(kw)[1]), only(kw)[2])
Onions.isonion(::Type{<:$(esc(namify(T)))}) = true
Onions.fields(x::$(esc(T))) where {$(esc.(params(T))...)} = ($(QuoteNode.(fields)...),)
Onions.fieldidx(::Type{<:$(esc(T))}, f::Symbol) where {$(esc.(params(T))...)} =
# NOTE: This lookup in the NamedTuple compiles away when f is const-propped in
# getproperty, and it's a constant-time lookup if it's dynamic.
getfield(($([:($f = $(UInt8(i))) for (i, f) in enumerate(namify.(fields))]...),), f)
$([
:(function Onions.unsafe_getproperty(x::$(esc(T)), ::Val{$(QuoteNode(f))}) where {$(esc.(params(T))...)}
$(if f in unboxed
:(if isbitstype($(esc(types[f])))
return getfield(x, :bits)::$(esc(types[f]))
end)
end)
getfield(x, :ptrs)::$(esc(types[f]))
end)
for f in fields
]...)
# NOTE: Even though the following two functions share most of their implementation,
# for some reason julia doesn't infer them well if you try to factor out a shared
# impl. So we duplicate the code here a touch.
function Onions.peel(
func::F,
x::T
) where {F, T<:$(esc(namify(T)))}
tag = getfield(x, :tag)
return $(ifelse(
[(:(tag === $(UInt8(i))), :(func(unsafe_getproperty(x, Val($(QuoteNode(f)))))))
for (i, f) in enumerate(namify.(fields))],
# It is _super_ perf-sensitive to outline the assertion-failure here.
# From 35μs to 5μs for peel benchmark. In any case, this is expected to
# be unreachable for a well-formed union instance.
:(tag_not_found(T, tag))
))
end
function Onions._ueq(a::T, b::T) where {T<:$(esc(namify(T)))}
getfield(a, :tag) == getfield(b, :tag) || return false
tag = getfield(a, :tag)
return $(ifelse(
[(:(tag === $(UInt8(i))), :(
f = Val($(QuoteNode(f)));
unsafe_getproperty(a, f) == unsafe_getproperty(b, f)
))
for (i, f) in enumerate(namify.(fields))],
# It is _super_ perf-sensitive to outline the assertion-failure here.
# From 35μs to 5μs for peel benchmark. In any case, this is expected to
# be unreachable for a well-formed union instance.
:(tag_not_found(T, tag))
))
end
function Base.getproperty(x::$(esc(T)), f::Symbol) where {$(esc.(params(T))...)}
# Comparing ints is cheaper than looking up the symbol for the tag
fieldidx(typeof(x), f) == getfield(x, :tag) ||
Onions.throw_not_set(typeof(x), f)
return unsafe_getproperty(x, Val(f))
end
Base.:(==)(a::$(esc(namify(T))), b::$(esc(namify(T)))) = ueq(a, b)
function Base.show_default(io::IO, x::$(esc(T))) where {$(esc.(params(T))...)}
show(io, typeof(x))
print(io, "($(field(x)) = ")
show(io, peel(x))
print(io, ")")
return
end
nothing
end)
end
function aligned_type(align)
if align == 1
UInt8
elseif align == 2
UInt16
elseif align == 4
UInt32
elseif align == 8
UInt64
elseif align == 16
UInt128
else
error("Unsupported alignment: $align")
end
end
peel(x) = peel(identity, x)
# User-overridable endpoint for implementing custom `==` for `@union` types.
ueq(a::T, b::T) where T = _ueq(a, b)
field(x) = fields(x)[getfield(x, :tag)]
function isfield(x, f)
@assert f in fields(x)
return field(x) === f
end
end # module Onions
using .Onions
using .Onions: peel, field, isfield
@union struct RelNumber
i8::Int8
i16::Int16
i32::Int32
i64::Int64
u8::UInt8
u16::UInt16
u32::UInt32
u64::UInt64
f16::Float16
f32::Float32
f64::Float64
end
RelNumber(x::Int8) = RelNumber(i8=x)
RelNumber(x::Int16) = RelNumber(i16=x)
RelNumber(x::Int32) = RelNumber(i32=x)
RelNumber(x::Int64) = RelNumber(i64=x)
RelNumber(x::UInt8) = RelNumber(u8=x)
RelNumber(x::UInt16) = RelNumber(u16=x)
RelNumber(x::UInt32) = RelNumber(u32=x)
RelNumber(x::UInt64) = RelNumber(u64=x)
RelNumber(x::Float16) = RelNumber(f16=x)
RelNumber(x::Float32) = RelNumber(f32=x)
RelNumber(x::Float64) = RelNumber(f64=x)
Base.:(<)(a::RelNumber, b::RelNumber) = cmp(a, b) == -1
Base.isless(a::RelNumber, b::RelNumber) = <(a,b)
function Base.cmp(a::RelNumber, b::RelNumber)
return peel(b) do bv; cmp_inner(a, bv) ; end
end
@noinline cmp_inner(a::RelNumber, bv) = peel(a) do av; cmp(av, bv) ; end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
bug
Something isn't working
TypedSyntax
An issue or pull request relating to the TypedSyntax.jl subpackage
The text was updated successfully, but these errors were encountered: