GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:53:11Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/5872bug in default implementation of popCount2019-07-07T18:53:11ZLevent Erkökbug in default implementation of popCountbase 4.5.0.0 (http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/src/Data-Bits.html\#popCount) gives the default implementation of popCount of the Bits class like this:
```
popCount :: a -> Int
popCount = go 0
...base 4.5.0.0 (http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/src/Data-Bits.html\#popCount) gives the default implementation of popCount of the Bits class like this:
```
popCount :: a -> Int
popCount = go 0
where
go !c 0 = c
go c w = go (c+1) (w .&. w - 1)
```
Alas, .&. binds more tightly than -, thus the last expression parses as `((w .&. w) - 1)` not as `(w .&. (w-1))`, as it was intended.
At the least, this causes `popCount :: Integer -> Int` to behave erratically:
```
Prelude Data.Bits> map popCount [2::Integer .. 4]
[2, 3, 4]
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.4.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"bug in default implementation of popCount","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"base 4.5.0.0 (http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/src/Data-Bits.html#popCount) gives the default implementation of popCount of the Bits class like this:\r\n\r\n{{{\r\npopCount :: a -> Int\r\npopCount = go 0\r\n where\r\n go !c 0 = c\r\n go c w = go (c+1) (w .&. w - 1)\r\n}}}\r\n\r\nAlas, .&. binds more tightly than -, thus the last expression parses as `((w .&. w) - 1)` not as `(w .&. (w-1))`, as it was intended. \r\n\r\nAt the least, this causes `popCount :: Integer -> Int` to behave erratically:\r\n\r\n{{{\r\nPrelude Data.Bits> map popCount [2::Integer .. 4]\r\n[2, 3, 4]\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->7.4.2tibbetibbe