Skip to content

Commit 75951ec

Browse files
authored
lowering: Recognize argument destructuring inside macro hygiene (#54702)
Fixes #54701
1 parent b1e5a86 commit 75951ec

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

src/macroexpand.scm

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -229,30 +229,26 @@
229229
lst)))
230230

231231
;; get the name from a function formal argument expression, allowing `(escape x)`
232-
(define (try-arg-name v)
233-
(cond ((symbol? v) (list v))
232+
(define (try-arg-name v (escaped #f))
233+
(cond ((symbol? v) (if escaped '() (list v)))
234234
((atom? v) '())
235235
(else
236236
(case (car v)
237-
((|::|) (if (length= v 2) '() (try-arg-name (cadr v))))
238-
((... kw =) (try-arg-name (cadr v)))
239-
((escape) (list v))
240-
((hygienic-scope) (try-arg-name (cadr v)))
237+
((|::|) (if (length= v 2) '() (try-arg-name (cadr v) escaped)))
238+
((... kw =) (try-arg-name (cadr v) escaped))
239+
((escape) (if escaped (list (cadr v)) '()))
240+
((hygienic-scope) (try-arg-name (cadr v) escaped))
241+
((tuple) (apply nconc (map (lambda (e) (try-arg-name e escaped)) (cdr v))))
241242
((meta) ;; allow certain per-argument annotations
242243
(if (nospecialize-meta? v #t)
243-
(try-arg-name (caddr v))
244+
(try-arg-name (caddr v) escaped)
244245
'()))
245246
(else '())))))
246247

247248
;; get names from a formal argument list, specifying whether to include escaped ones
248249
(define (safe-arg-names lst (escaped #f))
249250
(apply nconc
250-
(map (lambda (v)
251-
(let ((vv (try-arg-name v)))
252-
(if (eq? escaped (and (pair? vv) (pair? (car vv)) (eq? (caar vv) 'escape)))
253-
(if escaped (list (cadar vv)) vv)
254-
'())))
255-
lst)))
251+
(map (lambda (v) (try-arg-name v escaped)) lst)))
256252

257253
;; arg names, looking only at positional args
258254
(define (safe-llist-positional-args lst (escaped #f))

test/syntax.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3683,3 +3683,19 @@ end
36833683
# Issue #53729 - Lowering recursion into Expr(:toplevel)
36843684
@test eval(Expr(:let, Expr(:block), Expr(:block, Expr(:toplevel, :(f53729(x) = x)), :(x=1)))) == 1
36853685
@test f53729(2) == 2
3686+
3687+
# Issue #54701 - Macro hygiene of argument destructuring
3688+
macro makef54701()
3689+
quote
3690+
call(f) = f((1, 2))
3691+
function $(esc(:f54701))()
3692+
call() do (a54701, b54701)
3693+
return a54701+b54701
3694+
end
3695+
end
3696+
end
3697+
end
3698+
@makef54701
3699+
@test f54701() == 3
3700+
@test !@isdefined(a54701)
3701+
@test !@isdefined(b54701)

0 commit comments

Comments
 (0)