请分享您的看法参加2024 Clojure状态调查!

欢迎!请参阅关于页面,了解更多关于它是如何工作的信息。

0
记录和类型

考虑以下代码:

(definterface Test
(^void fail (()))

(deftype TestImpl
(^{:unsynchronized-mutable true :tag int} x)
Test
(fail this)

(set! x (dec x))))

它的编译失败并显示以下信息:
编译器异常: java.lang.VerifyError: (class: test/TestImpl, method: fail signature: ()V) 堆栈中期望找到整数,编译:(.../test.clj:27)

以下代码工作正常:

(definterface Test
(^void fail (()))

(deftype TestImpl
(^{:unsynchronized-mutable true :tag int} x)
Test
(fail this)

(set! x (int (dec x)))))

这里唯一的改变是我把 (dec x) 表达式包装进了 (int) 调用中。

我明白实际上前面的代码无论如何都不应该工作(或者至少不应该以我预期的那样工作),因为 (dec) 被定义为对 clojure.lang.Numbers.dec() 的调用,它只为 double, long 和 Object 重载(实际上,在第一个示例中将 :tag int 修改为 :tag long 允许程序编译)。然而,错误信息完全无用且具有误导性;它看起来像是编译器错误的后果。这不是一个具体示例的问题;我在一个更复杂的接口方法实现中发现了这个错误,其中 (set!) 调用在它的主体中间。

我使用 Clojure 1.4.0,并在 Archlinux x86_64 和 Windows 7 x86_64 上遇到了这个问题。

错误的全栈跟踪,以防有用:

java.lang.VerifyError: (class: test/TestImpl, method: fail signature: ()V) 堆栈中期望找到整数,编译:(.../test.clj:27)

at clojure.lang.Compiler.analyzeSeq(Compiler.java:6462)
at clojure.lang.Compiler.analyze(Compiler.java:6262)
at clojure.lang.Compiler.analyze(Compiler.java:6223)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5054)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3674)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6453)
at clojure.lang.Compiler.analyze(Compiler.java:6262)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6443)
at clojure.lang.Compiler.analyze(Compiler.java:6262)
at clojure.lang.Compiler.access$100(Compiler.java:37)
at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:518)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)
at clojure.lang.Compiler.analyze(Compiler.java:6262)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6443)
at clojure.lang.Compiler.analyze(Compiler.java:6262)
at clojure.lang.Compiler.analyze(Compiler.java:6223)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)
at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:5919)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)
at clojure.lang.Compiler.analyze(Compiler.java:6262)
at clojure.lang.Compiler.analyze(Compiler.java:6223)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5054)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3674)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6453)
at clojure.lang.Compiler.analyze(Compiler.java:6262)
at clojure.lang.Compiler.eval(Compiler.java:6508)
at clojure.lang.Compiler.load(Compiler.java:6952)
at clojure.lang.Compiler.loadFile(Compiler.java:6912)
at clojure.lang.RT$3.invoke(RT.java:307)
at test$eval3224.invoke(NO_SOURCE_FILE:43)
at clojure.lang.Compiler.eval(Compiler.java:6511)
at clojure.lang.Compiler.eval(Compiler.java:6477)
at clojure.core$eval.invoke(core.clj:2797)
at clojure.main$repl$read_eval_print__6405.invoke(main.clj:245)
at clojure.main$repl$fn__6410.invoke(main.clj:266)
at clojure.main$repl.doInvoke(main.clj:266)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.main$repl_opt.invoke(main.clj:332)
at clojure.main$main.doInvoke(main.clj:428)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.Var.invoke(Var.java:411)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)

原因:java.lang.VerifyError: (class: test/TestImpl, method: fail signature: ()V) 堆栈中期望找到整数

at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at clojure.lang.RT.classForName(RT.java:2039)
at clojure.lang.Compiler$HostExpr.maybeClass(Compiler.java:957)
at clojure.lang.Compiler$HostExpr.access$400(Compiler.java:736)
at clojure.lang.Compiler$NewExpr$Parser.parse(Compiler.java:2473)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)
... 45 more

3 答案

0

评论由:dpx-infinity

不应该设定主要优先级;但我无法再次编辑问题。:(

0
by

评论者:jafingerhut

降低优先级为次要,因为创建工单的人无法自己这样做。

0
by
参考: https://clojure.atlassian.net/browse/CLJ-1133(由 alex+import 报告)
...