Skip to content

Commit 80650d0

Browse files
committed
lowering: Plumb through arg destructuring code into all wrapper functions
In case the default argument of some other argument makes use of the destructured argument. Fixes #53832.
1 parent cd523fe commit 80650d0

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

src/julia-syntax.scm

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@
337337

338338
;; construct the (method ...) expression for one primitive method definition,
339339
;; assuming optional and keyword args are already handled
340-
(define (method-def-expr- name sparams argl body (rett '(core Any)))
340+
(define (method-def-expr- name sparams argl argl-stmts body (rett '(core Any)))
341341
(if
342342
(any kwarg? argl)
343343
;; has optional positional args
@@ -356,7 +356,7 @@
356356
(dfl (map caddr kws)))
357357
(receive
358358
(vararg req) (separate vararg? argl)
359-
(optional-positional-defs name sparams req opt dfl body
359+
(optional-positional-defs name sparams req opt dfl argl-stmts body
360360
(append req opt vararg) rett)))))
361361
;; no optional positional args
362362
(let* ((names (map car sparams))
@@ -442,7 +442,7 @@
442442
,@(map make-assignment names vals)
443443
,expr))
444444

445-
(define (keywords-method-def-expr name sparams argl body rett)
445+
(define (keywords-method-def-expr name sparams argl argl-stmts body rett)
446446
(let* ((kargl (cdar argl)) ;; keyword expressions (= k v)
447447
(annotations (map (lambda (a) `(meta ,(cadr a) ,(arg-name (cadr (caddr a)))))
448448
(filter nospecialize-meta? kargl)))
@@ -530,6 +530,7 @@
530530
;; strip type off function self argument if not needed for a static param.
531531
;; then it is ok for cl-convert to move this definition above the original def.
532532
,@not-optional ,@vararg)
533+
argl-stmts
533534
(insert-after-meta `(block
534535
,@stmts)
535536
(cons `(meta nkw ,(+ (length vars) (length restkw)))
@@ -538,9 +539,10 @@
538539

539540
;; call with no keyword args
540541
,(method-def-expr-
541-
name positional-sparams pargl-all
542+
name positional-sparams pargl-all argl-stmts
542543
`(block
543544
,@(keep-first linenum? (without-generated prologue))
545+
,@argl-stmts
544546
,(let (;; call mangled(vals..., [rest_kw,] pargs..., [vararg]...)
545547
(ret `(return (call ,mangled
546548
,@(if ordered-defaults keynames vals)
@@ -558,6 +560,7 @@
558560
;; if there are optional positional args, we need to be able to reference the function name
559561
,(if (any kwarg? `(,@pargl ,@vararg)) (gensy) UNUSED)
560562
(call (core kwftype) ,ftype)) ,kwdecl ,@pargl ,@vararg)
563+
argl-stmts
561564
`(block
562565
;; propagate method metadata to keyword sorter
563566
,@(map propagate-method-meta (filter meta? prologue))
@@ -571,6 +574,7 @@
571574
`(meta ,(cadr m) ,@(filter (lambda (v) (not (memq v keynames)))
572575
(cddr m))))
573576
(filter nospecialize-meta? prologue))
577+
,@argl-stmts
574578
;; If not using slots for the keyword argument values, still declare them
575579
;; for reflection purposes.
576580
,@(if ssa-keyvars?
@@ -655,7 +659,7 @@
655659
(else
656660
(loop filtered (cdr params))))))
657661

658-
(define (optional-positional-defs name sparams req opt dfl body overall-argl rett)
662+
(define (optional-positional-defs name sparams req opt dfl argl-stmts body overall-argl rett)
659663
(let ((prologue (without-generated (extract-method-prologue body))))
660664
`(block
661665
,@(map (lambda (n)
@@ -683,14 +687,16 @@
683687
;; then add only one next argument
684688
`(block
685689
,@prologue
690+
,@argl-stmts
686691
(call ,(arg-name (car req)) ,@(map arg-name (cdr passed)) ,(car vals)))
687692
;; otherwise add all
688693
`(block
689694
,@prologue
695+
,@argl-stmts
690696
(call ,(arg-name (car req)) ,@(map arg-name (cdr passed)) ,@vals))))))
691-
(method-def-expr- name sp passed body)))
697+
(method-def-expr- name sp passed argl-stmts body)))
692698
(iota (length opt)))
693-
,(method-def-expr- name sparams overall-argl body rett))))
699+
,(method-def-expr- name sparams overall-argl argl-stmts body rett))))
694700

695701
;; strip empty (parameters ...), normalizing `f(x;)` to `f(x)`.
696702
(define (remove-empty-parameters argl)
@@ -729,14 +735,14 @@
729735
;; definitions without keyword arguments are passed to method-def-expr-,
730736
;; which handles optional positional arguments by adding the needed small
731737
;; boilerplate definitions.
732-
(define (method-def-expr name sparams argl body rett)
738+
(define (method-def-expr name sparams argl argl-stmts body rett)
733739
(let ((argl (throw-unassigned-kw-args (remove-empty-parameters argl))))
734740
(if (has-parameters? argl)
735741
;; has keywords
736742
(begin (check-kw-args (cdar argl))
737-
(keywords-method-def-expr name sparams argl body rett))
743+
(keywords-method-def-expr name sparams argl argl-stmts body rett))
738744
;; no keywords
739-
(method-def-expr- name sparams argl body rett))))
745+
(method-def-expr- name sparams argl argl-stmts body rett))))
740746

741747
(define (struct-def-expr name params super fields mut)
742748
(receive
@@ -1236,7 +1242,7 @@
12361242
(name (if (or (decl? name) (and (pair? name) (memq (car name) '(curly where))))
12371243
#f name)))
12381244
(expand-forms
1239-
(method-def-expr name sparams argl body rett))))
1245+
(method-def-expr name sparams argl (cdr argl-stmts) body rett))))
12401246
(else
12411247
(error (string "invalid assignment location \"" (deparse name) "\""))))))
12421248

test/syntax.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3683,3 +3683,10 @@ 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 #53832 - interaction of arg destructuring and wrappers
3688+
f53832((a, b), c=a) = (a, b, c)
3689+
@test f53832((1,2)) == (1,2,1)
3690+
3691+
g53832((a, b); c=a) = (a, b, c)
3692+
@test g53832((1,2)) == (1,2,1)

0 commit comments

Comments
 (0)