[GHC] #2182: ghc sessions (--make, --interactive, ghc api) erroneously retain instances

GHC ghc-devs at haskell.org
Tue Nov 11 02:44:26 UTC 2014


#2182: ghc sessions (--make, --interactive, ghc api) erroneously retain instances
-------------------------------------+-------------------------------------
              Reporter:  claus       |            Owner:
                  Type:  bug         |           Status:  new
              Priority:  normal      |        Milestone:  7.10.1
             Component:  Compiler    |          Version:  6.9
  (Type checker)                     |         Keywords:
            Resolution:              |     Architecture:  Unknown/Multiple
      Operating System:              |       Difficulty:  Unknown
  Unknown/Multiple                   |       Blocked By:
       Type of failure:  GHC         |  Related Tickets:
  accepts invalid program            |
             Test Case:              |
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------
Changes (by ezyang):

 * priority:  low => normal
 * failure:  None/Unknown => GHC accepts invalid program
 * component:  GHCi => Compiler (Type checker)
 * milestone:  ⊥ => 7.10.1


Old description:

> {{{
> $ compiler/stage2/ghc-inplace --interactive
> GHCi, version 6.9.20080317: http://www.haskell.org/ghc/  :? for help
> Loading package base ... linking ... done.
> Prelude> :i Functor
> class Functor f where fmap :: (a -> b) -> f a -> f b
>         -- Defined in GHC.Base
> instance Functor Maybe -- Defined in Data.Maybe
> instance Functor [] -- Defined in GHC.Base
> instance Functor IO -- Defined in GHC.IOBase
> Prelude> fmap not (True,True)
>
> <interactive>:1:0:
>     No instance for (Functor ((,) Bool))
>       arising from a use of `fmap' at <interactive>:1:0-19
>     Possible fix: add an instance declaration for (Functor ((,) Bool))
>     In the expression: fmap not (True, True)
>     In the definition of `it': it = fmap not (True, True)
> Prelude> :m +Data.Array
> Prelude Data.Array> :i Functor
> class Functor f where fmap :: (a -> b) -> f a -> f b
>         -- Defined in GHC.Base
> instance (Ix i) => Functor (Array i) -- Defined in GHC.Arr
> instance Functor ((->) r) -- Defined in Control.Monad.Instances
> instance Functor ((,) a) -- Defined in Control.Monad.Instances
> instance Functor (Either a) -- Defined in Control.Monad.Instances
> instance Functor Maybe -- Defined in Data.Maybe
> instance Functor [] -- Defined in GHC.Base
> instance Functor IO -- Defined in GHC.IOBase
> Prelude Data.Array> fmap not (True,True)
> (True,False)
> Prelude Data.Array> :m -Data.Array
> Prelude> :i Functor
> class Functor f where fmap :: (a -> b) -> f a -> f b
>         -- Defined in GHC.Base
> instance Functor ((->) r) -- Defined in Control.Monad.Instances
> instance Functor ((,) a) -- Defined in Control.Monad.Instances
> instance Functor (Either a) -- Defined in Control.Monad.Instances
> instance Functor Maybe -- Defined in Data.Maybe
> instance Functor [] -- Defined in GHC.Base
> instance Functor IO -- Defined in GHC.IOBase
> Prelude> fmap not (True,True)
> (True,False)
> }}}

New description:

 The EPS (external-package state) is only ever increased, never decreased
 between compilation of different modules in a single batch compilation or
 GHCi session.

 Example 1 (GHCi):

 {{{
 ezyang at sabre:~/Dev/labs/ezyangest$ ghci
 GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
 Loading package ghc-prim ... linking ... done.
 Loading package integer-gmp ... linking ... done.
 Loading package base ... linking ... done.
 Prelude> (\x -> x)

 <interactive>:2:1:
     No instance for (Show (t0 -> t0)) arising from a use of `print'
     Possible fix: add an instance declaration for (Show (t0 -> t0))
     In a stmt of an interactive GHCi command: print it
 Prelude> :m +Text.Show.Functions
 Prelude Text.Show.Functions> (\x -> x)
 <function>
 Prelude Text.Show.Functions> :m -Text.Show.Functions
 Prelude> :r
 Ok, modules loaded: none.
 Prelude> (\x -> x)
 <function>
 }}}

 Example 2 (make):

 {{{
 ezyang at sabre:~/Dev/labs/ezyangest$ cat A.hs
 module A where
 import Text.Show.Functions
 ezyang at sabre:~/Dev/labs/ezyangest$ cat B.hs
 module B where
 y = show (\x -> x)
 ezyang at sabre:~/Dev/labs/ezyangest$ ghc --make B.hs A.hs
 [1 of 2] Compiling A                ( A.hs, A.o )
 [2 of 2] Compiling B                ( B.hs, B.o )
 ezyang at sabre:~/Dev/labs/ezyangest$ ghc --make A.hs B.hs -fforce-recomp
 [1 of 2] Compiling B                ( B.hs, B.o )

 B.hs:2:5:
     No instance for (Show (t0 -> t0)) arising from a use of `show'
     Possible fix: add an instance declaration for (Show (t0 -> t0))
     In the expression: show (\ x -> x)
     In an equation for `y': y = show (\ x -> x)

 }}}

--

Comment:

 I updated the bug description with some modernized, simpler test-cases.

 simonpj and I have chatted about this and we have a new, improved plan of
 attack to solve the problem:

 1. We'll maintain a set of loaded interface files in the type-checking
 environment. When an interface file is loaded, we add it to this set.
 2. When a type class instance lookup is performed, IF the instance is an
 orphan, we'll also check if the interface file which defined the instance
 is in the loaded set. If it is not, we pretend it doesn't exist.

 I have most of a patch to solve this but I have to shake out a bug where
 GHCi is not preserving the set of loaded interfaces.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/2182#comment:8>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list