Skip to content

Don't suggest `DeriveAnyClass` when instance can't be derived.

Closes #19692 (closed).

If DeriveAnyClass is disabled, and someone attempts to derive an instance, we currently suggest "Perhaps you intended to use DeriveAnyClass". But if the class has any required definitions (i.e. a method without a default, either a regular one or one using DefaultSignatures), that's probably a bad suggestion; it gives warnings about umimplemented methods and runtime errors. So we now disable the suggestion in this case

Two other edge cases: we still suggest it if the user explicitly says deriving anyclass when DeriveAnyClass is disabled, which seems reasonable to me. And we still suggest it if the instance is for a class itself (e.g. instance C Eq), because that's a specially-handled case. I haven't thought about it much but if we want I think I could apply the same change here.

Examples:

class C a where
  c :: a -> Int
data G = G1 deriving C

this used to give the suggestion, and the suggestion would have failed. Now doesn't give the suggestion.

class C a where
  c :: a -> Int
  c _ = 0
data G = G1 deriving C

this used to give the suggestion, and the suggestion would have succeeded. Still gives the suggestion.

class A
deriving instance A

This used to give the suggestion, and the suggestion would have succeeded. Still gives the suggestion. (I'm not 100% sure what's up with this case, it still gave the suggestion in fe80eaf6 and I don't know why.)

class C a
deriving instance C Eq

This used to give the suggestion and still does. The suggestion works.

class C a where
  f :: a Int => Int
deriving instance C Eq

This used to give the suggestion and still does. The suggestion fails.

data A = A Int deriving anyclass Eq

This used to give the suggestion and still does. The suggestion fails, but the user probably did intend to enable DeriveAnyClass anyway.

Merge request reports