[CLJ-1175] NPE in clojure.lang.Delay/deref Created: 06/Mar/13 Updated: 14/Aug/13 Resolved: 14/Aug/13
|Fix Version/s:||Release 1.6|
|Reporter:||Alan Malloy||Assignee:||Stuart Halloway|
|Patch:||Code and Test|
Delays get into a corrupt state if an exception is thrown, allowing deref to behave differently on subsequent calls.
This can manifest in multiple ways, depending on the expression being delayed:
Cause: clojure.core/delay creates a ^:once function, promising to call it only once, so that the compiler can do locals-clearing on its lexical closure. However, when an exception is thrown the Delay object is left thinking it has never called the function, so when it is forced again it calls the function again, breaking its promise to the compiler and causing the function to run after its locals have been cleared.
Solution: Make Delay remember the first exception that was thrown, and rethrow it on subsequent force attempts. This makes sense, in a way: the "result" of the expression was this exception e being thrown, and so this should happen every time.
|Comment by Alex Miller [ 08/Aug/13 2:07 AM ]|
Cleaned up description.