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 不会失败。

...