[GHC] #13943: Compiler infinite loop with GHC-8.2
GHC
ghc-devs at haskell.org
Thu Sep 7 21:55:30 UTC 2017
#13943: Compiler infinite loop with GHC-8.2
-------------------------------------+-------------------------------------
Reporter: vagarenko | Owner: (none)
Type: bug | Status: new
Priority: high | Milestone: 8.2.2
Component: Compiler | Version: 8.2.1-rc3
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: #12791 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by dfeuer):
I think it's basically wrong for the specializer to select a top-level
instance that might be overlapped by one that's given. However, it would
be very sad to lose this important optimization in the overwhelmingly more
common no-overlap case. I think the right goal is this: neither the type
checker nor the optimizer should have to bend over backwards to worry
about overlapping instances in the common case that there aren't any. I
believe that we can look at the future in a few stages:
==== Short term ====
When a potential instance is given, don't specialize to a top-level
instance if any of the following hold:
- The instance is marked `OVERLAPPABLE` or `OVERLAPS`.
- The instance is polymorphic, appears in a module declaring
`OverlappingInstances`, and is not marked `INCOHERENT`.
- There is a visible overlapping instance that might match.
This short-term change doesn't fix the problem in all cases, because an
instance declared in a module that doesn't mention overlapping can be
overlapped in an importing module anyway. So we should probably add an
option to avoid specializing to ''any'' non-`INCOHERENT` polymorphic
instance when a given could possibly match.
==== Short-medium term ====
Only allow an instance to be overlapped if it's explicitly marked
`OVERLAPPABLE` or `OVERLAPS`. This is a breaking change, and people will
gripe, but I don't think there's any less-invasive way to make this even
''moderately'' robust. Most of the rest of this comment is about trying to
make things robust even in the more complicated context of `GADTs`,
`RankNTypes`, and `ConstraintKinds`.
Add a `NO_OVERLAP` class declaration pragma to allow users to decree that
overlapping instances for a particular class are prohibited. Question:
should the pragma be per-class or per-parameter? I think probably per-
parameter. Given
{{{#!hs
class Foo a {-# NO_OVERLAP #-} b
}}}
a constraint like `Foo Int b` is much better behaved than one like `Foo a
b`.
==== Medium-long term ====
Only allow overlapping instances of a class if the definition of that
class is explicitly marked with a pragma. There can be two pragmas,
distinguishing ''semantically significant'' overlap from ''performance-
only'' overlap. A class allowing semantically significant overlap is
really for meta-programming only; trying to do anything fancy with it will
ultimately lead to headaches. My guess is that only *monomorphic*
constraints involving such a class should be allowed to instantiate
constraint variables, appear in GADT constructor constraints, or appear in
higher-rank types.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13943#comment:8>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list