haskell - 插件名称查找行为从 GHC 8.4 系列更改
问题描述
[更新:原来这是一个 GHC 错误,现在已修复,计划在 8.6.4 版本中发布:https ://ghc.haskell.org/trac/ghc/ticket/16104#comment:8 ]
我正在尝试将核心插件移植到 GHC 8.6.3,该插件最后在 GHC 8.4 系列上运行良好。不幸的是,我遇到了问题。想知道插件编程要求是否已经改变,或者这是 GHC 本身的回归。我将其归结为以下示例,并希望获得有关如何使其工作的一些指导:
我在文件中有以下内容TestPlugin.hs
:
{-# LANGUAGE TemplateHaskell #-}
module TestPlugin (plugin) where
import GhcPlugins
import Data.Bits
plugin :: Plugin
plugin = defaultPlugin {installCoreToDos = install}
where install _ todos = return (test : todos)
test = CoreDoPluginPass "Test" check
check :: ModGuts -> CoreM ModGuts
check m = do mbN <- thNameToGhcName 'complement
case mbN of
Just _ -> liftIO $ putStrLn "Found complement!"
Nothing -> error "Failed to locate complement"
return m
我有一个非常简单的Test.hs
文件:
{-# OPTIONS_GHC -fplugin TestPlugin #-}
main :: IO ()
main = return ()
使用 GHC-8.4.2,我有:
$ ghc-8.4.2 --make -package ghc -c TestPlugin.hs
[1 of 1] Compiling TestPlugin ( TestPlugin.hs, TestPlugin.o )
$ ghc-8.4.2 -package ghc -c Test.hs
Found complement!
但是使用 GHC 8.6.3,我得到:
$ ghc-8.6.3 --make -package ghc -c TestPlugin.hs
[1 of 1] Compiling TestPlugin ( TestPlugin.hs, TestPlugin.o )
$ ghc-8.6.3 -package ghc -c Test.hs
ghc: panic! (the 'impossible' happened)
(GHC version 8.6.3 for x86_64-apple-darwin):
Failed to locate complement
如果我Test.hs
改为:
{-# OPTIONS_GHC -fplugin TestPlugin #-}
import Data.Bits -- Should not be required in the client code!
main :: IO ()
main = return ()
也就是说,如果我明确导入Data.Bits
. 但是这是非常不可取的,因为Test.hs
客户端代码和插件的用户没有理由导入插件可能需要的所有模块。(实际上,这将需要客户端导入一大堆不相关的模块;非常不可行且不可维护。)
我发现了以下堆栈溢出票证,它似乎遇到了类似的问题:How to replication the behavior of 'name in a TH splice然而,答案表明在这种情况下是不行的(也许不是'那里也真的没问题),因为在我的情况下,它需要对客户端代码进行不必要的更改,这是不合理的预期。(也许@JoachimBretner 有一个想法?)我也将此作为 GHC 票(https://ghc.haskell.org/trac/ghc/ticket/16104#ticket)提交,但来自 stack-overflow 社区的反馈是非常感激。
我应该以不同的方式编码我的插件吗?或者这是一个 GHC 回归?
解决方案
不是直接的答案,但是当我需要在 GHC 插件中“硬编码”一个名称时,我不使用 TH。相反,我使用findImportedModule
andlookupOrig
来查找它,例如
lookupJDITyCon :: TcPluginM Class
lookupJDITyCon = do
Found _ md <- findImportedModule jdiModule Nothing
jdiTcNm <- lookupOrig md (mkTcOcc "JustDoIt")
tcLookupClass jdiTcNm
where
jdiModule = mkModuleName "GHC.JustDoIt"
从我的ghc-justdoit
插件的代码。
当用户需要提及名称时,我使用 Template Haskell 名称,例如在拼接或注释中,我想在插件中获取这些名称。这就是我在inspection-testing
. 我在检查测试论文的附录中对此进行了一些讨论。
推荐阅读
- reactjs - 在 Jest/Enzyme 中模拟 useReducer 的商店而不导入 reducer
- ruby - Ruby 中的语法错误:使用无效运算符时出现“语法错误,意外结束”
- python - 使可变元素的排序列表保持最新
- extjs - Sencha ExtJs 7.1 自定义单个组件
- runtime - 如何在尖峰中跟踪动态指令(在 RISC-V 上)
- r - 根据单位列将重量转换为千克
- javascript - AfterAll Uncaught TypeError: localStorage.removeItem 不是抛出的函数
- angular - Tab contenteditable div 标记文本的开头
- sql - Oracle 解码与案例。查询返回不同的结果集
- nginx - 运行时错误:/usr/local/share/lua/5.1/resty/session.lua:183: loop or previous error loading module 'resty.session.ciphers.aes'