GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T19:11:25Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/1853hpc mix files for Main modules overwrite each other2019-07-07T19:11:25Zguesthpc mix files for Main modules overwrite each otherI have several programs, and hence several files that define Main modules, in the same directory. I build each one with a ghc --make -o Progname. When The hpc mix files describing the compiled modules are dumped in .hpc, the current Main...I have several programs, and hence several files that define Main modules, in the same directory. I build each one with a ghc --make -o Progname. When The hpc mix files describing the compiled modules are dumped in .hpc, the current Main.mix overwrites any previous Main.mix. As a result, I can only get an hpc report from Progname.tix if Progname was the most recent binary to be compiled.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 6.8.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | chris@connett.net |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"hpc mix files for Main modules overwrite each other","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"andy@galois.com"},"version":"6.8.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["chris@connett.net"],"type":"Bug","description":"I have several programs, and hence several files that define Main modules, in the same directory. I build each one with a ghc --make -o Progname. When The hpc mix files describing the compiled modules are dumped in .hpc, the current Main.mix overwrites any previous Main.mix. As a result, I can only get an hpc report from Progname.tix if Progname was the most recent binary to be compiled.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1AndyGillAndyGillhttps://gitlab.haskell.org/ghc/ghc/-/issues/2075hpc should render information about the run in its html markup2019-07-07T19:10:19Zdonshpc should render information about the run in its html markupTo check if a generated coverage test is up to date, it would be useful to have hpc annotate its generated output with the date of the run, the compiler version, and OS info. Perhaps also information about which packages were included in...To check if a generated coverage test is up to date, it would be useful to have hpc annotate its generated output with the date of the run, the compiler version, and OS info. Perhaps also information about which packages were included in the build.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.8.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Multiple |
| Architecture | Unknown |
</details>
<!-- {"blocked_by":[],"summary":"hpc should render information about the run in its html markup","status":"New","operating_system":"Multiple","component":"Code Coverage","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"andy@galois.com"},"version":"6.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown","cc":[""],"type":"FeatureRequest","description":"To check if a generated coverage test is up to date, it would be useful to have hpc annotate its generated output with the date of the run, the compiler version, and OS info. Perhaps also information about which packages were included in the build.","type_of_failure":"OtherFailure","blocking":[]} -->andy@galois.comandy@galois.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/2224-fhpc inteferes/prevents rewrite rules from firing2019-07-07T19:09:39Zdons-fhpc inteferes/prevents rewrite rules from firingUse case:
I'm writing tests for rewrite rules, and using HPC to determine if rules were fired (and their code exercised). HPC is quite cool here, since it lets us see which rules fired, without needing to explicitly export functions to ...Use case:
I'm writing tests for rewrite rules, and using HPC to determine if rules were fired (and their code exercised). HPC is quite cool here, since it lets us see which rules fired, without needing to explicitly export functions to test.
However, -fhpc seems to prevent many rules from firing (likely due to ticks getting in the way?)
For example:
```
import qualified Data.ByteString.Char8 as C
main = print (C.pack "literal")
```
When compiled normally, triggers a nice rewrite rule:
```
$ ghc -O2 A.hs -ddump-rule-firings -c
Rule fired: unpack
Rule fired: Class op show
Rule fired: unpack-list
Rule fired: ByteString packChars/packAddress
```
Now with -fhpc:
```
$ ghc -O2 A.hs -ddump-rule-firings A.hs -c -fhpc
Rule fired: unpack
Rule fired: Class op show
Rule fired: unpack-list
```
What's the best way to ensure the same code is exercised with and without -fhpc here? (I'd quite like to get this working, since rewrite rules benefit from testing.)8.0.1andy@galois.comandy@galois.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/3175hpc should not mark otherwise as "always true"2023-05-07T17:19:01ZEdward Z. Yanghpc should not mark otherwise as "always true"It seems odd to me that hpc would be distressed about the otherwise guard always evaluating to true: isn't that the point of otherwise?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ------------...It seems odd to me that hpc would be distressed about the otherwise guard always evaluating to true: isn't that the point of otherwise?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 6.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"hpc should not mark otherwise as \"always true\"","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"andy@galois.com"},"version":"6.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"It seems odd to me that hpc would be distressed about the otherwise guard always evaluating to true: isn't that the point of otherwise?\r\n","type_of_failure":"OtherFailure","blocking":[]} -->andy@galois.comandy@galois.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/10951HPC program has poor error reporting / strange CLI in general2019-07-07T18:32:56ZMichael SloanHPC program has poor error reporting / strange CLI in general1. Many erroneous usages of the hpc program result in reporting 100% (0/0) coverage. Proposed resolution:
- Report an error and exit with failure. I can't think of a legitimate case where you would want a report that doesn't consider an...1. Many erroneous usages of the hpc program result in reporting 100% (0/0) coverage. Proposed resolution:
- Report an error and exit with failure. I can't think of a legitimate case where you would want a report that doesn't consider any expressions / declarations.
- If a --include flag is specified, I think it would be valuable to output all the module names, so that it's clearer why the --include flag didn't work.
- At the very least, (0/0) coverage shouldn't be reported as "100%".
1. Positional arguments after the initial tix file get interpreted as --include filters, filtering which modules / packages are considered. By default, HPC includes all modules in the report, unless include filters are supplied. If you accidentally provide a positional argument which isn't a valid thing for "--include", then your reports will always be (0/0) coverage. Proposed resolution:
- Deprecate using positional arguments for include filters. This way it will complain about this instead of yielding trivial (0/0) coverage reports
1. Ideally, you'd be able to pass in multiple tix files and combine them in memory instead of using "hpc combine" and generating intermediate tix files. This would be a better usage of positional arguments than include filters. For now, the additional tix files would need to be flag arguments. This also isn't all that useful until #1853 is fixed.
1. `--srcdir`, `--hpcdir`, and `--reset-hpcdirs` interface has strange semantics for searching for mix files. It literally does something roughly like `[sd </> hd | sd <- srcDirs, hd <- hpcDirs]`, and uses this when looking for mix files. This would be OK, except that the `srcdir` must be the work dir used for compilation, in order for source markup to be generated. This means that you are tied to having your hpcdir be a sub-directory of the compilation work dir. Proposed resolution:
- Add `--mixdir`, specifying a path to a mix file directory. Can be supplied multiple times. If `--mixdir` is provided, then it's an error to also use `--hpcdir` / `--reset-hpcdirs`.
- If GHC is provided an absolute `-hpcdir`, then use it rather than appending to the CWD.
1. If anything goes wrong when matching up a module in a tix file with mix metadata, the error is "can not find MODNAME in DIRS". (see the code here: https://github.com/ghc/packages-hpc/blob/fb14d3428ba24d36e779736989dae3092a50a957/Trace/Hpc/Mix.hs\#L87) This is quite confusing because this same message is used for all of the following cases:
- There's a parse error of the mix file
- Any IO error happens
- The module hash mismatches
Instead of fixing the hpc program, I have considered forking it and giving it a new executable name, so that the CLI and behavior can be entirely changed. Thoughts on this alternative? It is appealing because it seems tricky to fix the hpc program's CLI while ensuring that backwards compatibility is maintained.
I am keen on working on fixing this situation, but I want consensus from y'all about the approach that should be taken.
Maybe it makes sense for this hpc-ng program to be developed outside of the GHC repo? This way it can use more recent libraries for generating HTML and parsing command line arguments.https://gitlab.haskell.org/ghc/ghc/-/issues/12631`hpc report` silently ignore non-existent modules2019-07-07T18:25:46Zquabla`hpc report` silently ignore non-existent modules```
hpc report my.tix NotExistingModule
```
reports a coverage of 100% (0/0)
This was confusing to me since I didn't even wanted to supply a module but rather two arguments to --hpcdir without noting that the flag has to be given multi...```
hpc report my.tix NotExistingModule
```
reports a coverage of 100% (0/0)
This was confusing to me since I didn't even wanted to supply a module but rather two arguments to --hpcdir without noting that the flag has to be given multiple times. Instead of a \*\*\*Module *hpc/path* not found\*\*\* message, I got 100% converage.
```
$ hpc version
hpc tools, version 0.67
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 7.10.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"`hpc report` silently ignore non-existent modules","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{\r\nhpc report my.tix NotExistingModule\r\n}}}\r\n\r\nreports a coverage of 100% (0/0)\r\n\r\nThis was confusing to me since I didn't even wanted to supply a module but rather two arguments to --hpcdir without noting that the flag has to be given multiple times. Instead of a ***Module ''hpc/path'' not found*** message, I got 100% converage.\r\n\r\n{{{\r\n$ hpc version\r\nhpc tools, version 0.67\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/13448Make HPC use an RTS option to select the tix file2020-01-23T19:31:52ZDavid FeuerMake HPC use an RTS option to select the tix file[D3357](https://phabricator.haskell.org/D3357) will document the currently-undocumented `HPCTIXFILE` environment variable. I think, however, that we really should change how that's controlled. Make it an RTS option like any other, which ...[D3357](https://phabricator.haskell.org/D3357) will document the currently-undocumented `HPCTIXFILE` environment variable. I think, however, that we really should change how that's controlled. Make it an RTS option like any other, which can be controlled using `with-rtsopts`, `+RTS`, or the `GHCRTS` environment variable.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 8.1 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Make HPC use an RTS option to select the tix file","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Phab:D3357 will document the currently-undocumented `HPCTIXFILE` environment variable. I think, however, that we really should change how that's controlled. Make it an RTS option like any other, which can be controlled using `with-rtsopts`, `+RTS`, or the `GHCRTS` environment variable.","type_of_failure":"OtherFailure","blocking":[]} -->David FeuerDavid Feuerhttps://gitlab.haskell.org/ghc/ghc/-/issues/13452Lock .tix file2019-07-07T18:21:48ZDavid FeuerLock .tix fileThe HPC documentation [warns](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html#caveats-and-shortcomings-of-haskell-program-coverage) that
> HPC does not attempt to lock the `.tix` file, so multiple concurre...The HPC documentation [warns](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html#caveats-and-shortcomings-of-haskell-program-coverage) that
> HPC does not attempt to lock the `.tix` file, so multiple concurrently running binaries in the same directory will exhibit a race condition.
This sounds like something that shouldn't be too terribly hard to fix, once we determine exactly how we want to deal with contention.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 8.0.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | dfeuer |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Lock .tix file","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["dfeuer"],"type":"Bug","description":"The HPC documentation [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html#caveats-and-shortcomings-of-haskell-program-coverage warns] that\r\n\r\n> HPC does not attempt to lock the `.tix` file, so multiple concurrently running binaries in the same directory will exhibit a race condition.\r\n\r\nThis sounds like something that shouldn't be too terribly hard to fix, once we determine exactly how we want to deal with contention.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/14711Machine readable output of coverage2019-07-07T18:15:55ZKoterpillarMachine readable output of coverageWhen integrating with a CI system, it might be useful to fail the build, alert or take other actions based on coverage percentage. To do that, hpc needs to output a summary coverage report in a machine readable format.
For example, the ...When integrating with a CI system, it might be useful to fail the build, alert or take other actions based on coverage percentage. To do that, hpc needs to output a summary coverage report in a machine readable format.
For example, the current output:
```
38% expressions used (1779/4624)
57% boolean coverage (16/28)
56% guards (9/16), 6 always True, 1 always False
58% 'if' conditions (7/12), 2 always False, 3 unevaluated
100% qualifiers (0/0)
7% alternatives used (103/1410)
75% local declarations used (102/136)
40% top-level declarations used (185/457)
```
can be represented as:
```
{
expressions: { total: 4624, used: 1779, percentage: 0.38 },
boolean: { total: 28, used: 16, percentage: 0.57 },
<...>
}
```
This output can be then parsed to decide whether to fail the build, produce a coverage graph over time, etc.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.2.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Machine readable output of coverage","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"When integrating with a CI system, it might be useful to fail the build, alert or take other actions based on coverage percentage. To do that, hpc needs to output a summary coverage report in a machine readable format.\r\n\r\nFor example, the current output:\r\n\r\n{{{\r\n 38% expressions used (1779/4624)\r\n 57% boolean coverage (16/28)\r\n 56% guards (9/16), 6 always True, 1 always False\r\n 58% 'if' conditions (7/12), 2 always False, 3 unevaluated\r\n 100% qualifiers (0/0)\r\n 7% alternatives used (103/1410)\r\n 75% local declarations used (102/136)\r\n 40% top-level declarations used (185/457)\r\n}}}\r\n\r\ncan be represented as:\r\n\r\n{{{\r\n{\r\n expressions: { total: 4624, used: 1779, percentage: 0.38 },\r\n boolean: { total: 28, used: 16, percentage: 0.57 },\r\n <...>\r\n}\r\n}}}\r\n\r\nThis output can be then parsed to decide whether to fail the build, produce a coverage graph over time, etc.","type_of_failure":"OtherFailure","blocking":[]} -->jproyojproyohttps://gitlab.haskell.org/ghc/ghc/-/issues/15498HPC: do notation marks () as non-covered2019-07-07T18:04:29Ztom-bopHPC: do notation marks () as non-coveredWith this Main.hs, the "()" in "pure ()" is marked by HPC as a non-covered expression:
```hs
foo :: IO ()
foo = do
_ <- putStrLn "Unimportant string"
pure ()
main :: IO ()
main = do
foo
putStrLn "Unimportant #2"
```
Repro:...With this Main.hs, the "()" in "pure ()" is marked by HPC as a non-covered expression:
```hs
foo :: IO ()
foo = do
_ <- putStrLn "Unimportant string"
pure ()
main :: IO ()
main = do
foo
putStrLn "Unimportant #2"
```
Repro:
> - `ghc -fhpc Main.hs`
> - `./Main`
> - `hpc markup Main.tix`
This is an admittedly small issue, but it can be valuable for a project to aspire to 100% code coverage and false negatives prevent us from getting there.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 8.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"HPC: do notation marks () as non-covered","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"With this Main.hs, the \"()\" in \"pure ()\" is marked by HPC as a non-covered expression:\r\n\r\n{{{#!hs\r\nfoo :: IO ()\r\nfoo = do\r\n _ <- putStrLn \"Unimportant string\"\r\n pure ()\r\n\r\nmain :: IO ()\r\nmain = do\r\n foo\r\n putStrLn \"Unimportant #2\"\r\n}}}\r\n\r\nRepro:\r\n - `ghc -fhpc Main.hs`\r\n - `./Main`\r\n - `hpc markup Main.tix`\r\n\r\nThis is an admittedly small issue, but it can be valuable for a project to aspire to 100% code coverage and false negatives prevent us from getting there.\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15776Untested modules excluded from hpc coverage report2019-07-07T18:03:03Zramirez7Untested modules excluded from hpc coverage reportIf I add a new module to my project without adding testing and then generate a code coverage report, there is no mention of the new module in the report.
I believe the correct behavior is for the module to be included with it being 0% c...If I add a new module to my project without adding testing and then generate a code coverage report, there is no mention of the new module in the report.
I believe the correct behavior is for the module to be included with it being 0% covered (w/corresponding highlighted source)
I posted some details here: https://www.reddit.com/r/haskell/comments/9mjwr6/how_to_get_hpc_to_include_fullyuncovered_modules/
As a workaround, I could probably use the hpc library to add 0% coverage for all modules to tix files. But that feels hacky.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 8.4.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Untested modules excluded from hpc coverage report","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"If I add a new module to my project without adding testing and then generate a code coverage report, there is no mention of the new module in the report.\r\n\r\nI believe the correct behavior is for the module to be included with it being 0% covered (w/corresponding highlighted source)\r\n\r\nI posted some details here: https://www.reddit.com/r/haskell/comments/9mjwr6/how_to_get_hpc_to_include_fullyuncovered_modules/\r\n\r\nAs a workaround, I could probably use the hpc library to add 0% coverage for all modules to tix files. But that feels hacky.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/15932DeriveFunctor and GeneralizedNewtypeDeriving instances never reporting as cov...2021-03-04T08:53:07ZdaveanDeriveFunctor and GeneralizedNewtypeDeriving instances never reporting as coveredWhen testing coverage of test cases, HPC does not report some instances as receiving coverage even though it seems they are. Particularly, when one hand derives the functions they show full coverage. The specific instances in question ap...When testing coverage of test cases, HPC does not report some instances as receiving coverage even though it seems they are. Particularly, when one hand derives the functions they show full coverage. The specific instances in question appear to be ones derived via DeriveFunctor and GeneralizedNewtypeDeriving. Problems have been observed with at least Functor, Applicative, and Monad.
A minimal example is attached, and available as a cabal project at https://code.xkrd.net/davean/minimal-coverage-test. To reproduce, run "cabal v2-test --enable-coverage" and view the resulting coverage HTML files.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------- |
| Version | 8.6.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"DeriveFunctor and GeneralizedNewtypeDeriving instances never reporting as covered","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When testing coverage of test cases, HPC does not report some instances as receiving coverage even though it seems they are. Particularly, when one hand derives the functions they show full coverage. The specific instances in question appear to be ones derived via DeriveFunctor and GeneralizedNewtypeDeriving. Problems have been observed with at least Functor, Applicative, and Monad.\r\n\r\nA minimal example is attached, and available as a cabal project at https://code.xkrd.net/davean/minimal-coverage-test. To reproduce, run \"cabal v2-test --enable-coverage\" and view the resulting coverage HTML files.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3Javran ChengJavran Chenghttps://gitlab.haskell.org/ghc/ghc/-/issues/16380HPC's CLI is awkward2019-07-07T18:00:19ZMaxGabrielHPC's CLI is awkwardhpc's command line interface could be brought more in line with other Haskell tools (and most CLIs I've used). I would expect all of the following commands to work:
```
hpc --version
hpc --help
hpc markup --help
```
Currently these com...hpc's command line interface could be brought more in line with other Haskell tools (and most CLIs I've used). I would expect all of the following commands to work:
```
hpc --version
hpc --help
hpc markup --help
```
Currently these commands are:
```
hpc version
hpc help
hpc help markup
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Code Coverage |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"HPC's CLI is awkward","status":"New","operating_system":"","component":"Code Coverage","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"hpc's command line interface could be brought more in line with other Haskell tools (and most CLIs I've used). I would expect all of the following commands to work:\r\n\r\n{{{\r\nhpc --version\r\nhpc --help\r\nhpc markup --help\r\n}}}\r\n\r\nCurrently these commands are:\r\n\r\n{{{\r\nhpc version\r\nhpc help\r\nhpc help markup\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/17078hpc: do away with String, to avoid making a write() syscall per character2020-01-23T19:42:30ZAlp Mestanogullarihpc: do away with String, to avoid making a write() syscall per characterFrom https://gitlab.haskell.org/ghc/ghc/merge_requests/1598#note_218752 (by @nh2):
> At some point we probably want to switch this away from `String` entirely, given that `hPutStr` floods syscalls by doing one `write()` syscall *for eac...From https://gitlab.haskell.org/ghc/ghc/merge_requests/1598#note_218752 (by @nh2):
> At some point we probably want to switch this away from `String` entirely, given that `hPutStr` floods syscalls by doing one `write()` syscall *for each character*.
This is obviously quite inefficient and should be replaced by code that makes as few `write()` syscalls as possible.https://gitlab.haskell.org/ghc/ghc/-/issues/17155Code coverage requires all derived methods to be tested2020-01-23T19:43:03ZhilcodeCode coverage requires all derived methods to be tested## Summary
Running "stack --coverage test" yields incorrect results.
## Steps to reproduce
Untar coverage-bug.tbz2 and run "stack --coverage test". Then look at the generated HTML page for Lib.hs (Lib.hs.html). It shows zero coverage ...## Summary
Running "stack --coverage test" yields incorrect results.
## Steps to reproduce
Untar coverage-bug.tbz2 and run "stack --coverage test". Then look at the generated HTML page for Lib.hs (Lib.hs.html). It shows zero coverage for Ord even though it was clearly tested.
[coverage-bug.tbz2](/uploads/4f3cdd657ff85dcf027ad655f9b4bf68/coverage-bug.tbz2)
## Expected behavior
Correct coverage numbers.
## Environment
I tried it with everything listed on https://www.stackage.org/.
* Nightly 2019-09-04
* LTS 14.4 for ghc-8.6.5
* LTS 13.19 for ghc-8.6.4
* LTS 13.11 for ghc-8.6.3
* LTS 12.26 for ghc-8.4.4
* LTS 12.14 for ghc-8.4.3
* LTS 11.22 for ghc-8.2.2
* LTS 9.21 for ghc-8.0.2
* LTS 7.24 for ghc-8.0.1
* LTS 6.35 for ghc-7.10.3
* LTS 3.22 for ghc-7.10.2
Optional:
* Operating System: Gentoo
* System Architecture: x86_64https://gitlab.haskell.org/ghc/ghc/-/issues/17607T17073 fails on Windows2021-03-01T02:34:57ZBen GamariT17073 fails on Windows```
=====> T17073(hpc) 2152 of 7299 [0, 0, 0]
cd "hpc/T17073.run" && $MAKE -s --no-print-directory T17073 HPC="/c/GitLabRunner/builds/78d7d3f9/0/ghc/ghc/inplace/bin/hpc.exe" <
Wrong exit code for T17073()(expected 0 , actual 2 )
Stdou...```
=====> T17073(hpc) 2152 of 7299 [0, 0, 0]
cd "hpc/T17073.run" && $MAKE -s --no-print-directory T17073 HPC="/c/GitLabRunner/builds/78d7d3f9/0/ghc/ghc/inplace/bin/hpc.exe" <
Wrong exit code for T17073()(expected 0 , actual 2 )
Stdout ( T17073 ):
Добрый день
Error: unable to find tix file for:T17073
Usage: hpc report [OPTION] .. <TIX_FILE> [<MODULE> [<MODULE> ..]]
Output textual report about program coverage
Options:
--per-module show module level detail
--decl-list show unused decls
--exclude=[PACKAGE:][MODULE] exclude MODULE and/or PACKAGE
--include=[PACKAGE:][MODULE] include MODULE and/or PACKAGE
--srcdir=DIR path to source directory of .hs files
multi-use of srcdir possible
--hpcdir=DIR append sub-directory that contains .mix files
default .hpc [rarely used]
--reset-hpcdirs empty the list of hpcdir's
[rarely used]
--xml-output show output in XML
--verbosity=[0-2] verbosity level, 0-2
default 1
Stderr ( T17073 ):
make[2]: *** [Makefile:14: T17073] Error 1
*** unexpected failure for T17073(hpc)
```Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/17831HPC tick floating seems wrong2020-02-13T22:40:14ZSimon Peyton JonesHPC tick floating seems wrongConsider this:
```
import GHC.Exts
bar :: () -> Proxy# Int
bar _ = proxy# @Int
foo xs f = map f xs
```
And compile with `-O0 -fhpc`. We get this
```
foo :: forall a b. [a] -> (a -> b) -> [b]
foo
= \ (@a_aC5) (@b_aC6) ->
letrec...Consider this:
```
import GHC.Exts
bar :: () -> Proxy# Int
bar _ = proxy# @Int
foo xs f = map f xs
```
And compile with `-O0 -fhpc`. We get this
```
foo :: forall a b. [a] -> (a -> b) -> [b]
foo
= \ (@a_aC5) (@b_aC6) ->
letrec {
foo_aC9 :: [a_aC5] -> (a_aC5 -> b_aC6) -> [b_aC6]
[LclId]
foo_aC9
= \ (xs_avz :: [a_aC5]) (f_avA :: a_aC5 -> b_aC6) ->
hpc<Foo,3>
hpc<Foo,2>
map @a_aC5 @b_aC6 (hpc<Foo,0> f_avA) (hpc<Foo,1> xs_avz); } in
foo_aC9
bar :: () -> Proxy# Int
bar = \ (ds_dCz :: ()) -> hpc<Foo,5> hpc<Foo,4> proxy# @(*) @Int
==================== Desugar (after optimization) ====================
bar :: () -> Proxy# Int
bar = \ _ [Occ=Dead] ->
(hpc<Foo,5> hpc<Foo,4> proxy#) @(*) @Int
foo :: forall a b. [a] -> (a -> b) -> [b]
foo
= \ (@a_aC5) (@b_aC6) (xs_avz :: [a_aC5]) (f_avA :: a_aC5 -> b_aC6) ->
hpc<Foo,3> hpc<Foo,2> map @a_aC5 @b_aC6
(hpc<Foo,0> f_avA)
(hpc<Foo,1> xs_avz)
```
Notice that for `bar` the HPC ticks wrap the entire expression. But
for `foo`, the HPC ticks are pushed inwards so we get
```
(hpc<Foo,5> hpc<Foo,4> proxy#)
@(*)
@Int
```
The treatment of HPC ticks seeme weirdly inconsistent: they stay
outside value application but get pushed into the head of a type application.
Why?
This inconsistent treatment is maintained by the simplifier, so we
end up with the rather silly code for `bar` after CorePrep
```
bar = \_ -> case (hpc<Foo,5> hpc<Foo,4> proxy#) of
f -> f @(*) @Int
```
This mysterious behaviour happens because of the elaborate
and poorly-documented function `CoreUtils.mkTick`, which does this
"push ticks inside type application stuff":
```
App f arg
-- Always float through type applications.
| not (isRuntimeArg arg)
-> mkTick' (top . flip App arg) rest f
```
Maybe none of this is a bug, and it probably doesn't affect many programs, but looks wrong to me. And I wish `mkTick` was properly documented.
All this arose from looking at [this commennt](https://gitlab.haskell.org/ghc/ghc/merge_requests/1869#note_253458) in !1869https://gitlab.haskell.org/ghc/ghc/-/issues/17834Support RecordWildCards in HPC2020-06-29T20:59:20ZBrandon ChinnSupport RecordWildCards in HPC## Summary
Data type records are marked as "never executed" when I use them only with RecordWildCards. The same could probably be said for NamedFieldPuns as well.
## Steps to reproduce
```haskell
{-# LANGUAGE RecordWildCards #-}
data...## Summary
Data type records are marked as "never executed" when I use them only with RecordWildCards. The same could probably be said for NamedFieldPuns as well.
## Steps to reproduce
```haskell
{-# LANGUAGE RecordWildCards #-}
data Foo = Foo
{ foo1 :: Int
, foo2 :: Int
}
showFoo :: Foo -> IO ()
showFoo Foo{..} = print (foo1, foo2)
main = showFoo (Foo 1 2)
```
Running the above with coverage shows `foo1` and `foo2` as uncovered.
[Main.hs](/uploads/1c2bf48faab46d8da7a7cc10bd50aaae/Main.hs)
[Main.hs.html](/uploads/da8184b460bc0d399de6f498997191ab/Main.hs.html)
## Expected behavior
`foo1` and `foo2` should be marked as "hit"
## Environment
* GHC version used: 8.8.1
Optional:
* Operating System: MacOS 10.14.6
* System Architecture:https://gitlab.haskell.org/ghc/ghc/-/issues/17846runtimeRepPrimRep panic when combining UnboxedTuples with -fhpc or {-prof,-fp...2021-06-11T22:13:10ZRyan ScottruntimeRepPrimRep panic when combining UnboxedTuples with -fhpc or {-prof,-fprof-auto}(Originally observed in !2703.)
The following program:
```hs
{-# LANGUAGE UnboxedTuples #-}
module Bug where
makeUTup2 = (#,#)
```
Panics on GHC 8.0.2 or later if you compile it with `-fhpc`:
```
$ /opt/ghc/8.8.2/bin/ghc -fhpc -fforc...(Originally observed in !2703.)
The following program:
```hs
{-# LANGUAGE UnboxedTuples #-}
module Bug where
makeUTup2 = (#,#)
```
Panics on GHC 8.0.2 or later if you compile it with `-fhpc`:
```
$ /opt/ghc/8.8.2/bin/ghc -fhpc -fforce-recomp Bug.hs
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.8.2 for x86_64-unknown-linux):
runtimeRepPrimRep
typePrimRep (a_12 :: TYPE k0_10)
k0_10
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1159:37 in ghc:Outputable
pprPanic, called at compiler/simplStg/RepType.hs:365:5 in ghc:RepType
```
Or, alternatively, with the combination of `-prof` and `-fprof-auto`:
```
$ /opt/ghc/8.8.2/bin/ghc -prof -fprof-auto -fforce-recomp Bug.hs
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.8.2 for x86_64-unknown-linux):
runtimeRepPrimRep
typePrimRep (a_12 :: TYPE k0_10)
k0_10
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1159:37 in ghc:Outputable
pprPanic, called at compiler/simplStg/RepType.hs:365:5 in ghc:RepType
```
A workaround is to manually eta-expand `mkUTup2`:
```hs
{-# LANGUAGE UnboxedTuples #-}
module Bug where
makeUTup2 x y = (# x, y #)
```https://gitlab.haskell.org/ghc/ghc/-/issues/18289CAS operations do not work when compiled with -fhpc2020-06-02T17:55:22ZAlexey KuleshevichCAS operations do not work when compiled with -fhpc## Summary
Below is a short piece of code that works fine until it is compile with `-fhpc`
```haskell
data MutableArray a = MutableArray (MutableArray# RealWorld a)
readArray :: MutableArray a -> Int -> IO a
readArray (MutableArray ma...## Summary
Below is a short piece of code that works fine until it is compile with `-fhpc`
```haskell
data MutableArray a = MutableArray (MutableArray# RealWorld a)
readArray :: MutableArray a -> Int -> IO a
readArray (MutableArray ma#) (I# i#) = IO (readArray# ma# i#)
casArray :: MutableArray a -> Int -> a -> a -> IO (Bool, a)
casArray (MutableArray ma#) (I# i#) expected new =
IO $ \s ->
case casArray# ma# i# expected new s of
(# s', failed#, actual #) -> (# s', (isTrue# failed#, actual) #)
newArray :: Int -> a -> IO (MutableArray a)
newArray (I# n#) a =
IO $ \s ->
case newArray# n# a s of
(# s', ma# #) -> (# s', MutableArray ma# #)
main :: IO ()
main = do
arr <- newArray 1 99
expected <- readArray arr 0
(hasFailed, actual) <- casArray arr 0 expected 100
current <- readArray arr 0
putStrLn $
unlines
[ "========== Boxed Array ==========="
, "Expected: " ++ show expected
, "Actual: " ++ show actual
, "Has CAS failed: " ++ show hasFailed
, "Current: " ++ show current
]
```
Regular compilation produces expected output:
```shell
========== Boxed Array ===========
Expected: 99
Actual: 100
Has CAS failed: False
Current: 100
```
But compiling the same thing with `-fhpc`, results in a binary that produces different output 100% of the time:
```shell
========== Boxed Array ===========
Expected: 99
Actual: 99
Has CAS failed: True
Current: 99
```
It is clear from the output that CAS can never succeed with `hpc` enabled, which makes it impossible to get coverage reports when testing atomic operations. Same behavior is observed for `casSmallArray#` and `casMutVar#`, but unsurprisingly not for the `casByteArray#`.
## Steps to reproduce
Attached file [cas.hs](/uploads/e37882a10674c6eb2acd514bcf9b4e15/cas.hs) reproduces the behavior for all affected CAS operations. Same file can be found in [this repo](https://github.com/lehins/bugs/blob/master/haskell/ghc-cas-array/cas.hs) Steps to reproduce (`-threaded` isn't necessary, added just in case):
Correct behavior:
```
$ ghc -fforce-recomp -threaded cas.hs && ./cas
[1 of 1] Compiling Main ( cas.hs, cas.o )
Linking cas ...
========== Boxed Array ===========
Expected: 99
Actual: 100
Has CAS failed: False
Current: 100
========== Small Boxed Array ===========
Expected: 99
Actual: 100
Has CAS failed: False
Current: 100
========== MutVar ===========
Expected: 99
Actual: 100
Has CAS failed: False
Current: 100
========== ByteArray ===========
Expected: 99
Actual: 100
Has CAS failed: False
Current: 100
```
Broken:
```haskell
$ rm *.tix; ghc -fforce-recomp -threaded -fhpc cas.hs && ./cas
[1 of 1] Compiling Main ( cas.hs, cas.o )
Linking cas ...
========== Boxed Array ===========
Expected: 99
Actual: 99
Has CAS failed: True
Current: 99
========== Small Boxed Array ===========
Expected: 99
Actual: 99
Has CAS failed: True
Current: 99
========== MutVar ===========
Expected: 99
Actual: 99
Has CAS failed: True
Current: 99
========== ByteArray ===========
Expected: 99
Actual: 100
Has CAS failed: False
Current: 100
```
## Expected behavior
Expected behavior is that `-fhpc` flag should not change semantics of `casArray#`, `casSmallArray#` and `casMutVar#`
## Environment
* GHC version used: 7.10.3 - 8.10.1
Optional:
* Operating System: Ubuntu 18.04
* System Architecture: x86_64