expander: fix local-expand and dropped macro definition

If `local-expand` with a 'module-begin context introduces a macro
definition, but the definition is dropped while a non-macro definition
is later introduced, then make sure references go to the non-macro
definition.

This change also addresses a related scenario, where a
`local-expand`-discovered macro definition is not dropped, but it is
given an extra scope --- which amounts to the same thing from the
expander's perspective.
This commit is contained in:
Matthew Flatt 2018-05-23 15:19:35 -06:00
parent 61a50fbf93
commit 1faa0433fa
3 changed files with 615 additions and 536 deletions

View File

@ -2620,6 +2620,40 @@ case of module-leve bindings; it doesn't cover local bindings.
(require (submod "." m "..")))))
exn:fail?)
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; If `local-expand` creates a macro binding, and if
;; the definition is discarded with a non-macro definition
;; is introduced, then make sure the non-macro definition
;; is referenced.
(module discards-module-begin-macro-definition racket/base
(module mb racket/base
(require (for-syntax racket/base))
(provide (except-out (all-from-out racket/base)
#%module-begin)
(rename-out [module-begin #%module-begin]))
(define-syntax (module-begin stx)
(syntax-case stx ()
[(_ a b)
(begin
(local-expand #'(#%module-begin a) 'module-begin null)
#'(#%module-begin b))])))
(module use (submod ".." mb)
(begin
(require (for-syntax racket/base))
(define-syntax (m stx) #''not-ok))
(begin
(define (m) 'ok)
(define result (m))
(provide result)))
(require 'use)
(provide result))
(test 'ok dynamic-require ''discards-module-begin-macro-definition 'result)
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs)

View File

@ -777,6 +777,9 @@
#:frame-id frame-id
#:requires+provides requires+provides
#:in exp-body))
(for ([sym (in-list syms)])
;; In case `local-expand` created a binding with `sym` to a transformer
(namespace-unset-transformer! m-ns phase sym))
(add-defined-syms! requires+provides syms phase)
(log-expand partial-body-ctx 'exit-prim
(datum->syntax #f `(,(m 'define-values) ,ids ,(m 'rhs)) exp-body))

File diff suppressed because it is too large Load Diff