Opened 15 months ago

Closed 13 months ago

Last modified 11 months ago

#12220 closed bug (fixed)

TypeApplications and DefaultSignatures - problems deducing type variables.

Reported by: mkloczko Owned by:
Priority: normal Milestone: 8.0.2
Component: Compiler Version: 8.0.1
Keywords: DefaultSignatures, TypeApplications Cc:
Operating System: Linux Architecture: x86_64 (amd64)
Type of failure: None/Unknown Test Case: generics/T12220
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

The following example code throws an error.

The example code:

{-#LANGUAGE TypeApplications#-}
{-#LANGUAGE MultiParamTypeClasses #-}
{-#LANGUAGE AllowAmbiguousTypes #-}
{-#LANGUAGE FlexibleInstances #-}
{-#LANGUAGE ScopedTypeVariables #-}
{-#LANGUAGE DefaultSignatures #-}
module Test1 where

-- | Type a is only used for
-- type application.
class ToUse a where
    toUse :: Int -> Int

-- | The type used for
-- type application
data Default


-- | The instance using Default as type application.
-- To call use:
-- > toUse @Default 
instance ToUse Default where
    toUse a = 3*a

-- | Typeclass whose methods work
-- only with type application.
class (ToUse a) => Uses a b where
    uses :: b -> [b]
    -- | Default Signature, which generates the problem.
    -- It is the same as the normal one
    -- Comment it to 'fix' the bug.
    default uses :: b -> [b] 
    uses v = [v] 

-- | Normal instances, nothing special
instance Uses Default Int where
    uses v = take (toUse @Default 3) $ repeat v
-- | Another normal one
instance Uses Default String where
    uses v = take (toUse @Default 2) $ repeat v

-- | This one works nicely
instance (ToUse t, Uses t a, Uses t b) => Uses t (a,b) where
    uses (vl,vr) = zip ls rs
        where ls = uses @t vl
              rs = uses @t vr

-- | But this one doesn't.
-- Unless you comment the default signature.
instance (ToUse t, Uses t a, Uses t b, Uses t c) => Uses t (a,b,c)

The error:

    • Could not deduce (Uses a0 a)
        arising from a use of ‘Test1.$dmuses’
      from the context: (ToUse t, Uses t a, Uses t b, Uses t c)
        bound by the instance declaration at Test1.hs:47:10-66
      The type variable ‘a0’ is ambiguous
      Relevant bindings include
        uses :: (a, b, c) -> [(a, b, c)] (bound at Test1.hs:47:10)
    • In the expression: Test1.$dmuses
      In an equation for ‘uses’: uses = Test1.$dmuses
      In the instance declaration for ‘Uses t (a, b, c)’

Commenting out the default signature fixes the problem.

Change History (8)

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

In d2958bd0/ghc:

Improve typechecking of instance defaults

In an instance declaration when you don't specify the code for a
method, GHC fills in from the default binding in the class.
The type of the default method can legitmiately be ambiguous ---
see Note [Default methods in instances] in TcInstDcls --- so
typechecking it can be tricky.

Trac #12220 showed that although we were dealing with that ambiguity
for /vanilla/ default methods, we were not doing so for /generic/
default methods.  Moreover we were dealing with it clumsily, by
generating post-typechecked code.

This patch fixes the bug AND deletes code!  We now use the same code
path for both vanilla and generic default methods; and generate
/pre-typechecked/ code in both cases.  The key trick is that we can use
Visible Type Application to deal with the ambiguity, which wasn't
possible before.  Hooray.

There is a small hit to performance in compiler/perf/T1969 which
consists of nothing BUT instance declarations with several default
methods to fill, which we now have to typecheck. The actual hit is
from 724 -> 756 or 4% in that extreme example.  Real world programs
have vastly fewer instance decls.

comment:2 Changed 15 months ago by simonpj

Milestone: 8.0.2
Status: newmerge
Test Case: generics/T12220

Thanks for reporting this. Now fixed.

I think that the fix is non-invasive and so could merge to 8.0.2

Simon

comment:3 Changed 14 months ago by RyanGlScott

This isn't quite non-invasive, since it's causing some packages to fail to compile on GHC HEAD that were compiling on GHC 8.0.1. See #12466.

comment:4 Changed 13 months ago by simonpj

Does anyone care if this doesn't make it into 8.0.2? If it goes in, we'll have to fix #12466 too.

Last edited 13 months ago by bgamari (previous) (diff)

comment:5 Changed 13 months ago by bgamari

Milestone: 8.0.28.2.1
Resolution: fixed
Status: mergeclosed

Given that no one feels terribly strongly about this we'll be bumping it off to 8.2.1.

comment:6 Changed 12 months ago by bgamari

Milestone: 8.2.18.0.2

It ended up being not so bad to merge afterall. Merged to ghc-8.0 as 54b887b5abf6ee723c6ac6aaa2d2f4c14cf74060.

comment:7 Changed 11 months ago by RyanGlScott

This also introduced another typechecker regression in GHC 8.0.2: #12784.

comment:8 Changed 11 months ago by Ryan Scott <ryan.gl.scott@…>

In 2e8463b2/ghc:

Update 8.0.2 release notes for #12784

Summary:
The fix for #12220 exposed some ill-typed programs which passed the typechecker
in GHC 8.0.1 but now fail to typecheck in GHC 8.0.2. It's a bit difficult to
characterize what exactly triggers this bug, but we at least have a minimal
example and a simple fix to illustrate the problem and solution, so let's
add that the the 8.0.2 release notes to advertise this change.

Resolves #12784.

Reviewers: rwbarton, austin, bgamari

Reviewed By: bgamari

Subscribers: thomie

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

GHC Trac Issues: #12784
Note: See TracTickets for help on using tickets.