From 3f2de918d8b49372b89820b4a1a860712c7dff4c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 16 Jan 2017 08:17:52 -0700 Subject: [PATCH] fix `variable-reference->namespace` for phase > 0 Set up bindings and shift phases as needed to make `variable-reference->namespace` work in a run-time position when the enclosing module is instantiated at a phase other than 0. Thanks to Rohin Shah for the bug report. --- .../racket-test-core/tests/racket/module.rktl | 68 +++++++++++++++++++ racket/src/racket/src/env.c | 2 +- racket/src/racket/src/module.c | 7 +- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 0f5c3cf4f5..e15c851fe4 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1937,6 +1937,74 @@ case of module-leve bindings; it doesn't cover local bindings. (provide x)) (require 'a-submod))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Make sure that `variable-reference->namespace` works +;; with phase shifts + +(module evaluate-using-module-namespace racket/base + (provide go) + + (define x 'x) + + (define (go) + (define ns (variable-reference->namespace (#%variable-reference))) + (list (namespace-base-phase ns) + (eval '(list x) ns)))) + +(test '(0 (x)) (dynamic-require ''evaluate-using-module-namespace 'go)) + +(module evaluate-using-module-namespace-at-phase-1 racket/base + (require (for-syntax 'evaluate-using-module-namespace + racket/base)) + (provide went) + (define-syntax (m stx) + #`(quote #,(go))) + (define (went) (m))) + +(test '(1 (x)) (dynamic-require ''evaluate-using-module-namespace-at-phase-1 'went)) + +(module evaluate-using-module-namespace/saved-context racket/base + (provide go) + + (define x 'x/sc) + + ;; Macro-introduced definition triggers saving the module's bindings + (define-syntax-rule (force-save-context) (define x 1)) + (force-save-context) + + (define (go) + (define ns (variable-reference->namespace (#%variable-reference))) + (list (namespace-base-phase ns) + (eval '(list x) ns)))) + +(test '(0 (x/sc)) (dynamic-require ''evaluate-using-module-namespace/saved-context 'go)) + +(module evaluate-using-module-namespace-at-phase-1/saved-context racket/base + (require (for-syntax 'evaluate-using-module-namespace/saved-context + racket/base)) + (provide went) + (define-syntax (m stx) + #`(quote #,(go))) + (define (went) (m))) + +(test '(1 (x/sc)) (dynamic-require ''evaluate-using-module-namespace-at-phase-1/saved-context 'went)) + + +(module defines-a-variable-x-in-its-body racket/base + (define x 'defined)) + +(module uses-defines-a-variable-x-in-its-body-at-phase-1 racket/base + (require (for-syntax racket/base)) + (provide out) + + (define-syntax (m stx) + (dynamic-require ''defines-a-variable-x-in-its-body #f) + #`(quote #,(eval 'x (module->namespace ''defines-a-variable-x-in-its-body)))) + + (define out (m))) + +(test 'defined dynamic-require ''uses-defines-a-variable-x-in-its-body-at-phase-1 'out) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/env.c b/racket/src/racket/src/env.c index 0454223d25..bc5241b0c5 100644 --- a/racket/src/racket/src/env.c +++ b/racket/src/racket/src/env.c @@ -2121,7 +2121,7 @@ static Scheme_Object *do_variable_namespace(const char *who, int tl, int argc, S return env->access_insp; } else if (tl) { /* return env directly; need to set up */ - if (!env->phase && env->module) + if (!env->mod_phase && env->module) scheme_prep_namespace_rename(env); env->interactive_bindings = 1; } else { diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 044523b342..d31724e9ee 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -3237,6 +3237,7 @@ void scheme_prep_namespace_rename(Scheme_Env *menv) } rns = scheme_module_context_to_stx(rns, NULL); + m->rn_stx = rns; } else if (SCHEME_PAIRP(m->rn_stx)) { /* Delayed shift: */ @@ -3257,7 +3258,11 @@ void scheme_prep_namespace_rename(Scheme_Env *menv) m->rn_stx = rn_stx; } - rns = scheme_stx_to_module_context(m->rn_stx); + rns = m->rn_stx; + if (menv->phase) + rns = scheme_stx_shift(rns, scheme_make_integer(menv->phase), NULL, NULL, NULL, NULL, NULL); + + rns = scheme_stx_to_module_context(rns); menv->stx_context = rns; menv->rename_set_ready = 1;