Skip to content

Commit c446444

Browse files
authored
fix #27710, scope error with static param. and variable name conflicts (#27760)
1 parent c6eb703 commit c446444

File tree

2 files changed

+44
-37
lines changed

2 files changed

+44
-37
lines changed

src/julia-syntax.scm

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -273,15 +273,6 @@
273273
(map (lambda (x) (replace-vars x renames))
274274
(cdr e))))))
275275

276-
(define (replace-outer-vars e renames)
277-
(cond ((and (pair? e) (eq? (car e) 'outerref)) (lookup (cadr e) renames e))
278-
((or (not (pair? e)) (quoted? e)) e)
279-
((memq (car e) '(-> function scope-block)) e)
280-
(else
281-
(cons (car e)
282-
(map (lambda (x) (replace-outer-vars x renames))
283-
(cdr e))))))
284-
285276
(define (make-generator-function name sp-names arg-names body)
286277
(let ((arg-names (append sp-names
287278
(map (lambda (n)
@@ -2508,7 +2499,7 @@
25082499
;; 3. variables assigned inside this scope-block that don't exist in outer
25092500
;; scopes
25102501
;; returns lambdas in the form (lambda (args...) (locals...) body)
2511-
(define (resolve-scopes- e env outerglobals implicitglobals lam renames newlam)
2502+
(define (resolve-scopes- e env outerglobals implicitglobals lam renames newlam (sp '()))
25122503
(cond ((symbol? e) (let ((r (assq e renames)))
25132504
(if r (cdr r) e))) ;; return the renaming for e, or e
25142505
((or (not (pair? e)) (quoted? e) (memq (car e) '(toplevel global symbolicgoto symboliclabel))) e)
@@ -2525,7 +2516,7 @@
25252516
`(warn-loop-var ,(cadr e))
25262517
'(null)))
25272518
((eq? (car e) 'lambda)
2528-
(let* ((lv (lam:vars e))
2519+
(let* ((lv (append sp (lam:vars e)))
25292520
(env (append lv env))
25302521
(body (resolve-scopes- (lam:body e) env
25312522
;; don't propagate implicit or outer globals
@@ -2622,9 +2613,15 @@
26222613
`(break-block ,(cadr e) ;; ignore type symbol of break-block expression
26232614
,(resolve-scopes- (caddr e) env outerglobals implicitglobals lam renames #f))) ;; body of break-block expression
26242615
((eq? (car e) 'with-static-parameters)
2625-
`(with-static-parameters ;; ignore list of sparams in break-block expression
2626-
,(resolve-scopes- (cadr e) env outerglobals implicitglobals lam renames #f)
2627-
,@(cddr e))) ;; body of break-block expression
2616+
`(with-static-parameters
2617+
,(resolve-scopes- (cadr e) env outerglobals implicitglobals lam renames #f (cddr e))
2618+
,@(cddr e)))
2619+
((and (eq? (car e) 'method) (length> e 2))
2620+
`(method
2621+
,(resolve-scopes- (cadr e) env outerglobals implicitglobals lam renames #f)
2622+
,(resolve-scopes- (caddr e) env outerglobals implicitglobals lam renames #f)
2623+
,(resolve-scopes- (cadddr e) env outerglobals implicitglobals lam renames #f
2624+
(method-expr-static-parameters e))))
26282625
(else
26292626
(cons (car e)
26302627
(map (lambda (x)
@@ -3192,13 +3189,12 @@ f(x) = yt(x)
31923189
,@sp-inits
31933190
(method ,name ,(cl-convert sig fname lam namemap toplevel interp)
31943191
,(let ((body (add-box-inits-to-body
3195-
lam2
3196-
(cl-convert (cadddr lam2) 'anon lam2 (table) #f interp))))
3192+
lam2
3193+
(cl-convert (cadddr lam2) 'anon lam2 (table) #f interp))))
31973194
`(lambda ,(cadr lam2)
31983195
(,(clear-capture-bits (car vis))
31993196
,@(cdr vis))
3200-
,body))
3201-
,(last e))))
3197+
,body)))))
32023198
(else
32033199
(let* ((exprs (lift-toplevel (convert-lambda lam2 '|#anon| #t '())))
32043200
(top-stmts (cdr exprs))
@@ -3236,20 +3232,18 @@ f(x) = yt(x)
32363232
(capt-vars (diff all-capt-vars capt-sp)) ; remove capt-sp from capt-vars
32373233
(find-locals-in-method-sig (lambda (methdef)
32383234
(expr-find-all
3239-
(lambda (e) (and (or (symbol? e) (and (pair? e) (eq? (car e) 'outerref)))
3240-
(let ((s (if (symbol? e) e (cadr e))))
3241-
(and (symbol? s)
3242-
(not (eq? name s))
3243-
(not (memq s capt-sp))
3244-
(if (and (local? s) (length> (lam:args lam) 0))
3245-
; error for local variables except in toplevel thunks
3246-
(error (string "local variable " s
3247-
" cannot be used in closure declaration"))
3248-
#t)
3249-
; allow captured variables
3250-
(memq s (lam:sp lam))))))
3235+
(lambda (s) (and (symbol? s)
3236+
(not (eq? name s))
3237+
(not (memq s capt-sp))
3238+
(if (and (local? s) (length> (lam:args lam) 0))
3239+
;; error for local variables except in toplevel thunks
3240+
(error (string "local variable " s
3241+
" cannot be used in closure declaration"))
3242+
#t)
3243+
;; allow captured variables
3244+
(memq s (lam:sp lam))))
32513245
(caddr methdef)
3252-
(lambda (e) (cadr e)))))
3246+
identity)))
32533247
(sig-locals (simple-sort
32543248
(delete-duplicates ;; locals used in sig from all definitions
32553249
(apply append ;; will convert these into sparams for dispatch
@@ -3274,7 +3268,7 @@ f(x) = yt(x)
32743268
(let* ((iskw ;; TODO jb/functions need more robust version of this
32753269
(contains (lambda (x) (eq? x 'kwftype)) sig))
32763270
(renamemap (map cons closure-param-names closure-param-syms))
3277-
(arg-defs (replace-outer-vars
3271+
(arg-defs (replace-vars
32783272
(fix-function-arg-type sig type-name iskw namemap closure-param-syms)
32793273
renamemap)))
32803274
(append (map (lambda (gs tvar)
@@ -3296,7 +3290,7 @@ f(x) = yt(x)
32963290
v)))
32973291
capt-vars))
32983292
(P (append
3299-
(map (lambda (n) `(outerref ,n)) closure-param-names)
3293+
closure-param-names
33003294
(filter identity (map (lambda (v ve)
33013295
(if (is-var-boxed? v lam)
33023296
#f
@@ -4100,14 +4094,19 @@ f(x) = yt(x)
41004094
(define (renumber-stuff e)
41014095
(cond ((symbol? e)
41024096
(let ((idx (get slot-table e #f)))
4103-
(if idx `(slot ,idx) e)))
4097+
(if idx
4098+
`(slot ,idx)
4099+
(let ((idx (get sp-table e #f)))
4100+
(if idx
4101+
`(static_parameter ,idx)
4102+
e)))))
41044103
((and (pair? e) (eq? (car e) 'outerref))
4105-
(let ((idx (get sp-table (cadr e) #f)))
4106-
(if idx `(static_parameter ,idx) (cadr e))))
4104+
(cadr e))
41074105
((nospecialize-meta? e)
41084106
;; convert nospecialize vars to slot numbers
41094107
`(meta nospecialize ,@(map renumber-stuff (cddr e))))
4110-
((or (atom? e) (quoted? e)) e)
4108+
((or (atom? e) (quoted? e) (eq? (car e) 'global))
4109+
e)
41114110
((ssavalue? e)
41124111
(let ((idx (or (get ssavalue-table (cadr e) #f)
41134112
(error "ssavalue with no def"))))

test/syntax.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,3 +1447,11 @@ f27129(x = 1) = (@Base._inline_meta; x)
14471447
for meth in methods(f27129)
14481448
@test ccall(:jl_uncompress_ast, Any, (Any, Any), meth, meth.source).inlineable
14491449
end
1450+
1451+
# issue #27710
1452+
struct Foo27710{T} end
1453+
function test27710()
1454+
types(::Foo27710{T}) where T = T
1455+
T = types(Foo27710{Int64}())
1456+
end
1457+
@test test27710() === Int64

0 commit comments

Comments
 (0)