#7411: Exceptions are optimized away in certain situations
-------------------------------------+-------------------------------------
Reporter: SimonHengel | Owner: tdammers
Type: bug | Status: new
Priority: high | Milestone: 8.6.1
Component: Compiler | Version: 7.6.1
Resolution: | Keywords: seq, deepseq,
| evaluate, exceptions
Operating System: Linux | Architecture: x86_64
| (amd64)
Type of failure: Incorrect result | Test Case:
at runtime | simplCore/should_fail/T7411
Blocked By: | Blocking:
Related Tickets: #5129 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by tdammers):
Replying to [comment:20 tdammers]:
> Interestingly, the patch from #5129 does *not* fix this one too, so it's
not just due to incorrectly optimizing `seq` away; there is more happening
here.
Following the #5129 lead, I added some trace logging to the code touched
in #5129; specifically I trapped this case:
{{{
| SeqOp <- op
-> all (expr_ok primop_ok) args
}}}
...which is what caught the `seq#` instances that were inappropriately
optimized away previously.
However, for the offending examples, this trap doesn't fire, which means
we're not hitting the `SeqOp` case at all. So apparently the `seq` call
gets optimized away at an earlier stage.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/7411#comment:23>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#15129: Expose ghc-pkg internals as a library
-------------------------------------+-------------------------------------
Reporter: ryanreich | Owner: (none)
Type: feature | Status: new
request |
Priority: normal | Milestone: 8.6.1
Component: Core | Version: 8.2.2
Libraries |
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
The module [https://downloads.haskell.org/~ghc/latest/docs/html/libraries
/ghc-boot-8.4.1/GHC-PackageDb.html GHC.PackageDb], which is in the `ghc-
boot` package and therefore shipped alongside `base`, and which exposes
the crucial data type `InstalledPackageInfo a b c d e f g` and functions
`readPackageDbForGhc`, `readPackageDbForGhcPkg`, and `writePackageDb`, is
nonetheless crippled outside of GHC:
- The first function requires instances of the `BinaryStringRep` and
`DbUnitIdModuleRep` classes, which do not have any in any public package
- The second one uses a polymorphic parameter that, in order to run
without error, actually needs to be
[https://downloads.haskell.org/~ghc/latest/docs/html/libraries/Cabal-2.2.0.0
/Distribution-InstalledPackageInfo.html
Distribution.InstalledPackageInfo], defined in the completely different
`Cabal` package neither mentioning nor mentioned by `ghc-boot`
- The third one takes two arguments of which the first (a list of
`InstalledPackageInfo a b c d e f g`) is redundant because it can be
constructed from the second, but no conversion function is defined.
While it is possible to write both the instances and conversion function
by hand, it is extremely awkward and I worry that it is also fragile,
given the internal nature of this entire module.
The full functionality of this package is only available within the
[https://github.com/ghc/ghc/blob/master/utils/ghc-pkg/Main.hs Main] module
of `ghc-pkg`, which is highly monolithic despite containing such
[https://github.com/ghc/ghc/blob/master/utils/ghc-pkg/Main.hs#L1226-L1307
generally useful code] as the above instances and conversion function.
Since `GHC.PackageDb` provides so much of `ghc-pkg`'s essential
functionality as a library, it seems reasonable to request that this code
be brought out of the opaque `Main` module and into a public library. I
understand from the comments that `ghc-boot` is not the place for this,
but perhaps one of the following is:
a. `Cabal`, because it already has the `InstalledPackageInfo` (no
parameters) type used by `ghc-pkg`; however, `Cabal` seems committed to
calling `ghc-pkg` as an executable, not providing linkage to its
internals.
b. a separate `ghc-pkg` library containing, possibly, a more carefully
chosen selection of that executable's code.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15129>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#7411: Exceptions are optimized away in certain situations
-------------------------------------+-------------------------------------
Reporter: SimonHengel | Owner: tdammers
Type: bug | Status: new
Priority: high | Milestone: 8.6.1
Component: Compiler | Version: 7.6.1
Resolution: | Keywords: seq, deepseq,
| evaluate, exceptions
Operating System: Linux | Architecture: x86_64
| (amd64)
Type of failure: Incorrect result | Test Case:
at runtime | simplCore/should_fail/T7411
Blocked By: | Blocking:
Related Tickets: #5129 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by tdammers):
OK, boiled it down to a simpler test case that doesn't even involve
`deepseq`:
{{{
import Control.Exception
dslist :: [a] -> b -> b
dslist xs b = go xs `seq` b
where
go [] = ()
go (x:xs) = x `seq` go xs
-- the following variation also reproduces the problem:
-- go (x:xs) = go (x `seq` xs)
main = evaluate (('a':undefined) `dslist` return () :: IO ())
}}}
This is essentially what `deepseq` does on lists, with all the typeclass
instances and type variables manually unrolled.
Note that in order to trigger the bug, we actually do need the `go`
function; if instead we pass the `b` around and recurse directly, the
problem goes away, like so:
{{{
import Control.Exception
dslist :: [a] -> b -> b
dslist xs b = go xs `seq` b
where
dslist [] a = a
dslist (x:xs) a = x `seq` dslist xs a
main = evaluate (('a':undefined) `dslist` return () :: IO ())
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/7411#comment:22>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#7411: Exceptions are optimized away in certain situations
-------------------------------------+-------------------------------------
Reporter: SimonHengel | Owner: tdammers
Type: bug | Status: new
Priority: high | Milestone: 8.6.1
Component: Compiler | Version: 7.6.1
Resolution: | Keywords: seq, deepseq,
| evaluate, exceptions
Operating System: Linux | Architecture: x86_64
| (amd64)
Type of failure: Incorrect result | Test Case:
at runtime | simplCore/should_fail/T7411
Blocked By: | Blocking:
Related Tickets: #5129 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by tdammers):
Another data point: this only happens with lists, not with tuples - e.g.,
the following works as expected:
{{{
import Control.Exception
import Control.DeepSeq
main = evaluate (('a', undefined :: [Char]) `deepseq` return () :: IO ())
}}}
Which is baffling in that the `NFData` instances for tuples and lists are
strikingly similar and *should* do the same thing.
It gets even more baffling when I implement a custom (but isomorphic)
drop-in replacement for `[]`, like so:
{{{
import Control.Exception
import Control.DeepSeq
data List a = Nil | Cons a (List a)
instance NFData a => NFData (List a) where
rnf v = case v of
Nil -> ()
(Cons x (Cons y xs)) -> rnf x `seq` rnf y `seq` rnf xs
main = evaluate ((Cons 'a' $ Cons undefined $ Nil) `deepseq` return () ::
IO ())
}}}
This example reproduces the problem; however, changing the instance like
this behaves:
{{{
instance NFData a => NFData (List a) where
rnf v = case v of
Nil -> ()
(Cons x (Cons y xs)) -> rnf x `seq` rnf y
}}}
In other words, if the `NFData` instance says *not* to look beyond the
second list element, then the failure occurs, but if does look beyond,
then it gets optimized away.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/7411#comment:21>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#7411: Exceptions are optimized away in certain situations
-------------------------------------+-------------------------------------
Reporter: SimonHengel | Owner: tdammers
Type: bug | Status: new
Priority: high | Milestone: 8.6.1
Component: Compiler | Version: 7.6.1
Resolution: | Keywords: seq, deepseq,
| evaluate, exceptions
Operating System: Linux | Architecture: x86_64
| (amd64)
Type of failure: Incorrect result | Test Case:
at runtime | simplCore/should_fail/T7411
Blocked By: | Blocking:
Related Tickets: #5129 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by tdammers):
Interestingly, the patch from #5129 does *not* fix this one too, so it's
not just due to incorrectly optimizing `seq` away; there is more happening
here.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/7411#comment:20>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#10832: Generalize injective type families
-------------------------------------+-------------------------------------
Reporter: jstolarek | Owner: jstolarek
Type: feature | Status: new
request |
Priority: normal | Milestone:
Component: Compiler | Version: 7.11
(Type checker) |
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Revisions: |
-------------------------------------+-------------------------------------
With injective type families we can now declare that type family result
determines the arguments. But ITFs are not yet as expressive as functional
dependencies. For example with FDs I can say:
{{{#!hs
data Nat = Zero | Succ a
class Add a b r | a b -> r, r a -> b
instance Add Zero b b
instance (Add a b r) => Add (Succ a) b (Succ r)
}}}
Here we declare that the result and the first argument taken together
uniquely determine the second argument. This is not currently possible
with ITFs:
{{{#!hs
type family AddTF a b = r | r a -> b where
AddTF Zero b = b
AddTF (Succ a) b = Succ (AddTF a b)
}}}
But we want to be able to say that.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10832>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler