expander: fix problem related to (local-expand 'module-begin ...)
When `local-expand` is used for a 'module-begin context, use a fresh binding -> definition-unreadable-symbol table for the nested expansion. That way, the table used for the main expansion is unchanged, and re-expanding or evaluating the expanded module will arrive at the same unreadable symbols as the initial expansion. The report and example are from Alexis.
This commit is contained in:
parent
662a9022c0
commit
f231cb2003
|
@ -2535,6 +2535,53 @@ case of module-leve bindings; it doesn't cover local bindings.
|
|||
(compile/eval u-code)
|
||||
(test 'ns-val dynamic-require ''u 'v))))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Another example to check that re-expansion generates definition
|
||||
;; names consistent with the previoud expansion.
|
||||
|
||||
(parameterize ([current-namespace (make-base-namespace)])
|
||||
(define modbeg-trampoline
|
||||
'(module modbeg-trampoline racket/base
|
||||
(require (for-syntax racket/base
|
||||
syntax/strip-context))
|
||||
|
||||
(provide (rename-out [module-begin #%module-begin]))
|
||||
|
||||
(define-syntax (module-begin stx)
|
||||
(syntax-case stx ()
|
||||
[(_ lang . body)
|
||||
#'(#%plain-module-begin (module-begin-trampoline lang . body))]))
|
||||
|
||||
(define-syntax (module-begin-trampoline stx)
|
||||
(syntax-case stx ()
|
||||
[(_ lang . body)
|
||||
(with-syntax ([[modbeg . [body* ...]] (syntax-local-introduce
|
||||
(syntax-local-lift-require
|
||||
(strip-context #'lang)
|
||||
(datum->syntax #f (cons '#%module-begin
|
||||
(strip-context #'body)))))])
|
||||
(with-syntax ([body** (if (= (length (syntax->list #'(body* ...))) 1)
|
||||
(error "oops")
|
||||
#'(modbeg . [body* ...]))])
|
||||
(with-syntax ([(modbeg* form ...) (local-expand #'body** 'module-begin #f)])
|
||||
(with-syntax ([body*** (local-expand #'(modbeg* form ...) 'module-begin (list #'module*))])
|
||||
(with-syntax ([(modbeg**:#%plain-module-begin form* ...) #'body***])
|
||||
(syntax-track-origin #`(begin form* ...) #'body*** #'modbeg**))))))]))))
|
||||
|
||||
(define m-use
|
||||
'(module m-use 'modbeg-trampoline racket/base
|
||||
(require racket/contract/base)
|
||||
(provide (contract-out [f (-> number? number?)]))
|
||||
(define (f x) (+ x 42))
|
||||
(module* main racket
|
||||
(require (submod ".."))
|
||||
(f 10))))
|
||||
|
||||
(eval modbeg-trampoline)
|
||||
(eval (expand m-use))
|
||||
|
||||
(dynamic-require '(submod 'm-use main) #f))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(report-errs)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"../common/struct-star.rkt"
|
||||
"../common/performance.rkt"
|
||||
"../syntax/syntax.rkt"
|
||||
"../syntax/debug.rkt"
|
||||
"../syntax/property.rkt"
|
||||
"../syntax/scope.rkt"
|
||||
"../syntax/taint.rkt"
|
||||
|
@ -233,7 +234,7 @@
|
|||
(hash-clear! compiled-submodules)
|
||||
(set-box! compiled-module-box #f))
|
||||
(set! again? #t)
|
||||
|
||||
|
||||
;; In case a nested `#%module-begin` expansion is forced, save
|
||||
;; and restore the module-expansion state:
|
||||
(define ctx (struct*-copy expand-context mb-init-ctx
|
||||
|
@ -249,7 +250,8 @@
|
|||
#:copy-requires requires+provides))
|
||||
(with-save-and-restore ([requires+provides new-requires+provides]
|
||||
[compiled-submodules (make-hasheq)]
|
||||
[compiled-module-box (box #f)])
|
||||
[compiled-module-box (box #f)]
|
||||
[defined-syms (make-hasheq)])
|
||||
(module-begin-k s ctx)))]))
|
||||
|
||||
;; In case `#%module-begin` expansion is forced on syntax that
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user