diff --git a/pkgs/racket-doc/scribblings/reference/syntax.scrbl b/pkgs/racket-doc/scribblings/reference/syntax.scrbl index 804c0b2dff..06f59e1edf 100644 --- a/pkgs/racket-doc/scribblings/reference/syntax.scrbl +++ b/pkgs/racket-doc/scribblings/reference/syntax.scrbl @@ -224,7 +224,10 @@ declarations for @racket[A] and @racket[B]. However, a syntactic form that produces syntax definitions must be defined before it is used. No identifier can be imported or defined more than once at any -@tech{phase level} within a single module. Every exported identifier must be imported or +@tech{phase level} within a single module, except that a definition +via @racket[define-values] or @racket[define-syntaxes] can shadow a +preceding import via @racket[#%require]. +Every exported identifier must be imported or defined. No expression can refer to a @tech{top-level variable}. A @racket[module*] form in which the enclosing module's bindings are visible (i.e., a nested @racket[module*] with @racket[#f] instead of a @racket[module-path]) @@ -300,7 +303,11 @@ See also @secref["module-eval-model"] and @secref["mod-parse"]. (unless (zero? n) (printf "quack\n") (quack (sub1 n))))) -]} +] + +@history[#:changed "6.2.0.4" @elem{Changed @racket[define-syntaxes] + and @racket[define-values] to + shadow any preceding import.}]} @defform*[((module* id module-path form ...) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 18e16ad5a0..a6238085e8 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -127,7 +127,6 @@ (syntax-test #'(module m racket/base (#%require (rename n n not-there)))) (syntax-test #'(module m racket/base (#%require (rename n n m extra)))) -(syntax-test #'(module m racket/base (#%require racket/base) (define car 5))) (syntax-test #'(module m racket/base (define x 6) (define x 5))) (syntax-test #'(module m racket/base (define x 10) (define-syntax x 10))) (syntax-test #'(module m racket/base (define-syntax x 10) (define x 10))) @@ -142,6 +141,15 @@ (test 5 dynamic-require ''_shadow_ 'car) +;; Ok to redefine imported: +(module defines-car-that-overrides-import racket/base (#%require racket/base) (define car 5) (provide car)) +(module defines-car-that-overrides-import/stx racket/base (#%require racket/base (for-syntax racket/base)) (define-syntax (car stx) #'6) (provide car)) +(test 5 dynamic-require ''defines-car-that-overrides-import 'car) +(test 6 dynamic-require ''defines-car-that-overrides-import/stx 'car) +;; Can't redefine multiple times or import after definition: +(syntax-test #'(module m racket/base (#%require racket/base) (define car 5) (define car 5))) +(syntax-test #'(module m racket/base (define car 5) (#%require racket/base))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (let () diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index 74f2194800..4fb096178b 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -8959,11 +8959,9 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ return NULL; } - /* Not required: */ - if (check_already_required(required, name)) { - scheme_wrong_syntax(who, orig_name, e, "identifier is already imported"); - return NULL; - } + if (check_already_required(required, name)) { + /* allow definition of previously imported */ + } /* Not syntax: */ if (scheme_lookup_in_table(env->genv->syntax, (const char *)name)) { @@ -9062,10 +9060,8 @@ static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_ return NULL; } - /* Not required: */ if (check_already_required(required, name)) { - scheme_wrong_syntax(who, orig_name, e, "identifier is already imported"); - return NULL; + /* allow definition of previously imported */ } if (!SAME_OBJ(SCHEME_STX_VAL(orig_name), name)) {