Skip to content

Commit a48e9df

Browse files
committed
Add error for global methods inside function scope
1 parent 54d3dff commit a48e9df

File tree

3 files changed

+43
-17
lines changed

3 files changed

+43
-17
lines changed

src/scope_analysis.jl

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,19 @@ function _resolve_scopes(ctx, ex::SyntaxTree)
539539
throw(LoweringError(ex, "Unknown syntax assertion"))
540540
end
541541
makeleaf(ctx, ex, K"TOMBSTONE")
542+
elseif k == K"function_decl"
543+
resolved = mapchildren(e->_resolve_scopes(ctx, e), ctx, ex)
544+
name = resolved[1]
545+
if kind(name) == K"BindingId"
546+
bk = lookup_binding(ctx, name).kind
547+
if bk == :argument
548+
throw(LoweringError(name, "Cannot add method to a function argument"))
549+
elseif bk == :global && !ctx.scope_stack[end].in_toplevel_thunk
550+
throw(LoweringError(name,
551+
"Global method definition needs to be placed at the top level, or use `eval()`"))
552+
end
553+
end
554+
resolved
542555
elseif k == K"const_if_global"
543556
id = _resolve_scopes(ctx, ex[1])
544557
if lookup_binding(ctx, id).kind == :global
@@ -630,9 +643,6 @@ function analyze_variables!(ctx, ex)
630643
analyze_variables!(ctx, ex[2])
631644
elseif k == K"function_decl"
632645
name = ex[1]
633-
if kind(name) == K"BindingId" && lookup_binding(ctx, name).kind == :argument
634-
throw(LoweringError(name, "Cannot add method to a function argument"))
635-
end
636646
if lookup_binding(ctx, name.var_id).kind === :local
637647
init_closure_bindings!(ctx, name)
638648
end

test/closures_ir.jl

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -422,20 +422,6 @@ end
422422
18 (call core.kwcall %%%₁₆ %₁₇)
423423
19 (return %₁₈)
424424

425-
########################################
426-
# Error: Attempt to add methods to a function argument
427-
function f(g)
428-
function g()
429-
end
430-
end
431-
#---------------------
432-
LoweringError:
433-
function f(g)
434-
function g()
435-
# ╙ ── Cannot add method to a function argument
436-
end
437-
end
438-
439425
########################################
440426
# Error: Static parameter clashing with closure name
441427
function f(::g) where {g}

test/scopes_ir.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,36 @@ function f(::T) where T
379379
end
380380
end
381381

382+
########################################
383+
# Error: Attempt to add methods to a function argument
384+
function f(g)
385+
function g()
386+
end
387+
end
388+
#---------------------
389+
LoweringError:
390+
function f(g)
391+
function g()
392+
# ╙ ── Cannot add method to a function argument
393+
end
394+
end
395+
396+
########################################
397+
# Error: Global method definition inside function scope
398+
function f()
399+
global global_method
400+
function global_method()
401+
end
402+
end
403+
#---------------------
404+
LoweringError:
405+
function f()
406+
global global_method
407+
function global_method()
408+
# └───────────┘ ── Global method definition needs to be placed at the top level, or use `eval()`
409+
end
410+
end
411+
382412
########################################
383413
# @isdefined with defined variables
384414
let x = 1

0 commit comments

Comments
 (0)