Skip to content

Commit

Permalink
expander: fix syntax-local-bind-syntaxes for local-expand
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mflatt committed Jun 12, 2018
1 parent 380dc42 commit c7318ca
Show file tree
Hide file tree
Showing 4 changed files with 3,357 additions and 3,303 deletions.
8 changes: 6 additions & 2 deletions pkgs/racket-doc/scribblings/reference/stx-trans.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 27 additions & 0 deletions pkgs/racket-test-core/tests/racket/macro.rktl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
7 changes: 4 additions & 3 deletions racket/src/expander/expand/definition-context.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)]
Expand Down

2 comments on commit c7318ca

@lexi-lambda
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the behavior that the expander does perform this scope simplification when expanding a variable with an empty stop list documented anywhere?

@mflatt
Copy link
Member Author

@mflatt mflatt commented on c7318ca Jun 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, that's documented in the "Fully Expanded Programs" section.

Please sign in to comment.