Skip to content

Commit b06d260

Browse files
authored
Allow underscore (unused) args in presence of kwargs (#58803)
Admittedly fixed because I thought I introduced this bug recently, but actually, fix #32727. `f(_; kw) = 1` should now lower in a similar way to `f(::Any; kw) = 1`, where we use a gensym for the first argument. Not in this PR, but TODO: `nospecialize` underscore-only names
1 parent a48dcad commit b06d260

File tree

2 files changed

+14
-9
lines changed

2 files changed

+14
-9
lines changed

src/julia-syntax.scm

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33

44
;; pass 1: syntax desugaring
55

6-
;; allow (:: T) => (:: #gensym T) in formal argument lists
6+
;; unnamed or all-underscore arguments may still be read from internally, so
7+
;; convert (:: T) => (:: #gensym T) and _ => #gensym in formal argument lists
78
(define (fill-missing-argname a unused)
8-
(if (and (pair? a) (eq? (car a) '|::|) (null? (cddr a)))
9-
`(|::| ,(if unused UNUSED (gensy)) ,(cadr a))
10-
a))
9+
(define (replace-if-underscore u)
10+
(if (underscore-symbol? u) (if unused UNUSED (gensy)) u))
11+
(if (and (pair? a) (eq? (car a) '|::|))
12+
(cond ((null? (cddr a)) `(|::| ,(if unused UNUSED (gensy)) ,(cadr a)))
13+
((null? (cdddr a)) `(|::| ,(replace-if-underscore (cadr a)) ,(caddr a)))
14+
(else a))
15+
(replace-if-underscore a)))
1116
(define (fix-arglist l (unused #t))
1217
(if (any vararg? (butlast l))
1318
(error "invalid \"...\" on non-final argument"))
@@ -165,10 +170,7 @@
165170
;; GF method does not need to keep decl expressions on lambda args
166171
;; except for rest arg
167172
(define (method-lambda-expr argl body rett)
168-
(let ((argl (map (lambda (x)
169-
(let ((n (arg-name x)))
170-
(if (underscore-symbol? n) UNUSED n)))
171-
argl))
173+
(let ((argl (map arg-name argl))
172174
(body (blockify body)))
173175
`(lambda ,argl ()
174176
(scope-block
@@ -374,7 +376,7 @@
374376
(append req opt vararg) rett)))))
375377
;; no optional positional args
376378
(let* ((names (map car sparams))
377-
(anames (map (lambda (x) (if (underscore-symbol? x) UNUSED x)) (llist-vars argl)))
379+
(anames (llist-vars argl))
378380
(unused_anames (filter (lambda (x) (not (eq? x UNUSED))) anames))
379381
(ename (if (nodot-sym-ref? name) name
380382
(if (overlay? name) (cadr name) `(null)))))

test/syntax.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,6 +2897,9 @@ end
28972897
@test Meta.isexpr(Meta.lower(Main, :(for _ in 1:2; 1; end)), :thunk)
28982898
@test (try; throw(1); catch _; 2; end) === 2
28992899
@test (let _ = 1; 2; end) === 2
2900+
@test (function f(_, _); 2; end)(0,0) === 2
2901+
@test (function f(_, _=1); 2; end)(0,0) === 2
2902+
@test (function f(_, _; kw1=2); kw1; end)(0,0) === 2
29002903
# ERROR: syntax: all-underscore identifiers are write-only and their values cannot be used in expressions
29012904
@test Meta.isexpr(Meta.lower(Main, :(_ = 1; a = _)), :error)
29022905
@test Meta.isexpr(Meta.lower(Main, :(let; function f(); _; end; end)), :error)

0 commit comments

Comments
 (0)