Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lowering: Disallow splatting in non-final default value #50563

Merged
merged 4 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,10 @@
(vals (list-tail dfl n))
(absent (list-tail opt n)) ;; absent arguments
(body
(if (any (lambda (defaultv)
(if (any vararg? (butlast vals))
;; Forbid splat in all but the final default value
(error "invalid \"...\" in non-final positional argument default value")
(if (any (lambda (defaultv)
;; does any default val expression...
(contains (lambda (e)
;; contain "e" such that...
Expand All @@ -681,7 +684,7 @@
;; otherwise add all
`(block
,@prologue
(call ,(arg-name (car req)) ,@(map arg-name (cdr passed)) ,@vals)))))
(call ,(arg-name (car req)) ,@(map arg-name (cdr passed)) ,@vals))))))
(method-def-expr- name sp passed body)))
(iota (length opt)))
,(method-def-expr- name sparams overall-argl body rett))))
Expand Down
20 changes: 20 additions & 0 deletions test/syntax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3508,6 +3508,26 @@ let x = 1 => 2
@test_throws "function Base.=> must be explicitly imported to be extended" @eval a => b = 2
end

# Splatting in non-final default value (Ref #50518)
for expr in (quote
function g1(a=(1,2)..., b...=3)
b
end
end,quote
function g2(a=(1,2)..., b=3, c=4)
(b, c)
end
end,quote
function g3(a=(1,2)..., b=3, c...=4)
(b, c)
end
end)
let exc = try eval(expr); catch exc; exc end
@test isa(exc, ErrorException)
@test startswith(exc.msg, "syntax: invalid \"...\" in non-final positional argument default value")
end
end

# Test that bad lowering does not segfault (ref #50518)
@test_throws ErrorException("syntax: Attempted to use slot marked unused") @eval function funused50518(::Float64)
$(Symbol("#unused#"))
Expand Down