You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GHC类型检查器插件中"机会性"查找已加载定义?

GHC类型检查器插件中查找已加载定义的合规方式

针对你遇到的findImportedModule的问题,推荐使用以下稳妥的合规方案,核心思路是先确认目标模块已加载到当前环境,再安全查找对应名称:

1. 检查模块是否已加载

通过getTopEnv获取当前环境的HscEnv,直接查询GHC维护的已加载单元集合:

import GHC
import GHC.Types.Name.Occurrence
import GHC.Tc.Plugin (TcPluginM, getTopEnv)
import GHC.Unit.State (lookupModuleInHomeUnit, lookupModuleInUnits)
import GHC.Unit.Types (Module, ModuleName)

isModuleLoaded :: Module -> TcPluginM Bool
isModuleLoaded target_mod = do
  hsc_env <- getTopEnv
  let hsc_units = hsc_units hsc_env
      -- 先检查当前本地单元是否加载了该模块
      home_match = lookupModuleInHomeUnit hsc_units (moduleName target_mod)
      -- 再检查依赖单元中是否加载了该模块
      dep_match = lookupModuleInUnits hsc_units (moduleName target_mod) (moduleUnit target_mod)
  return $ case (home_match, dep_match) of
    (Just _, _) -> True
    (_, Just _) -> True
    _ -> False

2. 安全查找模块内的名称

确认模块已加载后,调用lookupOrig查找目标名称,此时不会出现模块未加载的报错:

lookupOrigSafe :: Module -> OccName -> TcPluginM (Maybe Name)
lookupOrigSafe mod occ = do
  loaded <- isModuleLoaded mod
  if not loaded
    then return Nothing
    else Just <$> lookupOrig mod occ

方案优势

  • 规避findImportedModule的两类问题:既不会因NoPkgQual返回未加载模块,也不会因单元依赖顺序触发panic
  • 使用GHC公开的单元状态查询API,完全合规,不依赖内部实现细节
  • 逻辑清晰,仅在模块已加载时执行查找,符合你"仅在特定模块上下文执行操作"的需求

额外建议

如果插件仅需在模块存在时触发逻辑,也可以尝试findModule,但findModule可能触发模块加载流程,因此优先使用上述"先检查加载状态"的方式更稳妥。

内容的提问来源于stack exchange,提问作者Cactus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 07:15:50