--- orig/ice-9/boot-9.scm +++ mod/ice-9/boot-9.scm @@ -1511,10 +1511,22 @@ (module-modified m) b))) - ;; Create a new local variable. - (let ((local-var (make-undefined-variable))) - (module-add! m v local-var) - local-var))) + ;; No local variable yet, so we need to create a new one. That + ;; new variable is initialized with the old imported value of V, + ;; if there is one. This is required by Section 5.2.1 of R5RS which + ;; says that `define' is equivalent to `set!' when V is already bound + ;; (of course here we respect module boundaries so this is not exactly + ;; a `set!'). + (let ((imported-var (module-variable m v)) + (local-var (or (and (module-binder m) + ((module-binder m) m v #t)) + (begin + (let ((answer (make-undefined-variable))) + (module-add! m v answer) + answer))))) + (if (and imported-var (not (variable-bound? local-var))) + (variable-set! local-var (variable-ref imported-var))) + local-var))) ;; module-ensure-local-variable! module symbol ;; --- orig/test-suite/tests/modules.test +++ mod/test-suite/tests/modules.test @@ -118,7 +118,16 @@ (map module-variable (map resolve-interface mods) syms) - locals)))) + locals))) + + (pass-if "redefinition" + (let ((m (make-module))) + (beautify-user-module! m) + + ;; The previous value of `round' must still be visible at the time the + ;; new `round' is defined. + (eval '(define round round) m) + (eq? (module-ref m 'stat) stat))))