Opened 5 years ago

Closed 5 years ago

Last modified 4 years ago

#9739 closed bug (fixed)

GHC 7.8 chokes on recursive classes

Reported by: bitonic Owned by:
Priority: normal Milestone: 7.10.1
Component: Compiler (Type checker) Version: 7.9
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Compile-time crash Test Case: typecheck/should_fail/T9739
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Type checking this makes GHC 7.8.3 loop:

{-# LANGUAGE MultiParamTypeClasses #-}
module Foo where

class Class3 a => Class1 a where

class Class2 t a where
  class2 :: (Class3 t) => a -> m

class (Class1 t, Class2 t t) => Class3 t where

Does not happen in 7.6.3.

I think it's something to do with the Class3 constraint appearing in class2.

Change History (13)

comment:1 Changed 5 years ago by ezyang

Version: 7.8.37.9

Confirmed to loop on GHC HEAD 75979f3661ff16ec44528a23005ac1be2b9683fe

comment:2 Changed 5 years ago by dfeuer

Type of failure: None/UnknownCompile-time crash

comment:3 Changed 5 years ago by bitonic

Actually, you don't need MultiParamTypeClasses:

module Foo where

class Class3 a => Class1 a where

class Class2 a where
  class2 :: (Class3 a) => b

class (Class1 a, Class2 a) => Class3 a where

comment:4 Changed 5 years ago by bitonic

Aaaand with only two classes:

module Foo where

class Class2 a => Class1 a where
  class3 :: (Class2 a) => b

class (Class1 a) => Class2 a where
Last edited 5 years ago by bitonic (previous) (diff)

comment:5 Changed 5 years ago by dfeuer

Milestone: 7.10.1

comment:6 in reply to:  4 Changed 5 years ago by dfeuer

Replying to bitonic:

Aaaand with only two classes:

module Foo where

class Class2 a => Class1 a where
  class3 :: (Class2 a) => b

class (Class1 a) => Class2 a where

The two-class version doesn't loop in 7.9; it just gets an error as it should.

comment:7 Changed 5 years ago by dfeuer

This is interesting: the definition of Class1 is actually illegal in Haskell 98, because class3 constrains the type variable a. This sort of thing is only supposed to be allowed with -XConstrainedClassMethods. In fact, if you enable that flag, suddenly the compiler realizes there's a loop! So it looks likely that someone made the flag enable the extra loop checking required by such methods, but accidentally failed to make it control whether such things are allowed at all!

comment:8 Changed 5 years ago by simonpj

Test Case: typecheck/should_fail/T9739

The 3-class version still loops in HEAD. Reason is this:

  • TcTyClsDcls.checkValidClass is called on each class in turn.
  • It checks for superclass cycles, and then checks for ambiguity of the method types
  • The ambiguity check loops if there is a superclass cycle
  • The superclass cycle check was first, and aborted checkValidClass if it failed.
  • BUT we failed to notice that it would loop if there was a superclass cycle in another class in the group; and after each class we dust ourselves off and the next one, to get as many validity errors as possible.

Solution was simple: make the ambiguity check happen only if there have been no errors so far.

Patch coming

Simon

comment:9 Changed 5 years ago by dfeuer

I don't understand why such a member signature was even allowed without -XConstrainedClassMethods. That's essentially a syntax error! Someone also noticed that Foldable members currently have a redundant (but harmless) Foldable constraint that I think shouldn't have been allowed (I'll take care of those).

comment:10 Changed 5 years ago by Simon Peyton Jones <simonpj@…>

comment:11 Changed 5 years ago by Simon Peyton Jones <simonpj@…>

In 7c79633688238086ad60e1d23e0a424bb4eb325f/ghc:

Fix the superclass-cycle detection code (Trac #9739)

We were falling into an infinite loop when doing the ambiguity
check on a class method, even though we had previously detected
a superclass cycle.  There was code to deal with this, but it
wasn't right.

comment:12 Changed 5 years ago by simonpj

Resolution: fixed
Status: newclosed

Thanks for reporting this!

Simon

comment:13 Changed 4 years ago by Matthew Pickering <matthewtpickering@…>

In 44640af7/ghc:

Allow as-patterns in pattern synonym declarations.

We can allow them if they contain no free variables. This patch just allows
them in one direction and not to be used as builders as the original ticket
suggests.

Test Plan: ./validate

Reviewers: austin, bgamari

Reviewed By: bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1666

GHC Trac Issues:  #9739

Conflicts:
	testsuite/tests/patsyn/should_fail/all.T
Note: See TracTickets for help on using tickets.