#13915 closed bug (fixed)

GHC 8.2 regression: "Can't find interface-file declaration" for promoted data family instance

Reported by: RyanGlScott Owned by:
Priority: high Milestone: 8.2.1
Component: Compiler Version: 8.2.1-rc2
Keywords: TypeInType, TypeFamilies, Typeable Cc: bgamari
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s): Phab:D3759
Wiki Page:

Description

Due to #12088, you can't define a data family instance and promote it in the same module. One could, up until GHC 8.2, work around this using (somewhat obscure) wisdom: define the data family instance in a separate module from where it's promoted. For example, Bug typechecks in GHC 8.0.1 and 8.0.2:

{-# LANGUAGE TypeFamilies #-}
module Foo where

data family T a
data instance T Int = MkT
{-# LANGUAGE TypeInType #-}
module Bug where

import Foo

data Proxy (a :: k)
data S = MkS (Proxy 'MkT)

However, this stopped typechecking in GHC 8.2:

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

Bug.hs:1:1: error:
    Can't find interface-file declaration for variable Foo.$tc'MkT
      Probable cause: bug in .hi-boot file, or inconsistent .hi file
      Use -ddump-if-trace to get an idea of which file caused the error
  |
1 | {-# LANGUAGE TypeInType #-}
  | ^

Change History (6)

comment:1 Changed 13 months ago by RyanGlScott

Cc: bgamari added
Keywords: Typeable added

This regression was introduced in 8fa4bf9ab3f4ea4b208f4a43cc90857987e6d497 (Type-indexed Typeable).

comment:2 Changed 13 months ago by RyanGlScott

Interestingly, GHC isn't actually so great about using the Typeable instance for MkT, regardless of whether it's GHC 8.0 or 8.2. If you tweak Bug slightly:

{-# LANGUAGE TypeInType #-}
module Bug where

import Data.Typeable (Proxy(..), typeRep)
import Foo

main :: IO ()
main = print $ typeRep (Proxy :: Proxy MkT)

Then it fails on both GHC 8.0 and 8.2 with a similar panic:

GHC 8.0:

$ /opt/ghc/8.0.2/bin/runghc Bug.hs
GHC error in desugarer lookup in Bug:
  Can't find interface-file declaration for variable $tc'MkT
    Probable cause: bug in .hi-boot file, or inconsistent .hi file
    Use -ddump-if-trace to get an idea of which file caused the error
ghc: panic! (the 'impossible' happened)
  (GHC version 8.0.2 for x86_64-unknown-linux):
        initDs IOEnv failure

GHC 8.2:

$ /opt/ghc/8.2.1/bin/runghc Bug.hs
GHC error in desugarer lookup in Bug:
  Can't find interface-file declaration for variable $tc'MkT
    Probable cause: bug in .hi-boot file, or inconsistent .hi file
    Use -ddump-if-trace to get an idea of which file caused the error
ghc: panic! (the 'impossible' happened)
  (GHC version 8.2.0.20170623 for x86_64-unknown-linux):
        initDs

So to be honest, I'm not sure how the original program typechecks on GHC 8.0, given the fragility of MkT's Typeable instance.

comment:3 Changed 13 months ago by RyanGlScott

If you try using MkT's Typeable instance in the same module it's defined in, it gets even crazier. This program:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
module Foo where

import Data.Typeable (Proxy(..), typeRep)

data family T a
data instance T Int = MkT

main :: IO ()
main = print $ typeRep (Proxy :: Proxy MkT)

Gives the same panic on GHC 8.0.2 and 8.2.1:

$ /opt/ghc/8.2.1/bin/runghc Foo.hs
ghc: panic! (the 'impossible' happened)
  (GHC version 8.2.0.20170623 for x86_64-unknown-linux):
        tcIfaceGlobal (local): not found
  You are in a maze of twisty little passages, all alike.
  While forcing the thunk for TyThing $tc'MkT
  which was lazily initialized by mkDsEnvs,
  I tried to tie the knot, but I couldn't find $tc'MkT
  in the current type environment.
  If you are developing GHC, please read Note [Tying the knot]
  and Note [Type-checking inside the knot].
  Consider rebuilding GHC with profiling for a better stack trace.
  Contents of current type environment:
    [a1Vr :-> Identifier ‘$dShow_a1Vr’,
     a218 :-> Identifier ‘$dTypeable_a218’,
     r1qQ :-> Type constructor ‘T’, r1rU :-> Data constructor ‘MkT’,
     r1rV :-> Identifier ‘main’, r1uL :-> Identifier ‘$tcT’,
     r1v7 :-> Type constructor ‘R:TInt’,
     r1vc :-> Coercion axiom ‘D:R:TInt0’, r1vg :-> Identifier ‘$WMkT’,
     r1vh :-> Identifier ‘MkT’, r21e :-> Identifier ‘$trModule’]
  Call stack:
      CallStack (from HasCallStack):
        prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable
        callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable
        pprPanic, called at compiler/iface/TcIface.hs:1689:23 in ghc:TcIface

comment:4 Changed 12 months ago by bgamari

Differential Rev(s): Phab:D3759
Status: newpatch

comment:5 Changed 12 months ago by Ben Gamari <ben@…>

In cc839c5/ghc:

Typeable: Ensure that promoted data family instance tycons get bindings

This fixes #13915, where the promoted tycons belonging to data family
instances wouldn't get Typeable bindings, resulting in missing
declarations.

Test Plan: Validate with included testcases

Reviewers: austin, simonpj

Reviewed By: simonpj

Subscribers: simonpj, RyanGlScott, rwbarton, thomie

GHC Trac Issues: #13915

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

comment:6 Changed 12 months ago by bgamari

Resolution: fixed
Status: patchclosed
Note: See TracTickets for help on using tickets.