Skip to content

Commit

Permalink
fix JuliaLang#44013: aliasing in property destructuring (JuliaLang#44020
Browse files Browse the repository at this point in the history
)
  • Loading branch information
simeonschaub authored and LilithHafner committed Mar 8, 2022
1 parent 098f7e6 commit b89ad88
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
32 changes: 18 additions & 14 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions test/syntax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit b89ad88

Please sign in to comment.