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 replicate the behaviour of ‘name in a TH splice然而,答案表明在这种情况下只是不行(也许在那里也不行),因为它需要不必要的在我的情况下更改客户端代码是不合理的. (也许@JoachimBretner有一个想法?)我也把它作为GHC票据(https://ghc.haskell.org/trac/ghc/ticket/16104#ticket)提交,但非常感谢来自堆栈溢出社区的反馈.

我应该以不同的方式编写插件吗?或者这是GHC回归?

最佳答案 不是直接的答案,但是当我需要在GHC插件中“硬编码”一个名字时,我不使用TH.相反,我使用findImportedModule和lookupOrig来查找它,例如如在

lookupJDITyCon :: TcPluginM Class
lookupJDITyCon = do
    Found _ md   <- findImportedModule jdiModule Nothing
    jdiTcNm <- lookupOrig md (mkTcOcc "JustDoIt")
    tcLookupClass jdiTcNm
  where
jdiModule = mkModuleName "GHC.JustDoIt"

来自我的ghc-justdoit插件的代码.

当用户需要提及名称时,我使用模板Haskell名称,例如在拼接或注释中,我想在插件中获取.这就是我在inspection-testing所做的事情.我在appendix of the Inspection Testing paper中对此进行了一些讨论.

点赞