Skip to content

Commit 508d7ab

Browse files
authored
Respect namespace in method definitions (#443)
The symbol-lookup in `evaluate_methoddef` was not careful about avoiding extending methods in Base when the method was unqualified. Fixes timholy/Revise.jl#579
1 parent 15a0c6f commit 508d7ab

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

src/interpret.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,19 @@ function evaluate_methoddef(frame, node)
264264
f = node.args[1]
265265
if isa(f, Symbol)
266266
mod = moduleof(frame)
267-
f = isdefined(mod, f) ? getfield(mod, f) : Core.eval(moduleof(frame), Expr(:function, f)) # create a new function
267+
if Base.isbindingresolved(mod, f) && isdefined(mod, f) # `isdefined` accesses the binding, making it impossible to create a new one
268+
f = getfield(mod, f)
269+
else
270+
f = Core.eval(moduleof(frame), Expr(:function, f)) # create a new function
271+
end
272+
elseif isa(f, GlobalRef)
273+
f = getfield(f.mod, f.name)
268274
end
269275
length(node.args) == 1 && return f
270276
sig = @lookup(frame, node.args[2])::SimpleVector
271277
body = @lookup(frame, node.args[3])
272278
ccall(:jl_method_def, Cvoid, (Any, Any, Any), sig, body, moduleof(frame))
273-
return nothing
279+
return f
274280
end
275281

276282
function structname(frame, node)

test/toplevel.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,23 @@ module Toplevel end
235235
@test Toplevel.Testing.Frame === Frame
236236
end
237237

238+
# Proper handling of namespaces
239+
# https://github.com/timholy/Revise.jl/issues/579
240+
module Namespace end
241+
@testset "Namespace" begin
242+
frame = Frame(Namespace, :(sin(::Int) = 10))
243+
while true
244+
JuliaInterpreter.through_methoddef_or_done!(frame) === nothing && break
245+
end
246+
@test Namespace.sin(0) == 10
247+
if Base.VERSION >= v"1.5"
248+
@test Base.sin(0) == 0
249+
else
250+
@test_broken Base.sin(0) == 0
251+
Core.eval(Base, :(sin(x::Int) = sin(float(x)))) # fix the definition of `sin`
252+
end
253+
end
254+
238255
# incremental interpretation solves world-age problems
239256
# Taken straight from Julia's test/tuple.jl
240257
module IncTest

0 commit comments

Comments
 (0)