Clojure

deftype: compiler error on set! for mutable field

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Duplicate
  • Affects Version/s: Release 1.4
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None

Description

The following code demonstrates the error in a minimal example:

(defprotocol IBlob (do-sth [this, x]))

(deftype Blob [^{:volatile-mutable true} a]
  IBlob
  (do-sth [this, x] 
    (try (/ 1 x) 
      (catch Throwable t 
        (set! a (inc a))))
        (inc x)))

(deftype Blob2 [^{:volatile-mutable true} a]
  IBlob
  (do-sth [this, x] 
    (try (/ 1 x) 
      (catch Throwable t 
        (set! a (inc a))))))

Compiling Blob results in the following exception:

CompilerException java.lang.IllegalArgumentException: Cannot assign to non-mutable: a

Compiling Blob2 works as expected.

Activity

Hide
Chouser added a comment - - edited
(defmethod print-method clojure.lang.Compiler$LocalBinding 
  [^clojure.lang.Compiler$LocalBinding o w]
  (.write w
    (str "#<LB "
      (binding [*print-meta* true]
        (pr-str {:sym (.-sym o)
                 :tag (.-tag o)
                 :idx (.-idx o)
                 :name (.-name o)
                 :isArg (.-isArg o)
                 :canBeCleared (.canBeCleared o)
                 :recurMistmatch (.-recurMistmatch o)})) ">")))

(defmacro prn-env []
  (doseq [[_ lb] &env]
    (prn lb)))

(deftype T [^:volatile-mutable x]
  clojure.lang.IDeref
  (deref [this]
    (try
      (catch Exception e
        (prn-env)
        (set! x 0)))
    1))

#<LB {:sym ^{:volatile-mutable true} x, :tag nil, :idx -1, :name "x", :isArg false, :canBeCleared true, :recurMistmatch false}>
#<LB {:sym e, :tag Exception, :idx 3, :name "e", :isArg false, :canBeCleared true, :recurMistmatch false}>
#<LB {:sym this, :tag compile__stub.user.T, :idx 0, :name "this", :isArg false, :canBeCleared true, :recurMistmatch false}>
CompilerException java.lang.IllegalArgumentException: Cannot assign to non-mutable: x, compiling:(NO_SOURCE_PATH:1)
Show
Chouser added a comment - - edited
(defmethod print-method clojure.lang.Compiler$LocalBinding 
  [^clojure.lang.Compiler$LocalBinding o w]
  (.write w
    (str "#<LB "
      (binding [*print-meta* true]
        (pr-str {:sym (.-sym o)
                 :tag (.-tag o)
                 :idx (.-idx o)
                 :name (.-name o)
                 :isArg (.-isArg o)
                 :canBeCleared (.canBeCleared o)
                 :recurMistmatch (.-recurMistmatch o)})) ">")))

(defmacro prn-env []
  (doseq [[_ lb] &env]
    (prn lb)))

(deftype T [^:volatile-mutable x]
  clojure.lang.IDeref
  (deref [this]
    (try
      (catch Exception e
        (prn-env)
        (set! x 0)))
    1))

#<LB {:sym ^{:volatile-mutable true} x, :tag nil, :idx -1, :name "x", :isArg false, :canBeCleared true, :recurMistmatch false}>
#<LB {:sym e, :tag Exception, :idx 3, :name "e", :isArg false, :canBeCleared true, :recurMistmatch false}>
#<LB {:sym this, :tag compile__stub.user.T, :idx 0, :name "this", :isArg false, :canBeCleared true, :recurMistmatch false}>
CompilerException java.lang.IllegalArgumentException: Cannot assign to non-mutable: x, compiling:(NO_SOURCE_PATH:1)
Hide
Gunnar Völkel added a comment -

As a workaround you can create a setter method for that field, e.g.

(set-a [this, na] (set! a na))
Show
Gunnar Völkel added a comment - As a workaround you can create a setter method for that field, e.g.
(set-a [this, na] (set! a na))
Hide
Andy Fingerhut added a comment -

Is this the same issue as CLJ-1023?

Show
Andy Fingerhut added a comment - Is this the same issue as CLJ-1023?
Hide
Gunnar Völkel added a comment -

That one looks very similar, yes.
The "non-tail try-catch as closure" being the problem, would explain the examples above, as well.

Show
Gunnar Völkel added a comment - That one looks very similar, yes. The "non-tail try-catch as closure" being the problem, would explain the examples above, as well.
Hide
Timothy Baldridge added a comment -

closing as duplicate of CLJ-1023

Show
Timothy Baldridge added a comment - closing as duplicate of CLJ-1023
Timothy Baldridge made changes -
Field Original Value New Value
Resolution Duplicate [ 3 ]
Status Open [ 1 ] Closed [ 6 ]

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: