From e7c1345d071fa83736045c2484faabd7f978125f Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 7 Feb 2022 13:49:32 -0500 Subject: [PATCH] fix #43960, evaluation order of splat inside ref (#44024) (cherry picked from commit 546a77474bf730569e651b60415a187da769fb64) --- src/julia-syntax.scm | 48 +++++++++++++++++++++----------------------- test/syntax.jl | 8 ++++++++ 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 48b175680c535d..b72ac74e9acea8 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -130,31 +130,29 @@ ;; returns (values index-list stmts) where stmts are statements that need ;; to execute first. (define (process-indices a i) - (let loop ((lst i) - (n 1) - (stmts '()) - (tuples '()) - (ret '())) - (if (null? lst) - (values (reverse ret) (reverse stmts)) - (let ((idx (car lst)) - (last (null? (cdr lst)))) - (if (and (pair? idx) (eq? (car idx) '...)) - (if (symbol-like? (cadr idx)) - (loop (cdr lst) (+ n 1) - stmts - (cons (cadr idx) tuples) - (cons `(... ,(replace-beginend (cadr idx) a n tuples last)) - ret)) - (let ((g (make-ssavalue))) - (loop (cdr lst) (+ n 1) - (cons `(= ,g ,(replace-beginend (cadr idx) a n tuples last)) - stmts) - (cons g tuples) - (cons `(... ,g) ret)))) - (loop (cdr lst) (+ n 1) - stmts tuples - (cons (replace-beginend idx a n tuples last) ret))))))) + (let ((has-va? (any vararg? i))) + (let loop ((lst i) + (n 1) + (stmts '()) + (tuples '()) + (ret '())) + (if (null? lst) + (values (reverse ret) (reverse stmts)) + (let* ((idx0 (car lst)) + (idx (if (vararg? idx0) (cadr idx0) idx0)) + (last (null? (cdr lst))) + (replaced (replace-beginend idx a n tuples last)) + (idx (if (or (not has-va?) (simple-atom? replaced)) replaced (make-ssavalue)))) + (loop (cdr lst) (+ n 1) + (if (eq? idx replaced) + stmts + (cons `(= ,idx ,replaced) + stmts)) + (if (vararg? idx0) (cons idx tuples) tuples) + (cons (if (vararg? idx0) + `(... ,idx) + idx) + ret))))))) ;; GF method does not need to keep decl expressions on lambda args ;; except for rest arg diff --git a/test/syntax.jl b/test/syntax.jl index 6823ac47ee6b74..61f10a9e4c52fc 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -1193,6 +1193,14 @@ end @test [(0,0)... 1] == [0 0 1] @test Float32[(0,0)... 1] == Float32[0 0 1] +# issue #43960, evaluation order of splatting in `ref` +let a = [], b = [4,3,2,1] + f() = (push!(a, 1); 2) + g() = (push!(a, 2); ()) + @test b[f(), g()...] == 3 + @test a == [1,2] +end + @testset "raw_str macro" begin @test raw"$" == "\$" @test raw"\n" == "\\n"