fix some "phaseless" module holes
This commit is contained in:
parent
30c381f0b1
commit
2e652fc2b3
|
@ -629,7 +629,7 @@ is specified as @tech{phaseless} (such as
|
||||||
@racketmodname[racket/kernel]).
|
@racketmodname[racket/kernel]).
|
||||||
|
|
||||||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@subsection[#:tag "module-redeclare"]{Module Re-declarations}
|
@subsection[#:tag "module-redeclare"]{Module Redeclarations}
|
||||||
|
|
||||||
@section-index["modules" "re-define"]
|
@section-index["modules" "re-define"]
|
||||||
|
|
||||||
|
@ -642,9 +642,17 @@ module body. If a new variable definition has a counterpart in the old
|
||||||
declaration, it effectively assigns to the old variable.
|
declaration, it effectively assigns to the old variable.
|
||||||
|
|
||||||
If a module is @tech{instantiate}d in any @tech{phase}s before it is
|
If a module is @tech{instantiate}d in any @tech{phase}s before it is
|
||||||
re-declared, each re-declaration of the module is immediately
|
redeclared, each redeclaration of the module is immediately
|
||||||
@tech{instantiate}d in the same @tech{phase}s.
|
@tech{instantiate}d in the same @tech{phase}s.
|
||||||
|
|
||||||
|
If the current @tech{inspector} does not manage a module's declaration
|
||||||
|
inspector (see @secref["modprotect"]), then the module cannot be
|
||||||
|
redeclared. Similarly, a @tech{phaseless} module cannot be redeclared.
|
||||||
|
Even if redeclrection succeeds, instantiation of a module that is
|
||||||
|
previously instantiated may fail if instantiation for the
|
||||||
|
redeclaration attempts to modify variables that are constant (see
|
||||||
|
@racket[compile-enforce-module-constants]).
|
||||||
|
|
||||||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@subsection[#:tag "submodules"]{Submodules}
|
@subsection[#:tag "submodules"]{Submodules}
|
||||||
|
|
||||||
|
|
|
@ -992,8 +992,9 @@ to syntax transformers, via @racket[syntax-local-name].
|
||||||
@section[#:tag "phaseless-grammar"]{Phaseless Module Declarations}
|
@section[#:tag "phaseless-grammar"]{Phaseless Module Declarations}
|
||||||
|
|
||||||
A module is @tech{phaseless} only if it fits the following grammar,
|
A module is @tech{phaseless} only if it fits the following grammar,
|
||||||
which uses non-terminals from @secref["fully-expanded"], and 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.
|
||||||
|
|
||||||
@racketgrammar*[
|
@racketgrammar*[
|
||||||
#:literals (module module* #%plain-module-begin begin #%provide
|
#:literals (module module* #%plain-module-begin begin #%provide
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
(define i (open-input-bytes (get-output-bytes o)))
|
(define i (open-input-bytes (get-output-bytes o)))
|
||||||
(define e (zo-parse i))
|
(define e (zo-parse i))
|
||||||
(unless (equal? is? (and (memq 'phaseless (mod-flags (compilation-top-code e))) #t))
|
(unless (equal? is? (and (memq 'phaseless (mod-flags (compilation-top-code e))) #t))
|
||||||
(error 'phaseless "failed: ~s ~s\n" is? form))))
|
(error 'phaseless "failed: ~s ~s" is? form))))
|
||||||
|
|
||||||
(check-phaseless #t '(define-values (x) 5))
|
(check-phaseless #t '(define-values (x) 5))
|
||||||
(check-phaseless #t '(define-values (x) '5))
|
(check-phaseless #t '(define-values (x) '5))
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
(check-phaseless #f '(define-values (x) #(x)))
|
(check-phaseless #f '(define-values (x) #(x)))
|
||||||
(check-phaseless #f '(define-values (x) '(x)))
|
(check-phaseless #f '(define-values (x) '(x)))
|
||||||
|
(check-phaseless #f '(define-values (x) (lambda () (set! x 8))))
|
||||||
(check-phaseless #f '(define-values (x) (quote-syntax x)))
|
(check-phaseless #f '(define-values (x) (quote-syntax x)))
|
||||||
(check-phaseless #f '(define-values (x) (lambda () (quote-syntax x))))
|
(check-phaseless #f '(define-values (x) (lambda () (quote-syntax x))))
|
||||||
(check-phaseless #f '(define-values (x) (#%variable-reference)))
|
(check-phaseless #f '(define-values (x) (#%variable-reference)))
|
||||||
|
@ -74,5 +75,22 @@
|
||||||
(check-attach namespace-attach-module)
|
(check-attach namespace-attach-module)
|
||||||
(check-attach namespace-attach-module-declaration))
|
(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 'phaseless "redeclaration should have been disallowed"))))
|
||||||
|
|
||||||
(displayln "All tests passed.")
|
(displayln "All tests passed.")
|
||||||
|
|
||||||
|
|
|
@ -1203,6 +1203,7 @@ set_syntax (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec,
|
||||||
var = scheme_register_toplevel_in_prefix(var, env, rec, drec, 0, NULL);
|
var = scheme_register_toplevel_in_prefix(var, env, rec, drec, 0, NULL);
|
||||||
if (env->genv->module)
|
if (env->genv->module)
|
||||||
SCHEME_TOPLEVEL_FLAGS(var) |= SCHEME_TOPLEVEL_MUTATED;
|
SCHEME_TOPLEVEL_FLAGS(var) |= SCHEME_TOPLEVEL_MUTATED;
|
||||||
|
env->prefix->non_phaseless = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme_compile_rec_done_local(rec, drec);
|
scheme_compile_rec_done_local(rec, drec);
|
||||||
|
|
|
@ -6272,7 +6272,7 @@ static Scheme_Object *do_module_execute(Scheme_Object *data, Scheme_Env *genv,
|
||||||
Scheme_Object *prefix,
|
Scheme_Object *prefix,
|
||||||
Scheme_Object *supermodule)
|
Scheme_Object *supermodule)
|
||||||
{
|
{
|
||||||
Scheme_Module *m;
|
Scheme_Module *m, *old_m;
|
||||||
Scheme_Env *env;
|
Scheme_Env *env;
|
||||||
Scheme_Env *old_menv;
|
Scheme_Env *old_menv;
|
||||||
Scheme_Config *config;
|
Scheme_Config *config;
|
||||||
|
@ -6366,13 +6366,26 @@ static Scheme_Object *do_module_execute(Scheme_Object *data, Scheme_Env *genv,
|
||||||
if (old_menv) {
|
if (old_menv) {
|
||||||
if (scheme_module_protected_wrt(old_menv->guard_insp, insp) || old_menv->attached) {
|
if (scheme_module_protected_wrt(old_menv->guard_insp, insp) || old_menv->attached) {
|
||||||
scheme_contract_error("module->namespace",
|
scheme_contract_error("module->namespace",
|
||||||
"current code inspector cannot re-declare module",
|
"current code inspector cannot redeclare module",
|
||||||
"module name", 1, m->modname,
|
"module name", 1, m->modname,
|
||||||
NULL);
|
NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old_menv)
|
||||||
|
old_m = old_menv->module;
|
||||||
|
else
|
||||||
|
old_m = (Scheme_Module *)scheme_hash_get(env->module_registry->loaded, m->modname);
|
||||||
|
|
||||||
|
if (old_m && old_m->phaseless) {
|
||||||
|
scheme_contract_error("module->namespace",
|
||||||
|
"cannot redeclare phaseless module",
|
||||||
|
"module name", 1, m->modname,
|
||||||
|
NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!set_in_pre) {
|
if (!set_in_pre) {
|
||||||
/* execute pre-submodules: */
|
/* execute pre-submodules: */
|
||||||
execute_submodules(m, 1, genv, set_cache, set_in_pre, prefix);
|
execute_submodules(m, 1, genv, set_cache, set_in_pre, prefix);
|
||||||
|
@ -7117,7 +7130,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env,
|
||||||
m->tt_requires = scheme_null;
|
m->tt_requires = scheme_null;
|
||||||
m->dt_requires = scheme_null;
|
m->dt_requires = scheme_null;
|
||||||
|
|
||||||
if (iim && iim->phaseless)
|
if (iim && iim->phaseless && rec[drec].comp)
|
||||||
m->phaseless = scheme_true;
|
m->phaseless = scheme_true;
|
||||||
|
|
||||||
if (iidx) {
|
if (iidx) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user