2024年Clojure调查问卷中分享您的看法!

欢迎!请参阅关于页面以了解更多关于该功能的信息。

+1投票
编译器
重新标记

验证器错误

语法错误(VerifyError)在编译新文件时出现 (bug.clj:8:1)。
操作数栈下溢

最小示例

deps.edn

{:paths ["."]}

IBad.java

public interface IBad {
    public void put(Object key, Object value);
    public void onbad(Object thing);
}

编译

javac IBad.java

在命令行中使用clj

 clj
Clojure 1.10.1
user=> (import IBad)
IBad

user=> (defrecord Y [y]
  IBad
  (onbad [_ _] :bad))

Syntax error (VerifyError) compiling new at (REPL:1:1).
Operand stack underflow
Exception Details:
  Location:
    user/Y.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @8: areturn
  Reason:
    Attempt to pop empty stack.
  Current Frame:
    bci: @8
    flags: { }
    locals: { 'user/Y', 'java/lang/Object', 'java/lang/Object' }
    stack: { }
  Bytecode:
    0000000: 2a2b 2cb9 0177 0300 b0

user=> *e
#error {
 :cause "Operand stack underflow\nException Details:\n  Location:\n    user/Y.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @8: areturn\n  Reason:\n    Attempt to pop empty stack.\n  Current Frame:\n    bci: @8\n    flags: { }\n    locals: { 'user/Y', 'java/lang/Object', 'java/lang/Object' }\n    stack: { }\n  Bytecode:\n    0000000: 2a2b 2cb9 0177 0300 b0                 \n"
 :via
 [{:type clojure.lang.Compiler$CompilerException
   :message "Syntax error compiling new at (1:1)."
   :data #:clojure.error{:phase :compile-syntax-check, :line 1, :column 1, :source "NO_SOURCE_PATH", :symbol new}
   :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 7115]}
  {:type java.lang.VerifyError
   :message "Operand stack underflow\nException Details:\n  Location:\n    user/Y.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @8: areturn\n  Reason:\n    Attempt to pop empty stack.\n  Current Frame:\n    bci: @8\n    flags: { }\n    locals: { 'user/Y', 'java/lang/Object', 'java/lang/Object' }\n    stack: { }\n  Bytecode:\n    0000000: 2a2b 2cb9 0177 0300 b0                 \n"
   :at [java.lang.Class getDeclaredConstructors0 "Class.java" -2]}]
 :trace
 [[java.lang.Class getDeclaredConstructors0 "Class.java" -2]
  [java.lang.Class privateGetDeclaredConstructors "Class.java" 3138]
  [java.lang.Class getConstructors "Class.java" 1944]
  [clojure.lang.Compiler$NewExpr <init> "Compiler.java" 2575]
  [clojure.lang.Compiler$NewExpr$Parser parse "Compiler.java" 2667]
  [clojure.lang.Compiler analyzeSeq "Compiler.java" 7107]
  [clojure.lang.Compiler analyze "Compiler.java" 6789]
  [clojure.lang.Compiler analyze "Compiler.java" 6745]
  [clojure.lang.Compiler$BodyExpr$Parser parse "Compiler.java" 6120]
  [clojure.lang.Compiler$FnMethod parse "Compiler.java" 5467]
  [clojure.lang.Compiler$FnExpr parse "Compiler.java" 4029]
  [clojure.lang.Compiler analyzeSeq "Compiler.java" 7105]
  [clojure.lang.Compiler analyze "Compiler.java" 6789]
  [clojure.lang.Compiler analyzeSeq "Compiler.java" 7095]
  [clojure.lang.Compiler analyze "Compiler.java" 6789]
  [clojure.lang.Compiler access$300 "Compiler.java" 38]
  [clojure.lang.Compiler$DefExpr$Parser parse "Compiler.java" 596]
  [clojure.lang.Compiler analyzeSeq "Compiler.java" 7107]
  [clojure.lang.Compiler analyze "Compiler.java" 6789]
  [clojure.lang.Compiler analyzeSeq "Compiler.java" 7095]
  [clojure.lang.Compiler analyze "Compiler.java" 6789]
  [clojure.lang.Compiler analyze "Compiler.java" 6745]
  [clojure.lang.Compiler$BodyExpr$Parser parse "Compiler.java" 6118]
  [clojure.lang.Compiler$LetExpr$Parser parse "Compiler.java" 6436]
  [clojure.lang.Compiler analyzeSeq "Compiler.java" 7107]
  [clojure.lang.Compiler analyze "Compiler.java" 6789]
  [clojure.lang.Compiler analyze "Compiler.java" 6745]
  [clojure.lang.Compiler$BodyExpr$Parser parse "Compiler.java" 6120]
  [clojure.lang.Compiler$FnMethod parse "Compiler.java" 5467]
  [clojure.lang.Compiler$FnExpr parse "Compiler.java" 4029]
  [clojure.lang.Compiler analyzeSeq "Compiler.java" 7105]
  [clojure.lang.Compiler analyze "Compiler.java" 6789]
  [clojure.lang.Compiler eval "Compiler.java" 7174]
  [clojure.lang.Compiler eval "Compiler.java" 7132]
  [clojure.core$eval invokeStatic "core.clj" 3214]
  [clojure.core$eval invoke "core.clj" 3210]
  [clojure.main$repl$read_eval_print__9086$fn__9089 invoke "main.clj" 437]
  [clojure.main$repl$read_eval_print__9086 invoke "main.clj" 437]
  [clojure.main$repl$fn__9095 invoke "main.clj" 458]
  [clojure.main$repl invokeStatic "main.clj" 458]
  [clojure.main$repl_opt invokeStatic "main.clj" 522]
  [clojure.main$main invokeStatic "main.clj" 667]
  [clojure.main$main doInvoke "main.clj" 616]
  [clojure.lang.RestFn invoke "RestFn.java" 397]
  [clojure.lang.AFn applyToHelper "AFn.java" 152]
  [clojure.lang.RestFn applyTo "RestFn.java" 132]
  [clojure.lang.Var applyTo "Var.java" 705]
  [clojure.main main "main.java" 40]]}
user=>

我尝试仅使用协议来重现这个问题,但没有成功。

此外,还有一个额外的数据点,使用deftype可以成功

(deftype Y [y] IBad (onbad [_ _] :bad))
user.Y

2个答案

+1投票

被选择
 
最佳答案
我还尝试使用 `defprotocol` 和 `definterface` 重新创建,但无法获得类似的错误。不清楚这是否为简洁重現提供了有用的上下文。
0

猜测 IBad/put 是否覆盖了 java.util.Map 接口方法,这是 defrecord 默认实现的(仅抛出不支持的操作异常)。

这可以解释为什么 deftype 不会失败。

...