From c35465b376d6a127e0f8c4179a49c51a5a3bc4f6 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 1 Jun 2026 03:36:18 -0500 Subject: [PATCH] Treat a quoted Symbol callee as a name in normalize_defsig In buggy user code, function f(list) m = zeros(3, 3) m[:, :length(list)] end the intended call `length(list)` is a Symbol instead of a function. This caused `normalize_defsig` to throw, and led to a Revise bug, timholy/Revise.jl#914. A bare Symbol has no `nameof` method, so walking the body threw `MethodError: no method matching nameof(::Symbol)` and aborted `includet`. A quoted Symbol is already a name, so use it directly and reserve `nameof` for QuoteNodes wrapping functions, types, or modules. With this, such code loads and instead fails at call time with the clear runtime error the user expects. This is the same behavior exhibited as if the code had been `include`d rather than `includet`ed, and this is the contract that `includet` should uphold. Fixes timholy/Revise.jl#914. Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 2 +- src/signatures.jl | 4 +++- test/signatures.jl | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 92b81e5..91c2a86 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "LoweredCodeUtils" uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" -version = "3.5.1" +version = "3.5.2" authors = ["Tim Holy "] [deps] diff --git a/src/signatures.jl b/src/signatures.jl index 6fe00ac..2746be8 100644 --- a/src/signatures.jl +++ b/src/signatures.jl @@ -242,7 +242,9 @@ end # try to normalize `def` to `GlobalRef` representation function normalize_defsig(@nospecialize(def), mod::Module) if def isa QuoteNode - def = nameof(def.value) + # A quoted Symbol (e.g. the callee of `:foo(x)`) is already a name; only + # other wrapped values (functions, types, modules) need `nameof`. + def = def.value isa Symbol ? def.value : nameof(def.value) end if def isa Symbol def = GlobalRef(mod, def) diff --git a/test/signatures.jl b/test/signatures.jl index 082e72c..5e02174 100644 --- a/test/signatures.jl +++ b/test/signatures.jl @@ -538,4 +538,19 @@ end LoweredCodeUtils.identify_framemethod_calls(frame) # make sure this does not throw end +@testset "normalize_defsig with a quoted Symbol callee (issue Revise#914)" begin + # A quoted Symbol is already a name and must not be passed to `nameof`. + @test LoweredCodeUtils.normalize_defsig(QuoteNode(:length), Main) === GlobalRef(Main, :length) + + # A method body containing a call to a quoted symbol, e.g. `:length(list)`, + # lowers to a `:call` whose callee is `QuoteNode(:length)`. Walking it must + # not throw. + ex = :(function f_rvs914(list) + m = zeros(3, 3) + m[:, :length(list)] + end) + frame = Frame(Main, ex) + @test LoweredCodeUtils.identify_framemethod_calls(frame) isa Any # must not throw +end + end # module signatures