diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index b6dc7bb9c8a12..47cbc9dec1503 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -4322,11 +4322,10 @@ f(x) = yt(x) (define (linearize e) (cond ((or (not (pair? e)) (quoted? e)) e) ((eq? (car e) 'lambda) - (set-car! (cdddr e) (compile-body (cadddr e) (append (car (caddr e)) - (cadr (caddr e))) - e))) - (else (for-each linearize (cdr e)))) - e) + (list-set e 3 (compile-body (cadddr e) + (append (car (caddr e)) + (cadr (caddr e))) e))) + (else (cons (car e) (map linearize (cdr e)))))) (define (valid-ir-argument? e) (or (simple-atom? e) diff --git a/src/utils.scm b/src/utils.scm index 79e3a280b9886..80fc44615a49a 100644 --- a/src/utils.scm +++ b/src/utils.scm @@ -119,3 +119,16 @@ (cons (car lst) (filter (lambda (x) (not (pred x))) (cdr lst)))) (else (cons (car lst) (keep-first pred (cdr lst)))))) + +(define (take lst n) + (let loop ((lst lst) (n n) (out '())) + (if (= n 0) (reverse out) + (loop (cdr lst) (- n 1) (cons (car lst) out))))) + +(define (drop lst n) + (if (= n 0) lst + (drop (cdr lst) (- n 1)))) + +;; functional update at position i +(define (list-set lst i val) + (append (take lst i) (list val) (drop lst (+ i 1)))) diff --git a/test/syntax.jl b/test/syntax.jl index 67a6976adfcec..58eab90ff2ba9 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -4088,3 +4088,7 @@ abstract type A57267{S, T} end B57267{S} = A57267{S, 1} const C57267 = B57267 end + +# Issue #56904 - lambda linearized twice +@test (let; try 3; finally try 1; f(() -> x); catch x; end; end; x = 7; end) === 7 +@test (let; try 3; finally try 4; finally try 1; f(() -> x); catch x; end; end; end; x = 7; end) === 7