expander: fix require after shadowing define

This commit is contained in:
Matthew Flatt 2018-03-01 14:13:59 -07:00
parent 7069510d67
commit 11fd70c3dd
7 changed files with 15171 additions and 14862 deletions

View File

@ -683,6 +683,55 @@
(let ([n-ns (eval '(module->namespace ''n) ns)]) (let ([n-ns (eval '(module->namespace ''n) ns)])
(test 5 eval '(lambda (x) x) n-ns))))) (test 5 eval '(lambda (x) x) n-ns)))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check shadowing when `define` precedes `require`
(module definition-shadows-later-require racket/base
(provide result)
(define first "last")
(require racket/list)
(define result first))
(test "last" dynamic-require ''definition-shadows-later-require 'result)
(module definition-shadows-later-require/rename racket/base
(provide result)
(define first "last")
(require (rename-in racket/function
[curry first]))
(define result first))
(test "last" dynamic-require ''definition-shadows-later-require/rename 'result)
(module definition-shadows-later-require/2 racket/base
(provide result)
(define first "last")
(require racket/list)
(require racket/list)
(define result first))
(test "last" dynamic-require ''definition-shadows-later-require/2 'result)
(err/rt-test
(eval
'(module m racket/base
(define first "last")
(require racket/list)
;; late `require` collision:
(require (rename-in racket/function
[curry first]))))
exn:fail:syntax?)
(err/rt-test
(eval
'(module m racket/base
(require racket/list)
(define first "last")
;; late `require` collision:
(require (rename-in racket/function
[curry first]))))
exn:fail:syntax?)
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check printing of resolved module paths ;; Check printing of resolved module paths

View File

@ -85,10 +85,13 @@
(add-binding-in-scopes! (syntax-scope-set id phase) (syntax-e id) binding (add-binding-in-scopes! (syntax-scope-set id phase) (syntax-e id) binding
#:just-for-nominal? just-for-nominal?)) #:just-for-nominal? just-for-nominal?))
(define (add-bulk-binding! s binding phase #:in [in-s #f]) (define (add-bulk-binding! s binding phase
#:in [in-s #f]
#:shadow-except [shadow-except #f])
(when (syntax-tainted? s) (when (syntax-tainted? s)
(raise-syntax-error #f "cannot bind from tainted syntax" in-s s)) (raise-syntax-error #f "cannot bind from tainted syntax" in-s s))
(add-bulk-binding-in-scopes! (syntax-scope-set s phase) binding)) (add-bulk-binding-in-scopes! (syntax-scope-set s phase) binding
#:shadow-except shadow-except))
;; Helper for registering a local binding in a set of scopes: ;; Helper for registering a local binding in a set of scopes:
(define (add-local-binding! id phase counter #:frame-id [frame-id #f] #:in [in-s #f]) (define (add-local-binding! id phase counter #:frame-id [frame-id #f] #:in [in-s #f])

View File

@ -49,6 +49,7 @@
requires ; mpi [interned] -> require-phase -> sym -> list-ish of [bulk-]required requires ; mpi [interned] -> require-phase -> sym -> list-ish of [bulk-]required
provides ; phase -> sym -> binding or protected provides ; phase -> sym -> binding or protected
phase-to-defined-syms ; phase -> sym -> boolean phase-to-defined-syms ; phase -> sym -> boolean
also-required ; sym -> binding
[can-cross-phase-persistent? #:mutable] [can-cross-phase-persistent? #:mutable]
[all-bindings-simple? #:mutable]) ; tracks whether bindings are easily reconstructed [all-bindings-simple? #:mutable]) ; tracks whether bindings are easily reconstructed
#:authentic) #:authentic)
@ -82,6 +83,7 @@
(make-hasheq) ; requires (make-hasheq) ; requires
(make-hasheqv) ; provides (make-hasheqv) ; provides
(make-hasheqv) ; phase-to-defined-syms (make-hasheqv) ; phase-to-defined-syms
(make-hasheq) ; also-required
#t #t
#t)) #t))
@ -90,7 +92,8 @@
;; all previously required modules ;; all previously required modules
(hash-clear! (requires+provides-requires r+p)) (hash-clear! (requires+provides-requires r+p))
(hash-clear! (requires+provides-provides r+p)) (hash-clear! (requires+provides-provides r+p))
(hash-clear! (requires+provides-phase-to-defined-syms r+p))) (hash-clear! (requires+provides-phase-to-defined-syms r+p))
(hash-clear! (requires+provides-also-required r+p)))
;; ---------------------------------------- ;; ----------------------------------------
@ -150,7 +153,8 @@
(hash-ref sym-to-reqds sym null)))) (hash-ref sym-to-reqds sym null))))
;; Like `add-defined-or-required-id!`, but faster for bindings that ;; Like `add-defined-or-required-id!`, but faster for bindings that
;; all have the same scope, etc. ;; all have the same scope, etc.<
;; Return #t if any required id is already defined by a shaodwing definition.
(define (add-bulk-required-ids! r+p s self nominal-module phase-shift provides provide-phase-level (define (add-bulk-required-ids! r+p s self nominal-module phase-shift provides provide-phase-level
#:prefix bulk-prefix #:prefix bulk-prefix
#:excepts bulk-excepts #:excepts bulk-excepts
@ -169,29 +173,38 @@
(define sym-to-reqds (hash-ref! at-mod phase-shift make-hasheq)) (define sym-to-reqds (hash-ref! at-mod phase-shift make-hasheq))
(define prefix-len (if bulk-prefix (string-length (symbol->string bulk-prefix)) 0)) (define prefix-len (if bulk-prefix (string-length (symbol->string bulk-prefix)) 0))
(define br (bulk-required provides prefix-len s provide-phase-level can-be-shadowed?)) (define br (bulk-required provides prefix-len s provide-phase-level can-be-shadowed?))
(for ([(out-sym binding/p) (in-hash provides)]) (for/or ([(out-sym binding/p) (in-hash provides)])
(when symbols-accum (hash-set! symbols-accum out-sym #t)) (when symbols-accum (hash-set! symbols-accum out-sym #t))
(unless (hash-ref bulk-excepts out-sym #f) (cond
(define sym (cond [(hash-ref bulk-excepts out-sym #f)
[(not bulk-prefix) out-sym] #f]
[else (string->symbol (format "~a~a" bulk-prefix out-sym))])) [else
(when (and check-and-remove? (define sym (cond
[(not bulk-prefix) out-sym]
[else (string->symbol (format "~a~a" bulk-prefix out-sym))]))
(define already-defined?
(cond
[(and check-and-remove?
(or (not shortcut-table) (or (not shortcut-table)
(hash-ref shortcut-table sym #f))) (hash-ref shortcut-table sym #f)))
(check-not-defined #:check-not-required? #t (check-not-defined #:check-not-required? #t
r+p (datum->syntax s sym s) phase #:in orig-s #:allow-defined? #t
#:unless-matches r+p (datum->syntax s sym s) phase #:in orig-s
(lambda () #:unless-matches
(provide-binding-to-require-binding binding/p (lambda ()
sym (provide-binding-to-require-binding binding/p
#:self self sym
#:mpi mpi #:self self
#:provide-phase-level provide-phase-level #:mpi mpi
#:phase-shift phase-shift)) #:provide-phase-level provide-phase-level
#:remove-shadowed!? #t #:phase-shift phase-shift))
#:accum-update-nominals accum-update-nominals #:remove-shadowed!? #t
#:who who)) #:accum-update-nominals accum-update-nominals
(hash-set! sym-to-reqds sym (cons-ish br (hash-ref sym-to-reqds sym null)))))) #:who who)]
[else #f]))
(unless already-defined?
(hash-set! sym-to-reqds sym (cons-ish br (hash-ref sym-to-reqds sym null))))
already-defined?])))
;; Convert a combination of a symbol and `bulk-required` to a ;; Convert a combination of a symbol and `bulk-required` to a
;; `required` on demand ;; `required` on demand
@ -266,8 +279,10 @@
;; Check whether an identifier has a binding that is from a non-shadowable ;; Check whether an identifier has a binding that is from a non-shadowable
;; require; if something is found but it will be replaced, then record that ;; require; if something is found but it will be replaced, then record that
;; bindings are not simple. ;; bindings are not simple. Returns a boolean to dincate whether the binding
;; is defined already, since `allow-defined?` allows the result to be #t.
(define (check-not-defined #:check-not-required? [check-not-required? #f] (define (check-not-defined #:check-not-required? [check-not-required? #f]
#:allow-defined? [allow-defined? #f]
r+p id phase #:in orig-s r+p id phase #:in orig-s
#:unless-matches [ok-binding/delayed #f] ; binding or (-> binding) #:unless-matches [ok-binding/delayed #f] ; binding or (-> binding)
#:remove-shadowed!? [remove-shadowed!? #f] #:remove-shadowed!? [remove-shadowed!? #f]
@ -275,7 +290,7 @@
#:who who) #:who who)
(define b (resolve+shift id phase #:exactly? #t)) (define b (resolve+shift id phase #:exactly? #t))
(cond (cond
[(not b) (void)] [(not b) #f]
[(not (module-binding? b)) [(not (module-binding? b))
(raise-syntax-error #f "identifier out of context" id)] (raise-syntax-error #f "identifier out of context" id)]
[else [else
@ -285,7 +300,11 @@
[(and (not defined?) (not check-not-required?)) [(and (not defined?) (not check-not-required?))
;; Not defined, and we're shadowing all requires -- so, it's ok, ;; Not defined, and we're shadowing all requires -- so, it's ok,
;; but binding is non-simple ;; but binding is non-simple
(set-requires+provides-all-bindings-simple?! r+p #f)] (set-requires+provides-all-bindings-simple?! r+p #f)
;; Also, record the `require` binding, in case we see another
;; `require` for the same identifier
(hash-set! (requires+provides-also-required r+p) (module-binding-sym b) b)
#f]
[(and defined? [(and defined?
;; In case `#%module-begin` is expanded multiple times, check ;; In case `#%module-begin` is expanded multiple times, check
;; that the definition has been seen this particular expansion ;; that the definition has been seen this particular expansion
@ -295,19 +314,30 @@
(module-binding-sym b) (module-binding-sym b)
#f))) #f)))
;; Doesn't count as previously defined ;; Doesn't count as previously defined
(void)] #f]
[else [else
(define mpi (intern-mpi r+p (module-binding-nominal-module b))) (define mpi (intern-mpi r+p (module-binding-nominal-module b)))
(define at-mod (hash-ref (requires+provides-requires r+p) mpi #f)) (define at-mod (hash-ref (requires+provides-requires r+p) mpi #f))
(define ok-binding (if (procedure? ok-binding/delayed) (define ok-binding (if (procedure? ok-binding/delayed)
(ok-binding/delayed) (ok-binding/delayed)
ok-binding/delayed)) ok-binding/delayed))
(define (raise-already-bound defined?)
(raise-syntax-error who
(string-append "identifier already "
(if defined? "defined" "required")
(cond
[(zero-phase? phase) ""]
[(label-phase? phase) " for label"]
[(= 1 phase) " for syntax"]
[else (format " for phase ~a" phase)]))
orig-s
id))
(cond (cond
[(not at-mod) [(not at-mod)
;; Binding is from an enclosing context; if it's from an ;; Binding is from an enclosing context; if it's from an
;; enclosing module, then we've already marked bindings ;; enclosing module, then we've already marked bindings
;; a non-simple --- otherwise, we don't care ;; a non-simple --- otherwise, we don't care
(void)] #f]
[(and ok-binding (same-binding? b ok-binding)) [(and ok-binding (same-binding? b ok-binding))
;; It's the same binding already, so overall binding hasn't ;; It's the same binding already, so overall binding hasn't
;; become non-simple ;; become non-simple
@ -327,7 +357,19 @@
;; We can't reset now, because the caller is preparing for ;; We can't reset now, because the caller is preparing for
;; a bulk bind. Record that we need to merge nominals. ;; a bulk bind. Record that we need to merge nominals.
(set-box! accum-update-nominals (cons update! (unbox accum-update-nominals)))] (set-box! accum-update-nominals (cons update! (unbox accum-update-nominals)))]
[else (update!)]))] [else (update!)]))
defined?]
[(and defined? allow-defined?)
;; A `require` doesn't conflict with a definition, even if we
;; saw the definition earlier; but make sure there are not multiple
;; `require`s (any one of which would be shadowed by the definition)
(define also-required (requires+provides-also-required r+p))
(define prev-b (hash-ref also-required (module-binding-sym b) #f))
(when (and prev-b (not (same-binding? ok-binding prev-b)))
(raise-already-bound #f))
(hash-set! also-required (module-binding-sym b) ok-binding)
(set-requires+provides-all-bindings-simple?! r+p #f)
#t]
[else [else
(define nominal-phase (module-binding-nominal-require-phase b)) (define nominal-phase (module-binding-nominal-require-phase b))
(define sym-to-reqds (hash-ref at-mod nominal-phase #hasheq())) (define sym-to-reqds (hash-ref at-mod nominal-phase #hasheq()))
@ -339,21 +381,12 @@
(required-can-be-shadowed? r)) (required-can-be-shadowed? r))
;; Shadowing --- ok, but non-simple ;; Shadowing --- ok, but non-simple
(set-requires+provides-all-bindings-simple?! r+p #f)] (set-requires+provides-all-bindings-simple?! r+p #f)]
[else [else (raise-already-bound defined?)]))
(raise-syntax-error who
(string-append "identifier already "
(if defined? "defined" "required")
(cond
[(zero-phase? phase) ""]
[(label-phase? phase) " for label"]
[(= 1 phase) " for syntax"]
[else (format " for phase ~a" phase)]))
orig-s
id)]))
(when (and remove-shadowed!? (not (null? reqds))) (when (and remove-shadowed!? (not (null? reqds)))
;; Same work as in `remove-required-id!` ;; Same work as in `remove-required-id!`
(hash-set! sym-to-reqds (syntax-e id) (hash-set! sym-to-reqds (syntax-e id)
(remove-non-matching-requireds reqds id phase mpi nominal-phase (syntax-e id))))])])])) (remove-non-matching-requireds reqds id phase mpi nominal-phase (syntax-e id))))
#f])])]))
(define (add-defined-syms! r+p syms phase) (define (add-defined-syms! r+p syms phase)
(define phase-to-defined-syms (requires+provides-phase-to-defined-syms r+p)) (define phase-to-defined-syms (requires+provides-phase-to-defined-syms r+p))

View File

@ -258,6 +258,7 @@
m m
bind-in-stx phase-shift m-ns interned-mpi module-name bind-in-stx phase-shift m-ns interned-mpi module-name
#:in orig-s #:in orig-s
#:defines-mpi (and requires+provides (requires+provides-self requires+provides))
#:only (cond #:only (cond
[(adjust-only? adjust) (set->list (adjust-only-syms adjust))] [(adjust-only? adjust) (set->list (adjust-only-syms adjust))]
[(adjust-rename? adjust) (list (adjust-rename-from-sym adjust))] [(adjust-rename? adjust) (list (adjust-rename-from-sym adjust))]
@ -271,6 +272,7 @@
requires+provides requires+provides
can-bulk-bind? can-bulk-bind?
(lambda (provides provide-phase-level) (lambda (provides provide-phase-level)
;; Returns #t if any binding is already shadowed by a definition:
(add-bulk-required-ids! requires+provides (add-bulk-required-ids! requires+provides
bind-in-stx bind-in-stx
(module-self m) mpi phase-shift (module-self m) mpi phase-shift
@ -314,28 +316,37 @@
(and (eq? sym (adjust-rename-from-sym adjust)) (and (eq? sym (adjust-rename-from-sym adjust))
(hash-set! done-syms sym #t) (hash-set! done-syms sym #t)
(adjust-rename-to-id adjust))])) (adjust-rename-to-id adjust))]))
(when (and adjusted-sym requires+provides) (define skip-bind?
(define s (datum->syntax bind-in-stx adjusted-sym)) (cond
(define bind-phase (phase+ phase-shift provide-phase)) [(and adjusted-sym requires+provides)
(unless initial-require? (define s (datum->syntax bind-in-stx adjusted-sym))
(check-not-defined #:check-not-required? #t (define bind-phase (phase+ phase-shift provide-phase))
requires+provides (define skip-bind?
s bind-phase (cond
#:unless-matches binding [initial-require? #f]
#:in orig-s [else
#:remove-shadowed!? #t (check-not-defined #:check-not-required? #t
#:who who)) #:allow-defined? #t ; `define` shadows `require`
(add-defined-or-required-id! requires+provides requires+provides
s bind-phase binding s bind-phase
#:can-be-shadowed? can-be-shadowed? #:unless-matches binding
#:as-transformer? as-transformer?)) #:in orig-s
#:remove-shadowed!? #t
#:who who)]))
(unless skip-bind?
(add-defined-or-required-id! requires+provides
s bind-phase binding
#:can-be-shadowed? can-be-shadowed?
#:as-transformer? as-transformer?))
skip-bind?]
[else #f]))
(when (and adjusted-sym (when (and adjusted-sym
copy-variable-phase-level copy-variable-phase-level
(not as-transformer?) (not as-transformer?)
(equal? provide-phase copy-variable-phase-level)) (equal? provide-phase copy-variable-phase-level))
(copy-namespace-value m-ns adjusted-sym binding copy-variable-phase-level phase-shift (copy-namespace-value m-ns adjusted-sym binding copy-variable-phase-level phase-shift
copy-variable-as-constant?)) copy-variable-as-constant?))
adjusted-sym))) (and (not skip-bind?) adjusted-sym))))
;; Now that a bulk binding is in place, update to merge nominals: ;; Now that a bulk binding is in place, update to merge nominals:
(when update-nominals-box (when update-nominals-box
(for ([update! (in-list (unbox update-nominals-box))]) (for ([update! (in-list (unbox update-nominals-box))])
@ -359,6 +370,7 @@
(define (bind-all-provides! m in-stx phase-shift ns mpi module-name (define (bind-all-provides! m in-stx phase-shift ns mpi module-name
#:in orig-s #:in orig-s
#:defines-mpi defines-mpi
#:only only-syms #:only only-syms
#:just-meta just-meta #:just-meta just-meta
#:bind? bind? #:bind? bind?
@ -372,8 +384,9 @@
#:when (or (eq? just-meta 'all) #:when (or (eq? just-meta 'all)
(eqv? just-meta provide-phase-level))) (eqv? just-meta provide-phase-level)))
(define phase (phase+ phase-shift provide-phase-level)) (define phase (phase+ phase-shift provide-phase-level))
(when bulk-callback (define need-except?
(bulk-callback provides provide-phase-level)) (and bulk-callback
(bulk-callback provides provide-phase-level)))
(when bind? (when bind?
(when filter (when filter
(for ([sym (in-list (or only-syms (hash-keys provides)))]) (for ([sym (in-list (or only-syms (hash-keys provides)))])
@ -408,7 +421,8 @@
self mpi provide-phase-level phase-shift self mpi provide-phase-level phase-shift
bulk-binding-registry) bulk-binding-registry)
phase phase
#:in orig-s))))) #:in orig-s
#:shadow-except (and need-except? defines-mpi))))))
;; ---------------------------------------- ;; ----------------------------------------

View File

@ -3,7 +3,8 @@
"../common/set.rkt" "../common/set.rkt"
"../compile/serialize-property.rkt" "../compile/serialize-property.rkt"
"../compile/serialize-state.rkt" "../compile/serialize-state.rkt"
"syntax.rkt") "syntax.rkt"
"module-binding.rkt")
;; A binding table within a scope maps symbol plus scope set ;; A binding table within a scope maps symbol plus scope set
;; combinations (where the scope binding the binding table is always ;; combinations (where the scope binding the binding table is always
@ -105,7 +106,7 @@
just-for-nominal?)) just-for-nominal?))
;; Keep `syms/serialize` in sync with `syms`, except for bindings ;; Keep `syms/serialize` in sync with `syms`, except for bindings
;; that are just to extend the set of nominal imports. We keep those ;; that are just to extend the set of nominal imports. We keep those
;; separate --- and don't serialize them --- because they interfere ;; separate --- and don't serialize them --- because they interfere
;; with bulk representations of binding and they're used only to ;; with bulk representations of binding and they're used only to
;; commuincate to `provide`. ;; commuincate to `provide`.
(define new-syms/serialize (define new-syms/serialize
@ -124,18 +125,21 @@
[syms/serialize new-syms/serialize])])) [syms/serialize new-syms/serialize])]))
;; Adding a binding for a computed-on-demand set of symbols ;; Adding a binding for a computed-on-demand set of symbols
(define (binding-table-add-bulk bt scopes bulk) (define (binding-table-add-bulk bt scopes bulk
#:shadow-except [shadow-except #f])
(cond (cond
[(table-with-bulk-bindings? bt) [(table-with-bulk-bindings? bt)
(define new-syms (remove-matching-bindings (table-with-bulk-bindings-syms bt) (define new-syms (remove-matching-bindings (table-with-bulk-bindings-syms bt)
scopes scopes
bulk)) bulk
#:except shadow-except))
(define new-syms/serialize (if (eq? (table-with-bulk-bindings-syms bt) (define new-syms/serialize (if (eq? (table-with-bulk-bindings-syms bt)
(table-with-bulk-bindings-syms/serialize bt)) (table-with-bulk-bindings-syms/serialize bt))
new-syms new-syms
(remove-matching-bindings (table-with-bulk-bindings-syms/serialize bt) (remove-matching-bindings (table-with-bulk-bindings-syms/serialize bt)
scopes scopes
bulk))) bulk
#:except shadow-except)))
(table-with-bulk-bindings new-syms (table-with-bulk-bindings new-syms
new-syms/serialize new-syms/serialize
(cons (bulk-binding-at scopes bulk) (cons (bulk-binding-at scopes bulk)
@ -144,28 +148,36 @@
(binding-table-add-bulk (table-with-bulk-bindings bt bt null) scopes bulk)])) (binding-table-add-bulk (table-with-bulk-bindings bt bt null) scopes bulk)]))
;; The bindings of `bulk` at `scopes` should shadow any existing ;; The bindings of `bulk` at `scopes` should shadow any existing
;; mappings in `sym-bindings` ;; mappings in `sym-bindings`, except one for `except`
(define (remove-matching-bindings syms scopes bulk) (define (remove-matching-bindings syms scopes bulk #:except except)
(define bulk-symbols (bulk-binding-symbols bulk #f null)) (define bulk-symbols (bulk-binding-symbols bulk #f null))
(cond (cond
[((hash-count syms) . < . (hash-count bulk-symbols)) [((hash-count syms) . < . (hash-count bulk-symbols))
;; Faster to consider each sym in `sym-binding` ;; Faster to consider each sym in `syms`
(for/fold ([syms syms]) ([(sym sym-bindings) (in-immutable-hash syms)]) (for/fold ([syms syms]) ([(sym sym-bindings) (in-immutable-hash syms)])
(if (hash-ref bulk-symbols sym #f) (if (hash-ref bulk-symbols sym #f)
(remove-matching-binding syms sym sym-bindings scopes) (remove-matching-binding syms sym sym-bindings scopes #:except except)
syms))] syms))]
[else [else
;; Faster to consider each sym in `bulk-symbols` ;; Faster to consider each sym in `bulk-symbols`
(for/fold ([syms syms]) ([sym (in-immutable-hash-keys bulk-symbols)]) (for/fold ([syms syms]) ([sym (in-immutable-hash-keys bulk-symbols)])
(define sym-bindings (hash-ref syms sym #f)) (define sym-bindings (hash-ref syms sym #f))
(if sym-bindings (if sym-bindings
(remove-matching-binding syms sym sym-bindings scopes) (remove-matching-binding syms sym sym-bindings scopes #:except except)
syms))])) syms))]))
;; Update an individual symbol's bindings to remove a mapping ;; Update an individual symbol's bindings to remove a mapping
;; for a given set of scopes ;; for a given set of scopes
(define (remove-matching-binding syms sym sym-bindings scopes) (define (remove-matching-binding syms sym sym-bindings scopes #:except except)
(hash-set syms sym (hash-remove sym-bindings scopes))) (cond
[(and except
(let ([b (hash-ref sym-bindings scopes #f)])
(and (module-binding? b)
(eq? except (module-binding-module b)))))
;; Don't replace a shadowing definition
syms]
[else
(hash-set syms sym (hash-remove sym-bindings scopes))]))
;; ---------------------------------------- ;; ----------------------------------------

View File

@ -741,9 +741,11 @@
(set-scope-binding-table! max-sc bt) (set-scope-binding-table! max-sc bt)
(clear-resolve-cache! sym)) (clear-resolve-cache! sym))
(define (add-bulk-binding-in-scopes! scopes bulk-binding) (define (add-bulk-binding-in-scopes! scopes bulk-binding
#:shadow-except [shadow-except #f])
(define max-sc (find-max-scope scopes)) (define max-sc (find-max-scope scopes))
(define bt (binding-table-add-bulk (scope-binding-table max-sc) scopes bulk-binding)) (define bt (binding-table-add-bulk (scope-binding-table max-sc) scopes bulk-binding
#:shadow-except shadow-except))
(set-scope-binding-table! max-sc bt) (set-scope-binding-table! max-sc bt)
(clear-resolve-cache!)) (clear-resolve-cache!))

File diff suppressed because it is too large Load Diff