Skip to content

Commit

Permalink
add typeasserts for captured variables with declared types
Browse files Browse the repository at this point in the history
This provides an escape hatch for difficult-to-analyze bindings by
declaring their type. We assert that the type is as declared on
access.

fixes #16431
  • Loading branch information
JeffBezanson committed May 19, 2016
1 parent 1ce4ef0 commit 816ed28
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
16 changes: 11 additions & 5 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -2715,11 +2715,17 @@ f(x) = yt(x)
`($ (call (core QuoteNode) ,e))
`(call (core getfield) ,fname (inert ,e)))))
(if (and (vinfo:asgn cv) (vinfo:capt cv))
`(call (core getfield) ,access (inert contents))
(let ((val `(call (core getfield) ,access (inert contents))))
(if (eq? (vinfo:type cv) 'Any)
val
`(call (core typeassert) ,val ,(vinfo:type cv))))
access)))
(vi
(if (and (vinfo:asgn vi) (vinfo:capt vi))
`(call (core getfield) ,e (inert contents))
(let ((val `(call (core getfield) ,e (inert contents))))
(if (eq? (vinfo:type vi) 'Any)
val
`(call (core typeassert) ,val ,(vinfo:type vi))))
e))
(else e))))
((atom? e) e)
Expand All @@ -2741,9 +2747,9 @@ f(x) = yt(x)
(let ((vi (assq (cadr e) (car (lam:vinfo lam)))))
(if (and vi (vinfo:asgn vi) (vinfo:capt vi)
;; avoid redundant box for vars with newvar nodes
(not (any (lambda (x) (and (length= x 2)
(eq? (car x) 'newvar) (eq? (cadr x) (cadr e))))
(lam:body lam))))
(not (expr-contains-p (lambda (x) (and (length= x 2)
(eq? (car x) 'newvar) (eq? (cadr x) (cadr e))))
(lam:body lam))))
`(= ,(cadr e) (call (core Box)))
`(newvar ,(cadr e)))))
((const)
Expand Down
8 changes: 8 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4149,3 +4149,11 @@ end
@noinline MaybeFunc(T) = Union{T, Void}
fMaybeFunc() = MaybeFunc(Int64)
@test fMaybeFunc() == Union{Int64, Void}

# issue #16431
function f16431(x)
z::Int = x * 2
g(y) = begin z = z + y; y + x end
z * g(x)
end
@test @inferred(f16431(1)) == 4

0 comments on commit 816ed28

Please sign in to comment.