Skip to content

Commit 5086df0

Browse files
committed
fix: disallow thisfunction inside comprehension or generator
1 parent 787320b commit 5086df0

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

src/ast.scm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@
466466
(define (make-assignment l r) `(= ,l ,r))
467467
(define (assignment? e) (and (pair? e) (eq? (car e) '=)))
468468
(define (return? e) (and (pair? e) (eq? (car e) 'return)))
469+
(define (thisfunction? e) (and (pair? e) (eq? (car e) 'thisfunction)))
469470

470471
(define (tuple-call? e)
471472
(and (length> e 1)

src/julia-syntax.scm

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,6 @@
306306
(map (lambda (x) (replace-vars x renames))
307307
(cdr e))))))
308308

309-
(define (contains-thisfunction? expr)
310-
(expr-contains-p (lambda (x) (and (pair? x) (eq? (car x) 'thisfunction))) expr))
311-
312309
(define (make-generator-function name sp-names arg-names body)
313310
(let ((arg-names (append sp-names
314311
(map (lambda (n)
@@ -555,7 +552,7 @@
555552
(insert-after-meta `(block
556553
,@stmts)
557554
(cons `(meta nkw ,(+ (length vars) (length restkw)))
558-
(if (and name (contains-thisfunction? `(block ,@stmts)))
555+
(if (and name (has-thisfunction? `(block ,@stmts)))
559556
(cons `(meta thisfunction-original ,name) annotations)
560557
annotations)))
561558
rett)
@@ -2919,6 +2916,7 @@
29192916
'generator
29202917
(lambda (e)
29212918
(check-no-return e)
2919+
(check-no-thisfunction e)
29222920
(expand-generator e #f '()))
29232921

29242922
'flatten
@@ -3003,6 +3001,13 @@
30033001
(if (has-return? e)
30043002
(error "\"return\" not allowed inside comprehension or generator")))
30053003

3004+
(define (has-thisfunction? e)
3005+
(expr-contains-p thisfunction? e (lambda (x) (not (function-def? x)))))
3006+
3007+
(define (check-no-thisfunction e)
3008+
(if (has-thisfunction? e)
3009+
(error "\"thisfunction\" not allowed inside comprehension or generator")))
3010+
30063011
(define (has-break-or-continue? e)
30073012
(expr-contains-p (lambda (x) (and (pair? x) (memq (car x) '(break continue))))
30083013
e
@@ -3011,6 +3016,7 @@
30113016

30123017
(define (lower-comprehension ty expr itrs)
30133018
(check-no-return expr)
3019+
(check-no-thisfunction expr)
30143020
(if (has-break-or-continue? expr)
30153021
(error "break or continue outside loop"))
30163022
(let ((result (make-ssavalue))

test/syntax.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,8 +1526,11 @@ end
15261526
@test Meta.lower(@__MODULE__, :(return 0 for i=1:2)) == Expr(:error, "\"return\" not allowed inside comprehension or generator")
15271527
@test Meta.lower(@__MODULE__, :([ return 0 for i=1:2 ])) == Expr(:error, "\"return\" not allowed inside comprehension or generator")
15281528
@test Meta.lower(@__MODULE__, :(Int[ return 0 for i=1:2 ])) == Expr(:error, "\"return\" not allowed inside comprehension or generator")
1529+
@test Meta.lower(@__MODULE__, :([ $(Expr(:thisfunction)) for i=1:2 ])) == Expr(:error, "\"thisfunction\" not allowed inside comprehension or generator")
1530+
@test Meta.lower(@__MODULE__, :($(Expr(:thisfunction)) for i=1:2)) == Expr(:error, "\"thisfunction\" not allowed inside comprehension or generator")
15291531
@test [ ()->return 42 for i = 1:1 ][1]() == 42
15301532
@test Function[ identity() do x; return 2x; end for i = 1:1 ][1](21) == 42
1533+
@test @eval let f=[ ()->$(Expr(:thisfunction)) for i = 1:1 ][1]; f() === f; end
15311534

15321535
# issue #27155
15331536
macro test27155()

0 commit comments

Comments
 (0)