I think another way to go about this problem is to figure out an alternative to baking in DynFlags to SDocContext (which I feel is the core problem here). The only use of those DynFlags is via sdocWithDynFlags and 94 call sites use them.
- In the frontend, it's used to check for the presence of the flag (like suppress module prefixes, etc.)
- In the code generator, it's used to get the word size, endianness, and other platform specific stuff for platform-specific printing.
- Backpack-related stuff needed to get the package state
- Used in exactly 2 cases: Outputable instances for ComponentId and InstalledUnitId
From what I observed with the majority of use cases, sdocWithDynFlags is used to obviate the need for passing dflags to various ppr* functions, which is a good idea since without it, we'd probably have to pass around DynFlags to a whole lot more pure functions throughout the codebase.
So as others have said, Show instances are just not practical because printing many of the GHC types is highly dependent on the platform and what flags GHC was invoked with.
There are three solutions here:
1.) Figure out a subset of DynFlags (flags, platform details, package state) and only allow those inside of SDocContext and extend SDocContext as
new use cases come up. This is probably not practical as it would require sweeping changes.
2.) Provide a stock set of DynFlags for the purpose of printing with Outputable. It's easy to do for flags and platform details, but tricky to do for package state. This seems to be the most reasonable solution if some sane substitute for package state can be used.
Syd, can you tell us what kind of things you were trying to print out? You can try to pass in unsafeGlobalDynFlags but it may not be what you want. It gets written to on the initialisation of the GHC monad and after the command line options are parsed (so everything will be properly initialised except for package state).
Hope that helps,
Rahul