Haddock not obeying ignore-exports correctly - haskell

Take this example:
{-# OPTIONS_HADDOCK ignore-exports #-}
module HaddockTest (e1) where
-- * Exported
-- | This is exported.
e1 :: Int
e1 = 1
-- * Private
-- | This is not exported.
p1 :: Int
p1 = 1
Strangely, the doc-string for the non-exported declaration is ignored, even though we get the structure otherwise correctly:
Does anyone have a clue? For the record, invoking via cabal haddock --internal doesn't help, nor does haddock --ignore-all-exports.

It's a bug in haddock-2.10, reported in March and fixed soon after, but the haddock shipped with GHC-7.4.1 was affected. Presumably the haddock shipped with 7.4.2 includes the fix (haven't built 7.4.2 yet).

Related

Code that compiles with ghc but not with cabal new-run

I have this program Main.hs:
main :: IO ()
main = do
if False then undefined
else do
let x = 5
print x
When I compile it with ghc Main.hs it compils well generating a Main executable, but when (after initializing cabal with cabal init) I try to make a cabal new-run it gives an error:
$ cabal new-run
Build profile: -w ghc-8.6.5 -O1
In order, the following will be built (use -v for more details):
- ghc-vs-cabal-0.1.0.0 (exe:ghc-vs-cabal) (file Main.hs changed)
Preprocessing executable 'ghc-vs-cabal' for ghc-vs-cabal-0.1.0.0..
Building executable 'ghc-vs-cabal' for ghc-vs-cabal-0.1.0.0..
[1 of 1] Compiling Main ( Main.hs, /home/ivan/ghc_vs_cabal/dist-newstyle/build/x86_64-linux/ghc-8.6.5/ghc-vs-cabal-0.1.0.0/x/ghc-vs-cabal/build/ghc-vs-cabal/ghc-vs-cabal-tmp/Main.o )
Main.hs:4:10: error: Empty 'do' block
|
4 | else do
| ^^
With cabal run it also gives error.
I have cabal version 2.4.0.0:
$ cabal --version
cabal-install version 2.4.0.0
compiled using version 2.4.0.1 of the Cabal library
And ghc version 8.6.5:
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.5
Does somebody know what is happening?
I know that I can fix it if I add indentation:
main :: IO ()
main = do
if False then undefined
else do
let x = 5
print x
But I want to know why it compiles with ghc but not with cabal new-run
Your code requires a language extension to parse: NondecreasingIndentation. This extension exists to avoid the awkward runaway effect of nested dos
main :: IO ()
main = do
if False then undefined
else do -- next block should be indented in standard Haskell
let x = 5
print x -- ...but this can easily get out of hand if you do it multiple times
NondecreasingIndentation allows a nested do block to register as nested as long as it's indented as much as the containing block, instead of more than the container.
According to the GHC manual, NondecreasingIndentation is on by default but disabled in Haskell2010 mode (unless explicitly enabled again). I can't find the corresponding cabal documentation, but we can probably guess it defaults to specifying Haskell2010.
You can specify extensions in a source file to be enabled or disabled regardless of external options by adding a pragma like
{-# LANGUAGE NondecreasingIndentation #-}
to the very top of the file.

How to profile TemplateHaskell built with Cabal?

Full project at https://github.com/ysangkok/cabal-profiling-issue
The project contains scaffolding generated by cabal init. I'll paste the most interesting source snippets now.
In Main.hs I have:
newtype Wrapper = Wrapper Int
deriveConvertible ''Wrapper ''Int
in TH.hs I have:
import Data.Convertible
deriveConvertible :: TH.Name -> TH.Name -> TH.Q [TH.Dec]
deriveConvertible newType otherType = do
Just newCon <- TH.lookupValueName (TH.nameBase newType)
v <- TH.newName "v"
[d|
instance Convertible $(TH.conT newType) $(TH.conT otherType) where
safeConvert $(TH.conP newCon [TH.varP v]) = Right $(TH.varE v)
instance Convertible $(TH.conT otherType) $(TH.conT newType) where
safeConvert source = Right ($(TH.conE newCon) source)
|]
But if I put profiling: true in cabal.project and run cabal build with GHC 8.6.5 and Cabal 3.4.0.0 (installed using ghcup), I get:
Failed to load interface for 'Data.Convertible.Base'
Perhaps you haven't installed the profiling libraries for package 'convertible-1.1.1.0'?
What is wrong with the code, and why does it compile without profiling, but fails when enabled?
It is a known problem about compile multi-module program that contains TH code for profiling, see related sections in the documentation:
This causes difficulties if you have a multi-module program containing
Template Haskell code and you need to compile it for profiling,
because GHC cannot load the profiled object code and use it when
executing the splices.
As a workaround, just put TemplateHaskell into the other-modules in your test.cabal,
other-extensions: TemplateHaskell
Then building with profiling (i.e., with the cabal build --enable-library-profiling) every thing would be ok.
For more details about why we need TemplateHaskell in other-modules section, see https://github.com/haskell/cabal/issues/5961.

Plugin name lookup behavior change from GHC 8.4 series

[Update: Turns out this was a GHC bug and it is now fixed, slated for the 8.6.4 release: https://ghc.haskell.org/trac/ghc/ticket/16104#comment:8 ]
I'm trying to port a core plugin to GHC 8.6.3, which was last working fine with GHC 8.4 series. Unfortunately, I'm running into issues. Wondering if pluging programming requirements have changed, or is this a regression in GHC itself. I boiled it down to the following example and would like some guidance on how to make this work:
I have the following in file 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
And I have a very simple Test.hs file:
{-# OPTIONS_GHC -fplugin TestPlugin #-}
main :: IO ()
main = return ()
With GHC-8.4.2, I have:
$ 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!
But with GHC 8.6.3, I get:
$ 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
The problem goes away if I change Test.hs to:
{-# OPTIONS_GHC -fplugin TestPlugin #-}
import Data.Bits -- Should not be required in the client code!
main :: IO ()
main = return ()
That is, if I explicitly import Data.Bits. But tis is quite undesirable, since Test.hs is client code and the users of the plugin have no reason to import all bunch of modules the plugin might need for its own purposes. (In practice, this would require clients to import a whole bunch of irrelevant modules; quite unworkable and not maintainable.)
I've found the following stack-overflow ticket, which seems to suffer from a similar problem: How to replicate the behaviour of 'name in a TH splice However, the answer suggested there is just not OK in this case (and perhaps wasn't really OK there either) since it would require unnecessary changes to client code in my case that is just not reasonable to expect. (Perhaps #JoachimBretner has an idea?) I've also filed this as a GHC ticket (https://ghc.haskell.org/trac/ghc/ticket/16104#ticket), but feedback from the stack-overflow community is greatly appreciated.
Should I be coding my plugin differently? Or is this a GHC regression?
Not a direct answer, but when I need to “hard-code” a name in a GHC plugin, I don’t use TH. Instead, I use findImportedModule and lookupOrig to look it up, e.g. as in
lookupJDITyCon :: TcPluginM Class
lookupJDITyCon = do
Found _ md <- findImportedModule jdiModule Nothing
jdiTcNm <- lookupOrig md (mkTcOcc "JustDoIt")
tcLookupClass jdiTcNm
where
jdiModule = mkModuleName "GHC.JustDoIt"
from the code of my ghc-justdoit plugin.
I use Template Haskell names when the user needs to mention names, e.g. in splices or annotations, that I want to pick up in the plugin. This is what I do in inspection-testing. I discuss this a bit in the appendix of the Inspection Testing paper.

Problems with SourceGraph (Haskell)

I try to visualize an existing Haskell code base with SourceGraph.
SourceGraph mycabal.cabal
But all I get are error messages like this:
Could not parse source file ./src/mysource.hs
SourceGraph: Could not find data file templates/default.html
Any hints what to do or where to look for documentation?
The only documentation I have found so far is this one: http://code.haskell.org/~ivanm/Sample_SourceGraph/SourceGraph/SourceGraph.html which unfortunately only consists of catchy images but with no hints how to produce them.
Regarding your immediate question, it seems like the best documentation here is the source: http://code.haskell.org/SourceGraph/
I tried it on a repository of my own, and ran into the parsing issue, too. This is haskell-src-exts failing to parse a module. The following patch shows the actual error:
--- Parsing.hs 2013-02-14 12:59:34.000000000 +0100
+++ ../SourceGraph-0.7.0.5-fixed/Parsing.hs 2014-04-08 20:49:54.000000000 +0200
## -64,7 +64,7 ##
parseFile :: FileContents -> Either FilePath Module
parseFile (p,f) = case (parseFileContentsWithMode mode f) of
(ParseOk hs) -> Right hs
- _ -> Left p
+ x -> Left $ p ++ ": " ++ show x
where
mode = defaultParseMode { parseFilename = p
, fixities = Nothing
It turns out that most of my failing modules failed because "MultiParamTypeClasses is not enabled". This is apparently haskell-src-exts being rightfully strict, while ghc is happy without the MultiParamTypeClasses extension: https://github.com/haskell-suite/haskell-src-exts/issues/29
So as a quick fix, try adding
{-# LANGUAGE MultiParamTypeClasses #-}
at the top of your failing modules.
Just ran into a similar issue, so I thought I'd document here what I did. I put my changes in a patch file.
https://gist.github.com/ivanperez-keera/b398ce71a22e8a4849f3
cabal sandbox init
cabal unpack SourceGraph
wget https://gist.githubusercontent.com/ivanperez-keera/b398ce71a22e8a4849f3/raw/bf26ffc45564934c0f175e7619ded8a299a9b7d5/verbose-sourcegraph.patch
cd SourceGraph-0.7.0.6/
patch -i ../verbose-sourcegraph.patch
cd ..
cabal install SourceGraph-0.7.0.6/
Most of the "errors" in my files where due to bang patterns and multi param type classes. There must be a better solution to make SourceGraph's parse mode default to the same as GHC.

Haskell: How do I get the values of #define-d constants?

In a Haskell program, what's the best way to use constants defined in C headers?
For this task, hsc2hs is your friend.
For a simple example, let's get the value of INT_MAX from limits.h.
$ cat >IntMax.hsc
module Main where
#include <limits.h>
c_INT_MAX = #const INT_MAX
main = print c_INT_MAX
With hsc2hs, we can #include headers and use the values of constants with the #const directive.
Instead of building by hand, use Cabal:
$ cat >intmax.cabal
Name: intmax
Version: 0.0
Cabal-Version: >=1.2
Build-Type: Simple
Executable intmax
Main-Is: IntMax.hs
Build-Depends: base
Notice that even though the name of the main program is IntMax.hsc, the Main-Is line points to IntMax.hs. When Cabal looks for IntMax.hs but finds IntMax.hsc, it automatically feeds the latter through hsc2hs as part of the build.
$ cabal configure
Resolving dependencies...
Configuring intmax-0.0...
$ cabal build
Prerocessing executables for intmax-0.0...
Building intmax-0.0...
[1 of 1] Compiling Main ( dist\build\intmax\intmax-tmp\IntMax.hs, dist\build\intmax\intmax-tmp\Main.o )
Linking dist\build\intmax\intmax.exe ...
$ ./dist/build/intmax/intmax
2147483647
Note that you'll want to break up lines with multiple constants. Say you're assembling a bitfield to pass to FormatMessage. You'll want to write it as
flags = #const FORMAT_MESSAGE_FROM_SYSTEM
.|.
#const FORMAT_MESSAGE_IGNORE_INSERTS
Putting them all on one line will result in syntax errors.
GHC is moving away from -fvia-c and towards -fasm wherever possible.
One side effect is that your program may be compiled without using any C headers at all, even in -fvia-c mode, in order to ensure that the compilation results are functionally identical to GHC in -fasm mode.
Thus it is necessary to use hsc2hs, c2hs, or other preprocessors run before GHC compiles sources.
c2hs natively supports enum constants... it's been a while, but I think something like this is right.
#c
enum Foo = { Bar, Baz };
void something(enum Foo foo) {}
#endc
{#enum Foo#}
somethingBar = {#call pure something#} (cFromEnum Bar)
#define'd constants are a tick trickier. I've always just copied them inline, or used additional C to transform then into enums or const variables.

Resources