summaryrefslogtreecommitdiff
path: root/module
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2017-02-28 11:31:52 +0100
committerAndy Wingo <wingo@pobox.com>2017-02-28 11:49:15 +0100
commit631e9901d84ba59ffcb21de95dbb6c9215b642c7 (patch)
tree32c55ec03e0f1b6e6b2d6fda37576a36e38875fe /module
parent9e28a12121414b4b0508d56c9fe011d9059f48b7 (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.scm73
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))