Constants and top-level code
Consider this example:
(eval-when (:compile-toplevel :load-toplevel)
((lambda ()
(defpackage foo (:use) (:export foobar)))))
(print 'foo:foobar)
Compile it with:
shell> cmucl -noinit -eval '(compile-file "x.lisp")' -eval '(quit)'
; Python version 1.1, VM version Intel x86/sse2 on 2015-08-18 09:50:46.
; Compiling: /tmp/x.lisp 2015-08-18 09:38:14
; Byte Compiling Top-Level Form:
; x.sse2f written.
; Compilation finished in 0:00:00.
Then loading it produces and error:
shell> cmucl -noinit -load x
; Loading #P"/tmp/x.sse2f".
Error in function LISP::FOP-PACKAGE: The package "FOO" does not exist.
[Condition of type SIMPLE-ERROR]
Restarts:
0: [CONTINUE] Return NIL from load of "x".
1: [ABORT ] Skip remaining initializations.
Debug (type H for help)
(LISP::FOP-PACKAGE)
Source: Error finding source:
Error in function DEBUG::GET-FILE-TOP-LEVEL-FORM: Source file no longer exists:
target:code/load.lisp.
0]
I think the problem is that the loader wants to intern the symbol foo:foobar before it executes the code for the defpackage form. Intuitively this is wrong as the defpackage form occurs before the first use of foo:foobar.
I'd like to propose a workaround:
diff --git a/src/compiler/ir1tran.lisp b/src/compiler/ir1tran.lisp
index 81c7d74..9802336 100644
--- a/src/compiler/ir1tran.lisp
+++ b/src/compiler/ir1tran.lisp
@@ -2547,7 +2547,8 @@ (defun do-eval-when-stuff (situations body fun &optional toplevel-p)
(if (or (intersection '(:load-toplevel load) situations)
(and *converting-for-interpreter*
(intersection '(:execute eval) situations)))
- (funcall fun body)
+ (prog1 (funcall fun body)
+ (compile-top-level-lambdas '() t))
(funcall fun '(nil))))
;; Not toplevel, only :execute counts.
(if (intersection '(eval :execute) situations)
The idea is to flush any pending lambdas when (eval-when (:load-toplevel) ...) is used in toplevel position, so that the compiler can't put constants, that appear later in the source, in the same constant pool.
It solves my immediate problem but I don't know what new problems it might create.