diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 323c6b472e2e9..be21b395c0338 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -2750,12 +2750,37 @@ f(x) = yt(x) ,(delete-duplicates (append (lam:sp lam) capt-sp))) ,body))) +;; renumber ssavalues assigned in an expr, allowing it to be repeated +(define (renumber-assigned-ssavalues e) + (let ((vals (expr-find-all (lambda (x) (and (assignment? x) (ssavalue? (cadr x)))) + e + cadadr))) + (if (null? vals) + e + (let ((repl (table))) + (for-each (lambda (id) (put! repl id (make-ssavalue))) + vals) + (let do-replace ((x e)) + (if (or (atom? x) (quoted? x)) + x + (if (eq? (car x) 'ssavalue) + (or (get repl (cadr x) #f) x) + (cons (car x) + (map do-replace (cdr x)))))))))) + (define (convert-for-type-decl rhs t) (if (equal? t '(core Any)) rhs - `(call (core typeassert) - (call (top convert) ,t ,rhs) - ,t))) + (let* ((temp (if (or (atom? t) (ssavalue? t) (quoted? t)) + #f + (make-ssavalue))) + (ty (or temp t)) + (ex `(call (core typeassert) + (call (top convert) ,ty ,rhs) + ,ty))) + (if temp + `(block (= ,temp ,(renumber-assigned-ssavalues t)) ,ex) + ex)))) ;; convert assignment to a closed variable to a setfield! call. ;; while we're at it, generate `convert` calls for variables with diff --git a/test/core.jl b/test/core.jl index f1e4112c86677..be7876b9b2bb9 100644 --- a/test/core.jl +++ b/test/core.jl @@ -6710,3 +6710,12 @@ struct T29145{A,B} end end @test_throws TypeError T29145() + +# issue #29175 +function f29175(tuple::T) where {T<:Tuple} + prefix::Tuple{T.parameters[1:end-1]...} = tuple[1:length(T.parameters)-1] + x = prefix + prefix = x # force another conversion to declared type + return prefix +end +@test f29175((1,2,3)) === (1,2)