请分享你的想法,参加2024年Clojure状态调查!

欢迎!请查看关于页面以了解此工作的更多信息。

+1投票
编译器

像这样的表达式会导致nil,但应该编译失败

(let (link: ) do)

像这样的表达式会导致nil,但应该产生一个值

(let (link: do 1) do)

这适用于所有具有“隐式do”的特殊形式:try/catch/finally、letfn、let以及fn**/reify/deftype系列形式。

对这些特殊形式实现“隐式do”的方式是,相关的解析器会明确地将体表达式委派给BodyExpr.Parser。例如:

(let (link: x 1) (println x) x)

调用BodyExpr.Parser.parse()时使用列表 '((println x) x)。然而,BodyExpr.Parser还用于解析列表((do (println x) x)),在其他上下文中。为了处理这两种情况,它的parse()方法会跳过其第一个形式,如果这个形式是'm符号'。所以,如果一个具有“隐式do”的特殊形式的第一个表达式是裸符号'do',这个符号就会错误地被丢弃。

所附补丁通过在每个这样的特殊形式之前实际上插入一个显式的'do'来修复此问题,这样BodyExpr.Parser就可以无条件地假设其第一个形式是'do',然后跳过它。BodyExpr现在在这不是情况下会抛出异常,因为这表明编译器中存在错误 - 用户代码不能创建这种情况。

附加的补丁对编译时间的影响最小:它为每个具有隐式do的表达式的分析引入了一个额外的方法调用和一个额外的cons单元分配。它不会对生成的代码产生影响(除了修正本票项开头指出的错误)。

包含三个测试,补丁之前失败,补丁之后成功。

4个答案

0投票

评论由:amalloy 发布

补丁的先前的版本意外地只包含测试,而没有修复。这个补丁包含两个。

0投票

评论由:bronsa 发布

我认为这可能是一个与 CLJ-1216 重复的问题,不确定两个补丁是如何比较的

0投票

评论由:amalloy 发布

是的,肯定是那个的副本。我也更喜欢你的补丁。

0投票
参考:https://clojure.atlassian.net/browse/CLJ-2439(由 amalloy 报告)
...