#9033 closed bug (fixed)

Type error suppresses defaulting, causes spurious errors

Reported by: jun0 Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.8.2
Keywords: defaulting, ambiguous Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: typecheck/should_fail/T9033
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

I have a strong feeling this must have been reported already but I can't find a ticket for it, so here goes.

If a source file contains a type error, like

bad :: Bool
bad = ()

then GHC seems to turn off defaulting for ambiguous types in the remainder of the file. So if the same file contains for instance

square :: Integral i => i -> i
square x = x^2

then GHC reports another type error at the 2:

test.hs:4:7:
    Couldn't match expected type ‘Bool’ with actual type ‘()’
    In the expression: ()
    In an equation for ‘bad’: bad = ()

test.hs:7:13:
    Could not deduce (Integral b0) arising from a use of ‘^’
    from the context (Integral i)
      bound by the type signature for square :: Integral i => i -> i
      at test.hs:6:11-30
    The type variable ‘b0’ is ambiguous
    Note: there are several potential instances:
      instance Integral Int -- Defined in ‘GHC.Real’
      instance Integral Integer -- Defined in ‘GHC.Real’
      instance Integral GHC.Types.Word -- Defined in ‘GHC.Real’
    In the expression: x ^ 2
    In an equation for ‘square’: square x = x ^ 2

test.hs:7:14:
    Could not deduce (Num b0) arising from the literal ‘2’
    from the context (Integral i)
      bound by the type signature for square :: Integral i => i -> i
      at test.hs:6:11-30
    The type variable ‘b0’ is ambiguous
    Note: there are several potential instances:
      instance Num Double -- Defined in ‘GHC.Float’
      instance Num Float -- Defined in ‘GHC.Float’
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      ...plus three others
    In the second argument of ‘(^)’, namely ‘2’
    In the expression: x ^ 2
    In an equation for ‘square’: square x = x ^ 2

The first error is a legitimate type mismatch and it's all fine, but the other two should be resolved with default instance selection -- and it is, once the type error in bad is fixed. For example, rewriting bad to

bad :: ()
bad = ()

makes *all* errors go away, including the ones on square.

Default instance selection seems to be turned back on when square is made monomorphic, like

squareMono :: Int -> Int
squareMono x = x^2

Note that the type of x is being fixed, not the 2 that GHC complains about in square. The effect of this is that in a file with a large number of ^2, ^3, and such, the error message pointing to the real type error is drowned in all the "could not deduce" messages.

Attachments (1)

test.hs (132 bytes) - added by jun0 13 months ago.

Download all attachments as: .zip

Change History (3)

Changed 13 months ago by jun0

comment:1 Changed 13 months ago by Simon Peyton Jones <simonpj@…>

In ba2e20149e2addaccf5ce3122d3a6e93da696a0a/ghc:

Do type-class defaulting even if there are insoluble constraints

The argument in Trac #9033 is very compelling: we should not report 20
errors, fix one, and have the other 19 disappear.  They were spurious
in the first place.

The fix was easy; do type-class defaulting uncondionally, rather than
only if there are no insoluble constraints.

See Note [When to do type-class defaulting] in TcSimplify.

Error messages generally improve, especially tc211 which actually
had an example of precisely this phenomenon.

comment:2 Changed 13 months ago by simonpj

  • Resolution set to fixed
  • Status changed from new to closed
  • Test Case set to typecheck/should_fail/T9033

Good point, thank you!

Simon

Note: See TracTickets for help on using tickets.