
#14396: Hs-boot woes during family instance consistency checks -------------------------------------+------------------------------------- Reporter: simonpj | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.2.1 Resolution: | Keywords: hs-boot Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): Gah! This is ridiculously complicated. Surely there must be a better way. In thinking about this I realised: * A very similar danger happens for ordinary data type decls: {{{ M.hs-boot data S M1.hs import {-# SOURCE #-} M data D (a::S) = ... M.hs import M1 data T a = MkT (D a) data S = A | B }}} The danger is that we'll kind-check the decl for T, suck in the interface decl for T1, and then find that S is not yet in the type envt. But we fixed that (conservatively) in `RnSource.addBootDeps`; `Note [Extra dependencies from .hs-boot files]` in `RnSource` * Even within one module we have an open ticket about when to typecheck 'type instance' decls: #12088. It has a very similar flavour to the Edward's solution here. * Edward's solution defers the type family consistency check, but the interface-file instance is there in the family-instance environment all the time. e.g. {{{ M.hs-boot data SyntaxExpr M1.hs import {-# SOURCE #-} M instance F Int = SyntaxExpr M.hs import M1 data T = ...(F Int)... data SyntaxExpr = SE }}} I'm worried that an "earlier" decl, for T, might make use of that instance, which would again prematurely look for SyntaxExpr in the M's type environment, before it has been looked at. Oh -- but maybe it's (just) ok: the fix in addBootDeps will ensure that SyntaxExpr is typechecked before T. But it's terribly delicate. I did have one simplifying idea. Thought experiment: * When typechecking M, begin by loading M.hi-boot (which we already do) /and/ extend the type environment. So we'll add `SyntaxExpr` and `W`, in the above examples, to the type envt. * Do none of this addBootDeps stuff, nor deferring family instances. If we need `W` or `SyntaxExpr` before they've been encountered, we'll use the boot-versions. * So when compiling M we'll have places where we only have the boot TyCon instead of the real TyCon. Maybe that does not matter? * When we are all done, we'll spit out a M.hi file. * In --make mode we'll now re-typecheck the loop from the .hi files, building all the knots just as expected. This is much much simpler. Would it work? Worth a a try? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14396#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler