terminology change again: "cross-phases persistent" modules
This commit is contained in:
parent
c1469b9480
commit
88a36a077c
|
@ -1091,7 +1091,7 @@
|
||||||
[l (cons lang-info l)] ; lang-info
|
[l (cons lang-info l)] ; lang-info
|
||||||
[l (cons (map convert-module post-submodules) l)]
|
[l (cons (map convert-module post-submodules) l)]
|
||||||
[l (cons (map convert-module pre-submodules) l)]
|
[l (cons (map convert-module pre-submodules) l)]
|
||||||
[l (cons (if (memq 'phase-collapsing flags) #t #f) l)]
|
[l (cons (if (memq 'cross-phase flags) #t #f) l)]
|
||||||
[l (cons self-modidx l)]
|
[l (cons self-modidx l)]
|
||||||
[l (cons srcname l)]
|
[l (cons srcname l)]
|
||||||
[l (cons (if (pair? name) (car name) name) l)]
|
[l (cons (if (pair? name) (car name) name) l)]
|
||||||
|
|
|
@ -251,7 +251,7 @@
|
||||||
(define (read-module v)
|
(define (read-module v)
|
||||||
(match v
|
(match v
|
||||||
[`(,submod-path
|
[`(,submod-path
|
||||||
,name ,srcname ,self-modidx ,phase-collapsing?
|
,name ,srcname ,self-modidx ,cross-phase?
|
||||||
,pre-submods ,post-submods
|
,pre-submods ,post-submods
|
||||||
,lang-info ,functional? ,et-functional?
|
,lang-info ,functional? ,et-functional?
|
||||||
,rename ,max-let-depth ,dummy
|
,rename ,max-let-depth ,dummy
|
||||||
|
@ -337,7 +337,7 @@
|
||||||
dummy
|
dummy
|
||||||
lang-info
|
lang-info
|
||||||
rename
|
rename
|
||||||
(if phase-collapsing? '(phase-collapsing) '())
|
(if cross-phase? '(cross-phase) '())
|
||||||
(map read-module pre-submods)
|
(map read-module pre-submods)
|
||||||
(map read-module post-submods))]))]))
|
(map read-module post-submods))]))]))
|
||||||
(define (read-module-wrap v)
|
(define (read-module-wrap v)
|
||||||
|
|
|
@ -139,7 +139,7 @@
|
||||||
[dummy toplevel?]
|
[dummy toplevel?]
|
||||||
[lang-info (or/c #f (vector/c module-path? symbol? any/c))]
|
[lang-info (or/c #f (vector/c module-path? symbol? any/c))]
|
||||||
[internal-context (or/c #f #t stx? (vectorof stx?))]
|
[internal-context (or/c #f #t stx? (vectorof stx?))]
|
||||||
[flags (listof (or/c 'phase-collapsing))]
|
[flags (listof (or/c 'cross-phase))]
|
||||||
[pre-submodules (listof mod?)]
|
[pre-submodules (listof mod?)]
|
||||||
[post-submodules (listof mod?)]))
|
[post-submodules (listof mod?)]))
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ binding, constructor, etc.}
|
||||||
[dummy toplevel?]
|
[dummy toplevel?]
|
||||||
[lang-info (or/c #f (vector/c module-path? symbol? any/c))]
|
[lang-info (or/c #f (vector/c module-path? symbol? any/c))]
|
||||||
[internal-context (or/c #f #t stx? (vectorof stx?))]
|
[internal-context (or/c #f #t stx? (vectorof stx?))]
|
||||||
[flags (listof (or/c 'phase-collapsing))]
|
[flags (listof (or/c 'cross-phase))]
|
||||||
[pre-submodules (listof mod?)]
|
[pre-submodules (listof mod?)]
|
||||||
[post-submodules (listof mod?)])]{
|
[post-submodules (listof mod?)])]{
|
||||||
Represents a @racket[module] declaration.
|
Represents a @racket[module] declaration.
|
||||||
|
@ -248,7 +248,7 @@ binding, constructor, etc.}
|
||||||
syntax-object value embeds an arbitrary lexical context.
|
syntax-object value embeds an arbitrary lexical context.
|
||||||
|
|
||||||
The @racket[flags] field records certain properties of the module.
|
The @racket[flags] field records certain properties of the module.
|
||||||
The @racket['phase-collapsing] flag indicates that the module body is
|
The @racket['cross-phase] flag indicates that the module body is
|
||||||
evaluated once and the results shared across instances for all phases; such a
|
evaluated once and the results shared across instances for all phases; such a
|
||||||
module contains only definitions of functions, structure types, and
|
module contains only definitions of functions, structure types, and
|
||||||
structure type properties.
|
structure type properties.
|
||||||
|
|
|
@ -599,33 +599,33 @@ top-level variables in higher @tech{phases}, while module
|
||||||
top-levels are in corresponding higher @tech{phase}s.
|
top-levels are in corresponding higher @tech{phase}s.
|
||||||
|
|
||||||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@subsection[#:tag "phase-collapsing-modules"]{Phase-Collapsing Modules}
|
@subsection[#:tag "cross-phase persistent-modules"]{Cross-Phase Persistent Modules}
|
||||||
|
|
||||||
Module declarations that fit a highly constrained form create
|
Module declarations that fit a highly constrained form create
|
||||||
@deftech{phase-collapsing} modules. A @tech{phase-collapsing} module's
|
@deftech{cross-phase persistent} modules. A @tech{cross-phase persistent} module's
|
||||||
instantiations across all phases and @tech{module registries} share
|
instantiations across all phases and @tech{module registries} share
|
||||||
the variables produced by the first instantiation of the module.
|
the variables produced by the first instantiation of the module.
|
||||||
|
|
||||||
The intent of a @tech{phase-collapsing} module is to support values that are
|
The intent of a @tech{cross-phase persistent} module is to support values that are
|
||||||
recognizable after @tech{phase} crossings. For example, when a macro
|
recognizable after @tech{phase} crossings. For example, when a macro
|
||||||
transformer running in phase 1 raises a syntax error as represented by
|
transformer running in phase 1 raises a syntax error as represented by
|
||||||
a @racket[exn:fail:syntax] instance, the instance is recognizable by a
|
a @racket[exn:fail:syntax] instance, the instance is recognizable by a
|
||||||
phase-0 exception handler wrapping a call to @racket[eval] or
|
phase-0 exception handler wrapping a call to @racket[eval] or
|
||||||
@racket[expand] that triggered the syntax error, because the
|
@racket[expand] that triggered the syntax error, because the
|
||||||
@racket[exn:fail:syntax] structure type is defined by a
|
@racket[exn:fail:syntax] structure type is defined by a
|
||||||
@tech{phase-collapsing} module.
|
@tech{cross-phase persistent} module.
|
||||||
|
|
||||||
A @tech{phase-collapsing} module imports only other @tech{phase-collapsing} modules,
|
A @tech{cross-phase persistent} module imports only other @tech{cross-phase persistent} modules,
|
||||||
and it contains only definitions that bind variables to functions,
|
and it contains only definitions that bind variables to functions,
|
||||||
structure types and related functions, or structure-type properties
|
structure types and related functions, or structure-type properties
|
||||||
and related functions. A @tech{phase-collapsing} module never includes syntax
|
and related functions. A @tech{cross-phase persistent} module never includes syntax
|
||||||
literals (via @racket[quote-syntax]) or variable references (via
|
literals (via @racket[quote-syntax]) or variable references (via
|
||||||
@racket[#%variable-reference]). See @secref["phase-collapsing-grammar"] for
|
@racket[#%variable-reference]). See @secref["cross-phase persistent-grammar"] for
|
||||||
the syntactic specification of a @tech{phase-collapsing} module
|
the syntactic specification of a @tech{cross-phase persistent} module
|
||||||
declaration.
|
declaration.
|
||||||
|
|
||||||
A documented module should be assumed non-@tech{phase-collapsing} unless it
|
A documented module should be assumed non-@tech{cross-phase persistent} unless it
|
||||||
is specified as @tech{phase-collapsing} (such as
|
is specified as @tech{cross-phase persistent} (such as
|
||||||
@racketmodname[racket/kernel]).
|
@racketmodname[racket/kernel]).
|
||||||
|
|
||||||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -647,7 +647,7 @@ redeclared, each redeclaration of the module is immediately
|
||||||
|
|
||||||
If the current @tech{inspector} does not manage a module's declaration
|
If the current @tech{inspector} does not manage a module's declaration
|
||||||
inspector (see @secref["modprotect"]), then the module cannot be
|
inspector (see @secref["modprotect"]), then the module cannot be
|
||||||
redeclared. Similarly, a @tech{phase-collapsing} module cannot be redeclared.
|
redeclared. Similarly, a @tech{cross-phase persistent} module cannot be redeclared.
|
||||||
Even if redeclrection succeeds, instantiation of a module that is
|
Even if redeclrection succeeds, instantiation of a module that is
|
||||||
previously instantiated may fail if instantiation for the
|
previously instantiated may fail if instantiation for the
|
||||||
redeclaration attempts to modify variables that are constant (see
|
redeclaration attempts to modify variables that are constant (see
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
@title{Kernel Forms and Functions}
|
@title{Kernel Forms and Functions}
|
||||||
|
|
||||||
@defmodulelang[racket/kernel]{The @racketmodname[racket/kernel] library
|
@defmodulelang[racket/kernel]{The @racketmodname[racket/kernel] library
|
||||||
is a @tech{phase-collapsing} module that provides a minimal set of syntactic
|
is a @tech{cross-phase persistent} module that provides a minimal set of syntactic
|
||||||
forms and functions.}
|
forms and functions.}
|
||||||
|
|
||||||
``Minimal'' means that @racketmodname[racket/kernel] includes only
|
``Minimal'' means that @racketmodname[racket/kernel] includes only
|
||||||
|
|
|
@ -989,9 +989,9 @@ information. Inferred and property-assigned names are also available
|
||||||
to syntax transformers, via @racket[syntax-local-name].
|
to syntax transformers, via @racket[syntax-local-name].
|
||||||
|
|
||||||
@;----------------------------------------
|
@;----------------------------------------
|
||||||
@section[#:tag "phase-collapsing-grammar"]{Phase-Collapsing Module Declarations}
|
@section[#:tag "cross-phase persistent-grammar"]{Cross-Phase Persistent Module Declarations}
|
||||||
|
|
||||||
A module is @tech{phase-collapsing} only if it fits the following grammar,
|
A module is @tech{cross-phase persistent} only if it fits the following grammar,
|
||||||
which uses non-terminals from @secref["fully-expanded"], only if
|
which uses non-terminals from @secref["fully-expanded"], only if
|
||||||
it includes no uses of @racket[quote-syntax] or @racket[#%variable-reference],
|
it includes no uses of @racket[quote-syntax] or @racket[#%variable-reference],
|
||||||
and only if no module-level binding is @racket[set!]ed.
|
and only if no module-level binding is @racket[set!]ed.
|
||||||
|
@ -1003,33 +1003,31 @@ and only if no module-level binding is @racket[set!]ed.
|
||||||
set! quote-syntax quote with-continuation-mark
|
set! quote-syntax quote with-continuation-mark
|
||||||
#%plain-app
|
#%plain-app
|
||||||
cons list make-struct-type make-struct-type-property)
|
cons list make-struct-type make-struct-type-property)
|
||||||
[phase-collapse-module (module id module-path
|
[cross-module (module id module-path
|
||||||
(#%plain-module-begin
|
(#%plain-module-begin
|
||||||
phase-collapse-form ...))]
|
cross-form ...))]
|
||||||
[phase-collapse-form (begin phase-collapse-form ...)
|
[cross-form (begin cross-form ...)
|
||||||
(#%provide raw-provide-spec ...)
|
(#%provide raw-provide-spec ...)
|
||||||
submodule-form
|
submodule-form
|
||||||
(define-values (id ...)
|
(define-values (id ...) cross-expr)
|
||||||
phase-collapse-expr)
|
|
||||||
(#%require raw-require-spec ...)]
|
(#%require raw-require-spec ...)]
|
||||||
[phase-collapse-expr id
|
[cross-expr id
|
||||||
(@#,racket[quote] phase-collapse-datum)
|
(@#,racket[quote] cross-datum)
|
||||||
(#%plain-lambda formals expr ...+)
|
(#%plain-lambda formals expr ...+)
|
||||||
(case-lambda (formals expr ...+) ...)
|
(case-lambda (formals expr ...+) ...)
|
||||||
(#%plain-app cons expr ...+)
|
(#%plain-app cons expr ...+)
|
||||||
(#%plain-app list expr ...+)
|
(#%plain-app list expr ...+)
|
||||||
(#%plain-app make-struct-type expr ...+)
|
(#%plain-app make-struct-type expr ...+)
|
||||||
(#%plain-app make-struct-type-property
|
(#%plain-app make-struct-type-property expr ...+)]
|
||||||
expr ...+)]
|
[cross-datum number
|
||||||
[phase-collapse-datum number
|
|
||||||
boolean
|
boolean
|
||||||
identifier
|
identifier
|
||||||
string
|
string
|
||||||
bytes]
|
bytes]
|
||||||
]
|
]
|
||||||
|
|
||||||
This grammar applies after @tech{expansion}, but because a @tech{phase-collapsing}
|
This grammar applies after @tech{expansion}, but because a @tech{cross-phase persistent}
|
||||||
module imports only from other phase-collapsing modules, the only relevant
|
module imports only from other cross-phase persistent modules, the only relevant
|
||||||
expansion steps are the implicit introduction of
|
expansion steps are the implicit introduction of
|
||||||
@racket[#%plain-module-begin], implicit introduction of @racket[#%plain-app],
|
@racket[#%plain-module-begin], implicit introduction of @racket[#%plain-app],
|
||||||
and implicit introduction and/or expansion of @racket[#%datum].
|
and implicit introduction and/or expansion of @racket[#%datum].
|
||||||
|
|
96
collects/tests/racket/cross-phase.rkt
Normal file
96
collects/tests/racket/cross-phase.rkt
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#lang racket/base
|
||||||
|
(require compiler/zo-parse)
|
||||||
|
|
||||||
|
(define (check-cross-phase is? form)
|
||||||
|
(parameterize ([current-namespace (make-base-namespace)])
|
||||||
|
(define o (open-output-bytes))
|
||||||
|
(write (compile `(module m racket/kernel ,form)) o)
|
||||||
|
(close-output-port o)
|
||||||
|
(define i (open-input-bytes (get-output-bytes o)))
|
||||||
|
(define e (zo-parse i))
|
||||||
|
(unless (equal? is? (and (memq 'cross-phase (mod-flags (compilation-top-code e))) #t))
|
||||||
|
(error 'cross-phase "failed: ~s ~s" is? form))))
|
||||||
|
|
||||||
|
(check-cross-phase #t '(define-values (x) 5))
|
||||||
|
(check-cross-phase #t '(define-values (x) '5))
|
||||||
|
(check-cross-phase #t '(define-values (x) (#%datum . 5)))
|
||||||
|
(check-cross-phase #t '(define-values (x) #t))
|
||||||
|
(check-cross-phase #t '(define-values (x) 'x))
|
||||||
|
(check-cross-phase #t '(define-values (x) "x"))
|
||||||
|
(check-cross-phase #t '(define-values (x) #"x"))
|
||||||
|
(check-cross-phase #t '(define-values (x) cons))
|
||||||
|
(check-cross-phase #t '(define-values (x) (cons 1 2)))
|
||||||
|
(check-cross-phase #t '(define-values (x) (list 1 2)))
|
||||||
|
(check-cross-phase #t '(define-values (x) (cons 1 '())))
|
||||||
|
(check-cross-phase #t '(#%require racket/tcp))
|
||||||
|
(check-cross-phase #t '(define-values (x) (lambda (x) x)))
|
||||||
|
(check-cross-phase #t '(define-values (x) (case-lambda [(x) x] [y y])))
|
||||||
|
(check-cross-phase #t '(define-values (struct: ? -ref) (make-struct-type-property 'p)))
|
||||||
|
(check-cross-phase #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's #f 0 0)))
|
||||||
|
(check-cross-phase #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's struct:exn 0 0)))
|
||||||
|
(check-cross-phase #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's struct:exn 1 0 #f (list (cons prop:procedure 0)))))
|
||||||
|
(check-cross-phase #t '(begin
|
||||||
|
(define-values (x) 5)
|
||||||
|
(define-values (y) 6)))
|
||||||
|
|
||||||
|
(check-cross-phase #f '(define-values (x) #(x)))
|
||||||
|
(check-cross-phase #f '(define-values (x) '(x)))
|
||||||
|
(check-cross-phase #f '(define-values (x) (lambda () (set! x 8))))
|
||||||
|
(check-cross-phase #f '(define-values (x) (quote-syntax x)))
|
||||||
|
(check-cross-phase #f '(define-values (x) (lambda () (quote-syntax x))))
|
||||||
|
(check-cross-phase #f '(define-values (x) (#%variable-reference)))
|
||||||
|
(check-cross-phase #f '(define-values (x) (lambda () (#%variable-reference))))
|
||||||
|
(check-cross-phase #f '(define-values (x) (lambda () (if #f (#%variable-reference) 10))))
|
||||||
|
(check-cross-phase #f '(define-values (x) (#%variable-reference x)))
|
||||||
|
(check-cross-phase #f '(#%require racket/base))
|
||||||
|
|
||||||
|
(check-cross-phase #t '(module* sub #f (vector 1 2 3)))
|
||||||
|
(check-cross-phase #t '(module* sub #f (#%variable-reference)))
|
||||||
|
(check-cross-phase #t '(module* sub racket/base (#%variable-reference)))
|
||||||
|
(check-cross-phase #t '(module sub racket/base (#%variable-reference)))
|
||||||
|
|
||||||
|
;; Check phase crossing via an exception:
|
||||||
|
(parameterize ([current-namespace (make-base-namespace)])
|
||||||
|
(eval `(module m racket/kernel
|
||||||
|
(#%provide s? make-s)
|
||||||
|
(define-values (struct:s make-s s? s-ref s-set!) (make-struct-type 's #f 0 0))))
|
||||||
|
(eval '(require 'm))
|
||||||
|
(define s? (eval 's?))
|
||||||
|
(eval '(require (for-syntax racket/base 'm)))
|
||||||
|
(eval '(define-syntax (m stx) (raise (make-s))))
|
||||||
|
(with-handlers ([s? void])
|
||||||
|
(eval '(m)))
|
||||||
|
(define (check-exn)
|
||||||
|
(with-handlers ([s? void])
|
||||||
|
(eval '(module n racket/base
|
||||||
|
(require (for-syntax racket/base 'm))
|
||||||
|
(begin-for-syntax
|
||||||
|
(raise (make-s)))))))
|
||||||
|
(check-exn)
|
||||||
|
(define (check-attach namespace-attach-module)
|
||||||
|
(define ns (make-base-namespace))
|
||||||
|
(namespace-attach-module (current-namespace) ''m ns)
|
||||||
|
(parameterize ([current-namespace ns])
|
||||||
|
(check-exn)))
|
||||||
|
(check-attach namespace-attach-module)
|
||||||
|
(check-attach namespace-attach-module-declaration))
|
||||||
|
|
||||||
|
;; Check disallowing redeclaration:
|
||||||
|
(parameterize ([current-namespace (make-base-namespace)])
|
||||||
|
(parameterize ([compile-enforce-module-constants #f])
|
||||||
|
(eval `(module m racket/kernel
|
||||||
|
(#%provide x)
|
||||||
|
(define-values (x) 5)))
|
||||||
|
(compile `(module m racket/kernel
|
||||||
|
(#%provide x)
|
||||||
|
(define-values (x) 6)))
|
||||||
|
(unless (void?
|
||||||
|
(with-handlers ([exn:fail? void])
|
||||||
|
(eval `(module m racket/kernel
|
||||||
|
(#%provide x)
|
||||||
|
(define-values (x) 6)))
|
||||||
|
'ok))
|
||||||
|
(error 'cross-phase "redeclaration should have been disallowed"))))
|
||||||
|
|
||||||
|
(displayln "All tests passed.")
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
#lang racket/base
|
|
||||||
(require compiler/zo-parse)
|
|
||||||
|
|
||||||
(define (check-phase-collapsing is? form)
|
|
||||||
(parameterize ([current-namespace (make-base-namespace)])
|
|
||||||
(define o (open-output-bytes))
|
|
||||||
(write (compile `(module m racket/kernel ,form)) o)
|
|
||||||
(close-output-port o)
|
|
||||||
(define i (open-input-bytes (get-output-bytes o)))
|
|
||||||
(define e (zo-parse i))
|
|
||||||
(unless (equal? is? (and (memq 'phase-collapsing (mod-flags (compilation-top-code e))) #t))
|
|
||||||
(error 'phase-collapsing "failed: ~s ~s" is? form))))
|
|
||||||
|
|
||||||
(check-phase-collapsing #t '(define-values (x) 5))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) '5))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) (#%datum . 5)))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) #t))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) 'x))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) "x"))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) #"x"))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) cons))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) (cons 1 2)))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) (list 1 2)))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) (cons 1 '())))
|
|
||||||
(check-phase-collapsing #t '(#%require racket/tcp))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) (lambda (x) x)))
|
|
||||||
(check-phase-collapsing #t '(define-values (x) (case-lambda [(x) x] [y y])))
|
|
||||||
(check-phase-collapsing #t '(define-values (struct: ? -ref) (make-struct-type-property 'p)))
|
|
||||||
(check-phase-collapsing #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's #f 0 0)))
|
|
||||||
(check-phase-collapsing #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's struct:exn 0 0)))
|
|
||||||
(check-phase-collapsing #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's struct:exn 1 0 #f (list (cons prop:procedure 0)))))
|
|
||||||
(check-phase-collapsing #t '(begin
|
|
||||||
(define-values (x) 5)
|
|
||||||
(define-values (y) 6)))
|
|
||||||
|
|
||||||
(check-phase-collapsing #f '(define-values (x) #(x)))
|
|
||||||
(check-phase-collapsing #f '(define-values (x) '(x)))
|
|
||||||
(check-phase-collapsing #f '(define-values (x) (lambda () (set! x 8))))
|
|
||||||
(check-phase-collapsing #f '(define-values (x) (quote-syntax x)))
|
|
||||||
(check-phase-collapsing #f '(define-values (x) (lambda () (quote-syntax x))))
|
|
||||||
(check-phase-collapsing #f '(define-values (x) (#%variable-reference)))
|
|
||||||
(check-phase-collapsing #f '(define-values (x) (lambda () (#%variable-reference))))
|
|
||||||
(check-phase-collapsing #f '(define-values (x) (lambda () (if #f (#%variable-reference) 10))))
|
|
||||||
(check-phase-collapsing #f '(define-values (x) (#%variable-reference x)))
|
|
||||||
(check-phase-collapsing #f '(#%require racket/base))
|
|
||||||
|
|
||||||
(check-phase-collapsing #t '(module* sub #f (vector 1 2 3)))
|
|
||||||
(check-phase-collapsing #t '(module* sub #f (#%variable-reference)))
|
|
||||||
(check-phase-collapsing #t '(module* sub racket/base (#%variable-reference)))
|
|
||||||
(check-phase-collapsing #t '(module sub racket/base (#%variable-reference)))
|
|
||||||
|
|
||||||
;; Check phase crossing via an exception:
|
|
||||||
(parameterize ([current-namespace (make-base-namespace)])
|
|
||||||
(eval `(module m racket/kernel
|
|
||||||
(#%provide s? make-s)
|
|
||||||
(define-values (struct:s make-s s? s-ref s-set!) (make-struct-type 's #f 0 0))))
|
|
||||||
(eval '(require 'm))
|
|
||||||
(define s? (eval 's?))
|
|
||||||
(eval '(require (for-syntax racket/base 'm)))
|
|
||||||
(eval '(define-syntax (m stx) (raise (make-s))))
|
|
||||||
(with-handlers ([s? void])
|
|
||||||
(eval '(m)))
|
|
||||||
(define (check-exn)
|
|
||||||
(with-handlers ([s? void])
|
|
||||||
(eval '(module n racket/base
|
|
||||||
(require (for-syntax racket/base 'm))
|
|
||||||
(begin-for-syntax
|
|
||||||
(raise (make-s)))))))
|
|
||||||
(check-exn)
|
|
||||||
(define (check-attach namespace-attach-module)
|
|
||||||
(define ns (make-base-namespace))
|
|
||||||
(namespace-attach-module (current-namespace) ''m ns)
|
|
||||||
(parameterize ([current-namespace ns])
|
|
||||||
(check-exn)))
|
|
||||||
(check-attach namespace-attach-module)
|
|
||||||
(check-attach namespace-attach-module-declaration))
|
|
||||||
|
|
||||||
;; Check disallowing redeclaration:
|
|
||||||
(parameterize ([current-namespace (make-base-namespace)])
|
|
||||||
(parameterize ([compile-enforce-module-constants #f])
|
|
||||||
(eval `(module m racket/kernel
|
|
||||||
(#%provide x)
|
|
||||||
(define-values (x) 5)))
|
|
||||||
(compile `(module m racket/kernel
|
|
||||||
(#%provide x)
|
|
||||||
(define-values (x) 6)))
|
|
||||||
(unless (void?
|
|
||||||
(with-handlers ([exn:fail? void])
|
|
||||||
(eval `(module m racket/kernel
|
|
||||||
(#%provide x)
|
|
||||||
(define-values (x) 6)))
|
|
||||||
'ok))
|
|
||||||
(error 'phase-collapsing "redeclaration should have been disallowed"))))
|
|
||||||
|
|
||||||
(displayln "All tests passed.")
|
|
||||||
|
|
|
@ -6380,7 +6380,7 @@ static Scheme_Object *do_module_execute(Scheme_Object *data, Scheme_Env *genv,
|
||||||
|
|
||||||
if (old_m && old_m->phaseless) {
|
if (old_m && old_m->phaseless) {
|
||||||
scheme_contract_error("module->namespace",
|
scheme_contract_error("module->namespace",
|
||||||
"cannot redeclare phase-collapsing module",
|
"cannot redeclare cross-phase persistent module",
|
||||||
"module name", 1, m->modname,
|
"module name", 1, m->modname,
|
||||||
NULL);
|
NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -5216,7 +5216,7 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
scheme_log(info->logger,
|
scheme_log(info->logger,
|
||||||
SCHEME_LOG_DEBUG,
|
SCHEME_LOG_DEBUG,
|
||||||
0,
|
0,
|
||||||
"compilation of phase-collapsing module: %D",
|
"compilation of cross-phase persistent module: %D",
|
||||||
m->modname);
|
m->modname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user