diff options
author | Andy Wingo <wingo@pobox.com> | 2017-02-28 11:31:52 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2017-02-28 11:49:15 +0100 |
commit | 631e9901d84ba59ffcb21de95dbb6c9215b642c7 (patch) | |
tree | 32c55ec03e0f1b6e6b2d6fda37576a36e38875fe /module | |
parent | 9e28a12121414b4b0508d56c9fe011d9059f48b7 (diff) |
Declare module exports before loading imports
* module/ice-9/boot-9.scm (define-module*): Process module imports after
module exports. Allows for an additional kind of circular module
imports (see https://bugs.gnu.org/15540).
* test-suite/tests/modules.test ("circular imports"): Add test.
Diffstat (limited to 'module')
-rw-r--r-- | module/ice-9/boot-9.scm | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm index 229d91734..b480e3dd1 100644 --- a/module/ice-9/boot-9.scm +++ b/module/ice-9/boot-9.scm @@ -2859,24 +2859,13 @@ written into the port is returned." (define (list-of pred l) (or (null? l) (and (pair? l) (pred (car l)) (list-of pred (cdr l))))) + (define (valid-import? x) + (list? x)) (define (valid-export? x) (or (symbol? x) (and (pair? x) (symbol? (car x)) (symbol? (cdr x))))) (define (valid-autoload? x) (and (pair? x) (list-of symbol? (car x)) (list-of symbol? (cdr x)))) - (define (resolve-imports imports) - (define (resolve-import import-spec) - (if (list? import-spec) - (apply resolve-interface import-spec) - (error "unexpected use-module specification" import-spec))) - (let lp ((imports imports) (out '())) - (cond - ((null? imports) (reverse! out)) - ((pair? imports) - (lp (cdr imports) - (cons (resolve-import (car imports)) out))) - (else (error "unexpected tail of imports list" imports))))) - ;; We could add a #:no-check arg, set by the define-module macro, if ;; these checks are taking too much time. ;; @@ -2891,33 +2880,37 @@ written into the port is returned." (error "expected list of integers for version")) (set-module-version! module version) (set-module-version! (module-public-interface module) version)) - (let ((imports (resolve-imports imports))) - (call-with-deferred-observers - (lambda () - (unless (list-of valid-export? exports) - (error "expected exports to be a list of symbols or symbol pairs")) - (unless (list-of valid-export? replacements) - (error "expected replacements to be a list of symbols or symbol pairs")) - (unless (list-of valid-export? re-exports) - (error "expected re-exports to be a list of symbols or symbol pairs")) - (unless (null? imports) - (module-use-interfaces! module imports)) - (module-export! module exports) - (module-replace! module replacements) - (module-re-export! module re-exports) - ;; FIXME: Avoid use of `apply'. - (apply module-autoload! module autoloads) - (let ((duplicates (or duplicates - ;; Avoid stompling a previously installed - ;; duplicates handlers if possible. - (and (not (module-duplicates-handlers module)) - ;; Note: If you change this default, - ;; change it also in - ;; `default-duplicate-binding-procedures'. - '(replace warn-override-core warn last))))) - (when duplicates - (let ((handlers (lookup-duplicates-handlers duplicates))) - (set-module-duplicates-handlers! module handlers))))))) + (call-with-deferred-observers + (lambda () + (unless (list-of valid-import? imports) + (error "expected imports to be a list of import specifications")) + (unless (list-of valid-export? exports) + (error "expected exports to be a list of symbols or symbol pairs")) + (unless (list-of valid-export? replacements) + (error "expected replacements to be a list of symbols or symbol pairs")) + (unless (list-of valid-export? re-exports) + (error "expected re-exports to be a list of symbols or symbol pairs")) + (module-export! module exports) + (module-replace! module replacements) + (unless (null? imports) + (let ((imports (map (lambda (import-spec) + (apply resolve-interface import-spec)) + imports))) + (module-use-interfaces! module imports))) + (module-re-export! module re-exports) + ;; FIXME: Avoid use of `apply'. + (apply module-autoload! module autoloads) + (let ((duplicates (or duplicates + ;; Avoid stompling a previously installed + ;; duplicates handlers if possible. + (and (not (module-duplicates-handlers module)) + ;; Note: If you change this default, + ;; change it also in + ;; `default-duplicate-binding-procedures'. + '(replace warn-override-core warn last))))) + (when duplicates + (let ((handlers (lookup-duplicates-handlers duplicates))) + (set-module-duplicates-handlers! module handlers)))))) (when transformer (unless (and (pair? transformer) (list-of symbol? transformer)) |