Opened 2 years ago

Closed 2 years ago

#14368 closed bug (invalid)

GHC 8.2.1 doesn't inform you when the monomorphism restriction kicks in anymore

Reported by: RyanGlScott Owned by:
Priority: normal Milestone:
Component: Compiler (Type checker) Version: 8.2.1
Keywords: Cc: simonpj
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Poor/confusing error message Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

This program doesn't typecheck due to the monomorphism restriction:

f = (==)

In GHC 8.0.2, the error message was quite helpful in informing you of this fact:

GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Main             ( Bug.hs, interpreted )

Bug.hs:1:1: error:
    • Ambiguous type variable ‘a0’ arising from a use of ‘==’
      prevents the constraint ‘(Eq a0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      These potential instances exist:
        instance Eq Ordering -- Defined in ‘GHC.Classes’
        instance Eq Integer
          -- Defined in ‘integer-gmp-1.0.0.1:GHC.Integer.Type’
        instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Base’
        ...plus 22 others
        ...plus 7 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • When instantiating ‘f’, initially inferred to have
      this overly-general type:
        forall a. Eq a => a -> a -> Bool
      NB: This instantiation can be caused by the monomorphism restriction.

Notice the NB: This instantiation can be caused by the monomorphism restriction part. But in GHC 8.2.1, this advice has mysteriously vanished!

GHCi, version 8.2.1: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Main             ( Bug.hs, interpreted )

Bug.hs:1:5: error:
    • Ambiguous type variable ‘a0’ arising from a use of ‘==’
      prevents the constraint ‘(Eq a0)’ from being solved.
      Relevant bindings include
        f :: a0 -> a0 -> Bool (bound at Bug.hs:1:1)
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      These potential instances exist:
        instance Eq Ordering -- Defined in ‘GHC.Classes’
        instance Eq Integer
          -- Defined in ‘integer-gmp-1.0.1.0:GHC.Integer.Type’
        instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Base’
        ...plus 22 others
        ...plus 9 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the expression: (==)
      In an equation for ‘f’: f = (==)
  |
1 | f = (==)
  |     ^^^^

Change History (5)

comment:1 Changed 2 years ago by RyanGlScott

Cc: simonpj added

This regression occurred in commit 3f5673f34a2f761423027bf46f64f7499708725f (A collection of type-inference refactorings.).

Simon, do you recall why you changed this error message?

comment:2 Changed 2 years ago by simonpj

It was an ad-hoc special case before. This is tricky to report well. For example

f = Just (==)

does not give that hint. And

f = (==)
foo = (f 'c', f True)

gives

    • Couldn't match expected type ‘Char’ with actual type ‘Bool’
    • In the first argument of ‘f’, namely ‘True’

Ironically, we do generate a warning

  Foo.hs:7:1: warning:
      The Monomorphism Restriction applies to the binding for ‘f’
        Consider giving it a type signature

but since it's a warning it is suppressed when there is an error. Maybe errors should not suppress warnings?

comment:3 Changed 2 years ago by RyanGlScott

I'm OK with not being able to report every possible occurrences of the monomorphism restriction. But as you've demonstrated, GHC clearly can detect that the monorphism restriction is kicking in here (in a warning)—can't we just copy that message in the error?

comment:4 Changed 2 years ago by simonpj

can't we just copy that message in the error

But which errors? The two sites are quite separate. E.g. the Char/Bool error is much later.

I'm sure there are improvements to be had here; just not sure exactly what and how.

comment:5 Changed 2 years ago by RyanGlScott

Resolution: invalid
Status: newclosed

Oh, I see what you mean. This program:

f = (==)
foo = (f 'c', f True)

only emits an error about foo, and doesn't separately error for f. Blast.

In that case, I agree that this is probably not worth the effort to implement. I'll close as invalid (but feel free to reopen if you can think of a feasible way to do this.)

Note: See TracTickets for help on using tickets.