expander: fix syntax-local-bind-syntaxes for local-expand

Bind variables in a way that allows `local-expand` (with an empty stop
list) to replace a reference to the binding with one that has the same
scopes as the binding.
This commit is contained in:
Matthew Flatt 2018-06-12 16:21:17 -06:00
parent 380dc42427
commit c7318cab33
4 changed files with 3506 additions and 3452 deletions

View File

@ -275,11 +275,15 @@ The @racket[stop-ids] argument controls how far @racket[local-expand] expands @r
When @racket[#%plain-module-begin] is not in @racket[stop-ids], the
@racket[#%plain-module-begin] transformer detects and expands sub-forms (such as
@racket[define-values]) regardless of the identifiers presence in @racket[stop-ids].}
@racket[define-values]) regardless of the identifiers presence in @racket[stop-ids].
Expansion does not replace the scopes in a local-variable
reference to match the binding identifier.}
@item{If @racket[stop-ids] is @racket[#f] instead of a list, then @racket[stx] is expanded only as
long as the outermost form of @racket[stx] is a macro (i.e. expansion does @emph{not} proceed
to sub-expressions). @racketid[#%app], @racketid[#%datum], and @racketid[#%top] identifiers are
to sub-expressions, and it does not replace the scopes in a local-variable reference to match the
binding identifier). The @racketid[#%app], @racketid[#%datum], and @racketid[#%top] identifiers are
never introduced.}]
Independent of @racket[stop-ids], when @racket[local-expand] encounters an identifier that has a local

View File

@ -2234,6 +2234,33 @@
(expand-in-modbeg
(m)))))
;; ----------------------------------------
;; Make sure `syntax-local-bind-syntaxes` binds variables in a way
;; that `local-expand` replaces a use with the binding scopes.
(module uses-definition-context-and-local-expand-to-replace racket/base
(require (for-syntax racket/base))
(define-syntax (m stx)
(syntax-case stx ()
[(_ id)
(let ()
(define intdef (syntax-local-make-definition-context))
(syntax-local-bind-syntaxes (list #'id)
#f ; => local variable
intdef)
(define raw-bind-id (internal-definition-context-introduce intdef #'id))
(define raw-ex-id (local-expand ((make-syntax-introducer) #'id) 'expression null intdef))
(define bind-id (syntax-local-identifier-as-binding raw-bind-id))
(define ex-id (syntax-local-identifier-as-binding raw-ex-id))
#`(list #,(free-identifier=? bind-id ex-id)
#,(bound-identifier=? bind-id ex-id)))]))
(define result (m x))
(provide result))
(test '(#t #t) dynamic-require ''uses-definition-context-and-local-expand-to-replace 'result)
;; ----------------------------------------
(report-errs)

View File

@ -90,8 +90,9 @@
(cond
[s
(define input-s (flip-introduction-scopes (add-intdef-scopes s all-intdefs) ctx))
(define tmp-env (for/fold ([env (expand-context-env ctx)]) ([sym (in-list syms)])
(hash-set env sym variable)))
(define tmp-env (for/fold ([env (expand-context-env ctx)]) ([sym (in-list syms)]
[intdef-id (in-list intdef-ids)])
(hash-set env sym (local-variable intdef-id))))
(log-expand ctx 'enter-bind)
(define vals
(eval-for-syntaxes-binding 'syntax-local-bind-syntaxes
@ -103,7 +104,7 @@
(log-expand ctx 'exit-bind)
vals]
[else
(for/list ([id (in-list ids)]) variable)]))
(for/list ([intdef-id (in-list intdef-ids)]) (local-variable intdef-id))]))
(define env-mixins (internal-definition-context-env-mixins intdef))
(set-box! env-mixins (append (for/list ([intdef-id (in-list intdef-ids)]
[sym (in-list syms)]

File diff suppressed because it is too large Load Diff