diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 1b11b48765951..9e68ca826b6ac 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -2118,11 +2118,21 @@ `(call ,@hvncat ,dims ,(tf is-row-first) ,@aflat)) `(call ,@hvncat ,(tuplize shape) ,(tf is-row-first) ,@aflat)))))))) -(define (expand-property-destruct lhss x) - (if (not (length= lhss 1)) - (error (string "invalid assignment location \"" (deparse lhs) "\""))) - (let* ((xx (if (symbol-like? x) x (make-ssavalue))) - (ini (if (eq? x xx) '() (list (sink-assignment xx (expand-forms x)))))) +(define (maybe-ssavalue lhss x in-lhs?) + (cond ((or (and (not (in-lhs? x lhss)) (symbol? x)) + (ssavalue? x)) + x) + ((and (pair? lhss) (vararg? (last lhss)) + (eventually-call? (cadr (last lhss)))) + (gensy)) + (else (make-ssavalue)))) + +(define (expand-property-destruct lhs x) + (if (not (length= lhs 1)) + (error (string "invalid assignment location \"" (deparse `(tuple ,lhs)) "\""))) + (let* ((lhss (cdar lhs)) + (xx (maybe-ssavalue lhss x memq)) + (ini (if (eq? x xx) '() (list (sink-assignment xx (expand-forms x)))))) `(block ,@ini ,@(map @@ -2131,9 +2141,9 @@ ((and (pair? field) (eq? (car field) '|::|) (symbol? (cadr field))) (cadr field)) (else - (error (string "invalid assignment location \"" (deparse lhs) "\"")))))) + (error (string "invalid assignment location \"" (deparse `(tuple ,lhs)) "\"")))))) (expand-forms `(= ,field (call (top getproperty) ,xx (quote ,prop)))))) - (cdar lhss)) + lhss) (unnecessary ,xx)))) (define (expand-tuple-destruct lhss x) @@ -2166,13 +2176,7 @@ ((eq? l x) #t) (else (in-lhs? x (cdr lhss))))))) ;; in-lhs? also checks for invalid syntax, so always call it first - (let* ((xx (cond ((or (and (not (in-lhs? x lhss)) (symbol? x)) - (ssavalue? x)) - x) - ((and (pair? lhss) (vararg? (last lhss)) - (eventually-call? (cadr (last lhss)))) - (gensy)) - (else (make-ssavalue)))) + (let* ((xx (maybe-ssavalue lhss x in-lhs?)) (ini (if (eq? x xx) '() (list (sink-assignment xx (expand-forms x))))) (n (length lhss)) ;; skip last assignment if it is an all-underscore vararg diff --git a/test/syntax.jl b/test/syntax.jl index 9c16bb13a1233..72512ae543dec 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -3144,3 +3144,22 @@ end let ex = :(const $(esc(:x)) = 1; (::typeof(2))() = $(esc(:x))) @test macroexpand(Main, Expr(:var"hygienic-scope", ex, Main)).args[3].args[1] == :((::$(GlobalRef(Main, :typeof))(2))()) end + +struct Foo44013 + x + f +end + +@testset "issue #44013" begin + f = Foo44013(1, 2) + res = begin (; x, f) = f end + @test res == Foo44013(1, 2) + @test x == 1 + @test f == 2 + + f = Foo44013(1, 2) + res = begin (; f, x) = f end + @test res == Foo44013(1, 2) + @test x == 1 + @test f == 2 +end