Opened 7 years ago

Closed 7 years ago

#5820 closed bug (fixed)

defining instance in GHCi leads to duplicated instances

Reported by: guest Owned by:
Priority: high Milestone: 7.6.1
Component: GHCi Version: 7.4.1-rc1
Keywords: Cc: claudiusmaximus@…, castor@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: ghci/scripts/T5820
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Bizarre:

claude@jazzyjeff:~$ cat Foo.hs 
module Foo where
data Foo = Foo
instance Num Foo where
claude@jazzyjeff:~$ ~/opt/ghc-7.4/bin/ghci -w Foo.hs 
GHCi, version 7.4.0.20120119: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Foo              ( Foo.hs, interpreted )
Ok, modules loaded: Foo.
*Foo> :info Foo
data Foo = Foo  -- Defined at Foo.hs:2:6
instance Num Foo -- Defined at Foo.hs:3:10
*Foo> instance Fractional Foo where
*Foo> :info Foo
data Foo = Foo  -- Defined at Foo.hs:2:6
instance Fractional Foo -- Defined at <interactive>:3:10
instance Num Foo -- Defined at Foo.hs:3:10
instance Num Foo -- Defined at Foo.hs:3:10

I get an extra Num instance (where from? same source location??), which causes overlapping problems.

Change History (8)

comment:1 Changed 7 years ago by igloo

difficulty: Unknown
Milestone: 7.4.2
Priority: normalhigh

comment:2 Changed 7 years ago by castor

Cc: castor@… added

This problem also occurs using non-user-defined types. Take a look at the snippet below:

fernando@Castor ~/src $ cat Foo.hs
instance Num Bool where
fernando@Castor ~/src $ ghc/inplace/bin/ghc-stage2 --interactive -w Foo.hs
GHCi, version 7.5.20120130: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( Foo.hs, interpreted )
Ok, modules loaded: Main.
*Main> :info Bool
data Bool = False | True -- Defined in `GHC.Types'
instance Num Bool -- Defined at Foo.hs:1:10[[BR]] instance Bounded Bool -- Defined in `GHC.Enum'
instance Enum Bool -- Defined in `GHC.Enum'
instance Eq Bool -- Defined in `GHC.Classes'
instance Ord Bool -- Defined in `GHC.Classes'
instance Read Bool -- Defined in `GHC.Read'
instance Show Bool -- Defined in `GHC.Show'
*Main> instance Fractional Bool where
*Main> :info Bool
data Bool = False | True -- Defined in `GHC.Types'
instance Fractional Bool -- Defined at <interactive>:3:10
instance Num Bool -- Defined at Foo.hs:1:10[[BR]] instance Num Bool -- Defined at Foo.hs:1:10[[BR]] instance Bounded Bool -- Defined in `GHC.Enum'
instance Enum Bool -- Defined in `GHC.Enum'
instance Eq Bool -- Defined in `GHC.Classes'
instance Ord Bool -- Defined in `GHC.Classes'
instance Read Bool -- Defined in `GHC.Read'
instance Show Bool -- Defined in `GHC.Show'

This was the simplest program with which I was able to reproduce the problem.

comment:3 Changed 7 years ago by simonpj@…

commit 15ec88354665844635f6e16ba10902d7cc03f7ba

Author: Simon Peyton Jones <simonpj@microsoft.com>
Date:   Fri Feb 10 15:33:53 2012 +0000

    Complete fix of #5820
    
    There are two related changes in here
    
    a) Fix TcRnDriver.setInteractiveContext so that it initialises
       tcg_insts and tcg_fam_insts, as well as the corresponding
       tcg_inst_env and tcg_fam_inst_env fields.  Vital!
    
    b) Fix FamInst.tcExtendLocalFamInstEnv for the GHCi case.
       It had a special HACK to allow family instances to be overridden
       in GHCi.  Fair enough, but
         * It was only affecting the tcg_fam_inst_env, not tcg_fam_insts
         * It overrode home-package instances as well as ones entered
           at the GHCi prompt, which probably wasn't intended.
    
       I fixed both of these, and also narrowed the scope of what it does
       to override only *identical* instances, rather than any ones that
       conflict.  If people yelp about this we can return to the question,
       but for now it narrows the range of the HACK

 compiler/typecheck/FamInst.lhs    |   59 +++++++++++++++++++++---------------
 compiler/typecheck/TcRnDriver.lhs |    4 ++-
 compiler/types/FamInstEnv.lhs     |   58 ++++++++++++++----------------------
 3 files changed, 59 insertions(+), 62 deletions(-)

comment:4 Changed 7 years ago by simonpj@…

commit cc047084f6842f10a0767e976bde6c93582b53e7

Author: Simon Peyton Jones <simonpj@microsoft.com>
Date:   Fri Feb 10 10:46:16 2012 +0000

    Put only local instances in the interactive context (fixes Trac #5820)
    
    In HscMain.hscDeclsWithLocaion, we were grabbing class instances from
    the tcg_inst_env field of the TcGblEnv. But that's wrong: that field
    contains all the *home-package* instances.  Instead we need the
    tct_insts field, which has just the instances from the module being
    compiled.

 compiler/main/HscMain.hs |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

comment:5 Changed 7 years ago by simonpj

Resolution: fixed
Status: newclosed
Test Case: ghci/scripts/T5820

Yes, a real bug all right. The above two patches fix it, I believe.

Thanks!

Simon

comment:6 Changed 7 years ago by simonpj

Status: closedmerge

If we do 7.4.3, this should probably merge.

comment:7 Changed 7 years ago by simonpj

This patch does not merge cleanly on the 7.4 branch, so I propose that we do not fix it on the branch. It only affects instances declared at the GHCi prompt, and maybe we can manage without them working properly.

If this is going to ruin your life, yell.

Simon

comment:8 Changed 7 years ago by pcapriotti

Milestone: 7.4.27.6.1
Status: mergeclosed
Note: See TracTickets for help on using tickets.