Uploaded image for project: 'Clojure'
  1. CLJ-1330

Class name clash between top-level functions and defn'ed ones


    • Type: Bug
    • Status: Closed
    • Priority: Critical
    • Resolution: Completed
    • Affects versions: None
    • Fix versions: Release 1.7
    • Labels:
    • Approval:
    • Patch:


      Named anonymous fn's are not guaranteed to have unique class names when AOT-compiled.

      For example:

      (defn g [])
      (def xx (fn g []))

      When AOT-compiled both functions will emit user$g.class, the latter overwriting the former.

      Impact: this affects apps like Cursive, which has been using a patched version of Clojure to get around this issue for quite a while.

      Demonstration script: demo1.clj

      Patch: 0001-CLJ-1093-v3.patch (already applied, see below)

      Approach: Generate unique class names for named fn's the same way as for unnamed anonymous fn's.
      The patch contains an additional enhancement to include the name of the local binding in the class name.

      Comparison between pre and post patch naming scheme (N denotes unique number):

      code before after note
      (defn a []) user$a user$a same
      (fn []) user$evalN$fn__N user$evalN$fn__N same
      (fn a []) user$evalN$a__N user$evaN$a__N same
      (let [a (fn [])] a) user$evalN$a__N user$evalN$a__N same
      (let [a (fn x [])] a) user$eval1N$x__N user$evalN$a_x_N IMPROVED - contains local binding name
      (def a (fn [])) user$a user$a same
      (def a (fn x [])) user$x user$a_x_N FIXED conflict with (defn x [])
      (def ^{:foo (fn [])} a) user$fn__N user$fn__N same
      (def ^{:foo (fn a [])} a) user$a user$a__N FIXED conflict with (defn a [])
      (def a (fn [] (fn []))) user$a$fn__N user$a$fn__N same
      (def a (fn [] (fn x []))) user$a$x__N user$a$x__N same

      See also: This patch also fixes the issue reported in CLJ-1227 Closed .

      Screened by: Alex Miller - I am not sure whether the local binding name enhancement is worth doing. It improves debugging of which anonymous class you're talking about but has the downsides of increasing class name (and file name) length.

      REOPENED Patch: 0001-CLJ-1093-v3-no-locals-improv.patch
      REOPENED UPDATE: The local improvement version of this patch increases class names (and thus .class names) and we've had several reports of exceeding file system limits (~143 chars) - see comments for details. Thus, we should rollback the prior patch (0001-CLJ-1093-v3.patch) and apply the version without this enhancement. The replacement patch (0001-CLJ-1093-v3-no-locals-improv.patch) does not have the same effect on class name length.




            • Assignee:
              bronsa Nicola Mometto
            • Votes:
              6 Vote for this issue
              10 Start watching this issue


              • Created: