Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,862
    • Issues 4,862
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 455
    • Merge requests 455
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #21279
Closed
Open
Created Mar 22, 2022 by Aaron Allen@aaronallen8455Reporter

Plugin installed hooks are largely ignored

Summary

If a compiler plugin installs hooks, for example on compiler phases or the logger action, they do not get called as expected. This bug was introduced in GHC v9.2 in interactive mode but also occurs for make mode in other versions (not sure when the bug was introduced in make mode but it is present as early as 8.10.7).

Steps to reproduce

Write a plugin that modifies the Logger:

plugin :: Plugin
plugin = defaultPlugin
  { driverPlugin = \_ hscEnv -> do
      pure hscEnv
        { hsc_logger =
            pushLogHook logHook $ hsc_logger hscEnv
        }
  }

logHook :: LogAction -> LogAction
logHook action dynFlags warnReason sev srcSpan msgDoc =
  trace "Log hook called" $! action dynFlags warnReason sev srcSpan msgDoc

When compiling with this plugin, the log hook is invoked for warning messages but not error messages. For the interactive mode case, I have determined that this occurs because when the plugins are first initialized (in setInteractiveDynFlags), the loaded plugins are placed in the interactive context but do not end up in the HscEnv. This results in the plugins not being present at key points surrounding the loading of modules. The fix for this seems simple enough:

setInteractiveDynFlags in compiler/GHC.hs:

    -- Update both plugins cache and DynFlags in the interactive context.
    return $ plugin_env -- use plugin_env here instead of hsc_env0
                { hsc_IC = ic0
                    { ic_plugins = hsc_plugins plugin_env
                    , ic_dflags  = hsc_dflags  plugin_env
                    }
                }

GHC 9.0.x does not discard the loaded plugins in this way and the bug seems to have been a side effect of moving the loaded plugins from DynFlags to HscEnv.

Similarly for phase hooks, the hook is not called at all in GHCi (and only for certain phases in make mode). I suspect the cause is the same as in the logger hook example.

I have not yet investigated why this happens for compilation in make mode (my current focus is plugins intended to be used with GHCi) but I suspect it's because plugins are simply not being initialized early enough.

Expected behavior

The log hook should be invoked for all messages. Phase hooks should be called for all phases.

Environment

  • GHC version used: 9.2.x, head
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking