
#12860: GeneralizedNewtypeDeriving + MultiParamTypeClasses sends typechecker into an infinite loop -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler (Type | Version: 8.0.1 checker) | Keywords: FunDeps, Resolution: | deriving Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): Well, maybe. The original program and the program in comment:11 have another key difference. The latter uses `UndecidableInstances`, so I suppose it's entirely reasonable that we get a stack overflow error on that one. The former program, on the other hand, does not use `UndecidableInstances`. Really, we ought to reject the former program outright with an error message similar to the one that we get if we leave off `UndecidableInstances` from the latter program: {{{#!hs {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} module Bug where class C a b | a -> b where c :: a -> Int newtype Foo a = Foo a instance C b a => C b (Foo a) where c (Foo a) = c a }}} {{{ Bug.hs:12:10: error: • Illegal instance declaration for ‘C b (Foo a)’ The coverage condition fails in class ‘C’ for functional dependency: ‘a -> b’ Reason: lhs type ‘b’ does not determine rhs type ‘Foo a’ Un-determined variable: a Using UndecidableInstances might help • In the instance declaration for ‘C b (Foo a)’ | 12 | instance C b a => C b (Foo a) where | ^^^^^^^^^^^^^^^^^^^^ }}} If we did this, then I would consider this issue resolved. This coverage condition check is performed in `checkValidInstance`. Curiously, we don't call `checkValidInstance` on derived instances at the comment. There are relevant comments [http://git.haskell.org/ghc.git/blob/b14c03737574895718eed786a60dfdfd42ab49ce... here]: {{{#!hs -- checkValidInstance tyvars theta clas inst_tys -- Not necessary; see Note [Exotic derived instance contexts] ; traceTc "TcDeriv" (ppr deriv_rhs $$ ppr theta) -- Claim: the result instance declaration is guaranteed valid -- Hence no need to call: -- checkValidInstance tyvars theta clas inst_tys }}} As this ticket shows, this isn't quite right. So perhaps we need to carve out the bit that checks the coverage condition and just check that. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12860#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler