Skip to content

Commit 7bfc2ec

Browse files
authored
fix identification of argument occurrences in optional arg defaults (#59205)
If an optional argument default depends on a previous argument, we need to pass the arguments one by one, otherwise we can pass them all at once. This fixes a bug in that logic that counted quoted symbols as argument occurrences. Arguably, internal calls done for the purpose of passing default values should use `invoke` to make sure only the originally selected method body can be called, instead of one of the intermediate calls getting intercepted by a shorter signature with more specific types. But that is a bit tricky to implement, and is a more significant change, while the behavior fixed by this PR is clearly not intended, so I think we can leave it like this for now.
1 parent c734b62 commit 7bfc2ec

File tree

2 files changed

+28
-22
lines changed

2 files changed

+28
-22
lines changed

src/julia-syntax.scm

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -684,28 +684,27 @@
684684
(absent (list-tail opt n)) ;; absent arguments
685685
(body
686686
(if (any vararg? (butlast vals))
687-
;; Forbid splat in all but the final default value
688-
(error "invalid \"...\" in non-final positional argument default value")
689-
(if (any (lambda (defaultv)
690-
;; does any default val expression...
691-
(contains (lambda (e)
692-
;; contain "e" such that...
693-
(any (lambda (a)
694-
;; "e" is in an absent arg
695-
(contains (lambda (u)
696-
(eq? u e))
697-
a))
698-
absent))
699-
defaultv))
700-
vals)
701-
;; then add only one next argument
702-
`(block
703-
,@prologue
704-
(call ,(arg-name (car req)) ,@(map arg-name (cdr passed)) ,(car vals)))
705-
;; otherwise add all
706-
`(block
707-
,@prologue
708-
(call ,(arg-name (car req)) ,@(map arg-name (cdr passed)) ,@vals))))))
687+
;; Forbid splat in all but the final default value
688+
(error "invalid \"...\" in non-final positional argument default value")
689+
(if (any (lambda (defaultv)
690+
;; does any default val expression...
691+
(expr-contains-p
692+
(lambda (e)
693+
;; contain "e" such that...
694+
(any (lambda (a)
695+
;; "e" is in an absent arg
696+
(expr-contains-eq e a))
697+
absent))
698+
defaultv))
699+
vals)
700+
;; then add only one next argument
701+
`(block
702+
,@prologue
703+
(call ,(arg-name (car req)) ,@(map arg-name (cdr passed)) ,(car vals)))
704+
;; otherwise add all
705+
`(block
706+
,@prologue
707+
(call ,(arg-name (car req)) ,@(map arg-name (cdr passed)) ,@vals))))))
709708
(method-def-expr- name sp passed body)))
710709
(iota (length opt)))
711710
,(method-def-expr- name sparams overall-argl body rett))))

test/syntax.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4548,3 +4548,10 @@ end
45484548
)
45494549
end
45504550
end
4551+
4552+
let d = Dict(:a=>1)
4553+
# quoted symbols should not be recognized as argument uses
4554+
foo(a=d[:a], b=d[:a]) = 1
4555+
foo(a::Int) = 2
4556+
@test foo() == 1
4557+
end

0 commit comments

Comments
 (0)