diff --git a/src/ast.scm b/src/ast.scm index 005afb4647f5f..bc8d847279fc9 100644 --- a/src/ast.scm +++ b/src/ast.scm @@ -319,7 +319,7 @@ (bad-formal-argument v)) (else (case (car v) - ((... kw) + ((...) (arg-name (cadr v)) ;; to check for errors (decl-var (cadr v))) ((|::|) @@ -330,6 +330,8 @@ (if (nospecialize-meta? v #t) (arg-name (caddr v)) (bad-formal-argument v))) + ((kw) + (arg-name (cadr v))) (else (bad-formal-argument v)))))) (define (arg-type v) @@ -349,6 +351,8 @@ (if (nospecialize-meta? v #t) (arg-type (caddr v)) (bad-formal-argument v))) + ((kw) + (arg-type (cadr v))) (else (bad-formal-argument v)))))) ;; convert a lambda list into a list of just symbols diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index d80c6a5052c85..420eeaf51f747 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -442,9 +442,12 @@ ;; 1-element list of vararg argument, or empty if none (vararg (let* ((l (if (null? pargl) '() (last pargl))) ;; handle vararg with default value - (l (if (kwarg? l) (cadr l) l))) - (if (or (vararg? l) (varargexpr? l)) + (l- (if (kwarg? l) (cadr l) l))) + (if (or (vararg? l-) (varargexpr? l-)) (list l) '()))) + ;; expression to forward varargs to another call + (splatted-vararg (if (null? vararg) '() + (list `(... ,(arg-name (car vararg)))))) ;; positional args with vararg (pargl-all pargl) ;; positional args without vararg @@ -520,8 +523,7 @@ ,@(if ordered-defaults keynames vals) ,@(if (null? restkw) '() `((call (top pairs) (call (core NamedTuple))))) ,@(map arg-name pargl) - ,@(if (null? vararg) '() - (list `(... ,(arg-name (car vararg))))))))) + ,@splatted-vararg)))) (if ordered-defaults (scopenest keynames vals ret) ret)))) @@ -579,16 +581,13 @@ ,@(if (null? restkw) `((if (call (top isempty) ,rkw) (null) - (call (top kwerr) ,kw ,@(map arg-name pargl) - ,@(if (null? vararg) '() - (list `(... ,(arg-name (car vararg)))))))) + (call (top kwerr) ,kw ,@(map arg-name pargl) ,@splatted-vararg))) '()) (return (call ,mangled ;; finally, call the core function ,@keynames ,@(if (null? restkw) '() (list rkw)) ,@(map arg-name pargl) - ,@(if (null? vararg) '() - (list `(... ,(arg-name (car vararg))))))))))) + ,@splatted-vararg)))))) ;; return primary function ,(if (not (symbol? name)) '(null) name))))) diff --git a/test/keywordargs.jl b/test/keywordargs.jl index 348eaea2ee4c3..9cbae2b1a0b19 100644 --- a/test/keywordargs.jl +++ b/test/keywordargs.jl @@ -380,3 +380,10 @@ f40964(xs::Int...=1; k = 2) = (xs, k) @test f40964() === ((1,), 2) @test f40964(7, 8) === ((7,8), 2) @test f40964(7, 8, k=0) === ((7,8), 0) +# issue #41416 +@test f40964(; k = 1) === ((1,), 1) +f41416(a...="a"; b=true) = (b, a) +@test f41416() === (true, ("a",)) +@test f41416(;b=false) === (false, ("a",)) +@test f41416(33) === (true, (33,)) +@test f41416(3; b=false) === (false, (3,))