[project @ 2002-01-31 17:48:26 by simonpj]
authorsimonpj <unknown>
Thu, 31 Jan 2002 17:48:27 +0000 (17:48 +0000)
committersimonpj <unknown>
Thu, 31 Jan 2002 17:48:27 +0000 (17:48 +0000)
Wibbles to yesterdays changes

ghc/compiler/typecheck/TcInstDcls.lhs
ghc/compiler/typecheck/TcModule.lhs
ghc/compiler/typecheck/TcSimplify.lhs

index c4023c4..21ed1d5 100644 (file)
@@ -5,7 +5,7 @@
 
 \begin{code}
 module TcInstDcls ( tcInstDecls1, tcIfaceInstDecls1, addInstDFuns, 
-                   tcInstDecls2, tcAddDeclCtxt ) where
+                   tcInstDecls2, initInstEnv, tcAddDeclCtxt ) where
 
 #include "HsVersions.h"
 
@@ -44,7 +44,8 @@ import PprType                ( pprClassPred )
 import TcMonoType      ( tcHsTyVars, kcHsSigType, tcHsType, tcHsSigType )
 import TcUnify         ( checkSigTyVars )
 import TcSimplify      ( tcSimplifyCheck )
-import HscTypes                ( HomeSymbolTable, DFunId, PersistentCompilerState(..),
+import HscTypes                ( HomeSymbolTable, DFunId, 
+                         PersistentCompilerState(..), PersistentRenamerState,
                          ModDetails(..), PackageInstEnv
                        )
 import Subst           ( substTy, substTheta )
@@ -160,9 +161,8 @@ Gather up the instance declarations from their various sources
 
 \begin{code}
 tcInstDecls1   -- Deal with source-code instance decls
-   :: PersistentCompilerState  
-   -> HomeSymbolTable          -- Contains instances
-   -> TcEnv                    -- Contains IdInfo for dfun ids
+   :: PersistentRenamerState   
+   -> InstEnv                  -- Imported instance envt
    -> (Name -> Maybe Fixity)   -- for deriving Show and Read
    -> Module                   -- Module for deriving
    -> [RenamedTyClDecl]                -- For deriving stuff
@@ -172,63 +172,52 @@ tcInstDecls1      -- Deal with source-code instance decls
                                -- for this module
           RenamedHsBinds)      -- derived instances
 
-tcInstDecls1 pcs hst unf_env get_fixity 
-            this_mod tycl_decls inst_decls
-  = let
-       pkg_inst_env = pcs_insts pcs
-       prs          = pcs_PRS   pcs
-       clas_decls = filter isClassDecl tycl_decls
-    in
+tcInstDecls1 prs inst_env get_fixity this_mod 
+            tycl_decls inst_decls
+-- The incoming inst_env includes all the imported instances already
+  = checkNoErrsTc $
+       -- Stop if addInstInfos etc discovers any errors
+       -- (they recover, so that we get more than one error each round)
        -- (1) Do the ordinary instance declarations
     mapNF_Tc tcLocalInstDecl1 inst_decls       `thenNF_Tc` \ local_inst_infos ->
 
+    let
+       local_inst_info = catMaybes local_inst_infos
+       clas_decls      = filter isClassDecl tycl_decls
+    in
        -- (2) Instances from generic class declarations
     getGenericInstances clas_decls             `thenTc` \ generic_inst_info -> 
 
        -- Next, construct the instance environment so far, consisting of
-       --      a) cached non-home-package InstEnv (gotten from pcs) inst_env0
-       --      b) imported instance decls (not in the home package) inst_env1
-       --      c) other modules in this package (gotten from hst)   inst_env2
-       --      d) imported instance decls (from this module)        inst_env3
-       --      e) local instance decls                              inst_env4
-       --      f) generic instances                                 inst_env5
-       -- The result of (b) replaces the cached InstEnv in the PCS
-       --
-       -- Note that iface_dfuns may contain not only insts that we
-       -- demand-loaded from interface files, but also instances from
-       -- the current module in the case where we are loading this
-       -- module's interface file in GHCi, so we partition the
-       -- iface_dfuns into non-local and local instances so that we
-       -- don't end up with home package instances in the PCS.
-       --
-       -- There can't be any instance declarations from the home
-       -- package other than from the current module (with the
-       -- compilation manager) because they are loaded explicitly by
-       -- the compilation manager.
-    let
-       local_inst_info = catMaybes local_inst_infos
-       hst_dfuns = foldModuleEnv ((++) . md_insts) [] hst
-    in 
-
---    pprTrace "tcInstDecls" (vcat [ppr imported_dfuns, ppr hst_dfuns]) $
-
-    addInstDFuns pkg_inst_env hst_dfuns                `thenNF_Tc` \ inst_env2 ->
-    addInstInfos inst_env2 local_inst_info     `thenNF_Tc` \ inst_env3 ->
-    addInstInfos inst_env3 generic_inst_info   `thenNF_Tc` \ inst_env4 ->
+       --      a) imported instance decls (from this module)        inst_env1
+       --      b) local instance decls                              inst_env2
+       --      c) generic instances                                 final_inst_env
+    addInstInfos inst_env local_inst_info      `thenNF_Tc` \ inst_env1 ->
+    addInstInfos inst_env1 generic_inst_info   `thenNF_Tc` \ inst_env2 ->
 
        -- (3) Compute instances from "deriving" clauses; 
        --     note that we only do derivings for things in this module; 
        --     we ignore deriving decls from interfaces!
        -- This stuff computes a context for the derived instance decl, so it
        -- needs to know about all the instances possible; hence inst_env4
-    tcDeriving prs this_mod inst_env4 
+    tcDeriving prs this_mod inst_env2 
               get_fixity tycl_decls            `thenTc` \ (deriv_inst_info, deriv_binds) ->
-    addInstInfos inst_env4 deriv_inst_info     `thenNF_Tc` \ final_inst_env ->
+    addInstInfos inst_env2 deriv_inst_info     `thenNF_Tc` \ final_inst_env ->
 
     returnTc (final_inst_env, 
              generic_inst_info ++ deriv_inst_info ++ local_inst_info,
              deriv_binds)
 
+initInstEnv :: PersistentCompilerState -> HomeSymbolTable -> NF_TcM InstEnv
+-- Initialise the instance environment from the 
+-- persistent compiler state and the home symbol table
+initInstEnv pcs hst
+  = let
+       pkg_inst_env = pcs_insts pcs
+       hst_dfuns    = foldModuleEnv ((++) . md_insts) [] hst
+    in
+    addInstDFuns pkg_inst_env hst_dfuns
+
 addInstInfos :: InstEnv -> [InstInfo] -> NF_TcM InstEnv
 addInstInfos inst_env infos = addInstDFuns inst_env (map iDFunId infos)
 
index 5bb4062..50ff6f7 100644 (file)
@@ -52,7 +52,7 @@ import TcEnv          ( TcEnv, RecTcEnv, InstInfo(iDFunId), tcExtendGlobalValEnv, tcLook
 import TcRules         ( tcIfaceRules, tcSourceRules )
 import TcForeign       ( tcForeignImports, tcForeignExports )
 import TcIfaceSig      ( tcInterfaceSigs )
-import TcInstDcls      ( tcInstDecls1, tcIfaceInstDecls1, addInstDFuns, tcInstDecls2 )
+import TcInstDcls      ( tcInstDecls1, tcIfaceInstDecls1, addInstDFuns, initInstEnv, tcInstDecls2 )
 import TcUnify         ( unifyTauTy )
 import TcSimplify      ( tcSimplifyTop, tcSimplifyInfer )
 import TcTyClsDecls    ( tcTyAndClassDecls )
@@ -111,7 +111,7 @@ typecheckStmt dflags pcs hst ic_type_env unqual this_mod names (stmt, iface_decl
     tcSetDefaultTys defaultDefaultTys $
 
        -- Typecheck the extra declarations
-    tcExtraDecls pcs this_mod iface_decls      `thenTc` \ (new_pcs, env) ->
+    tcExtraDecls pcs hst this_mod iface_decls  `thenTc` \ (new_pcs, env) ->
 
     tcSetEnv env                               $
     tcExtendGlobalTypeEnv ic_type_env          $
@@ -245,7 +245,7 @@ typecheckExpr dflags pcs hst ic_type_env unqual this_mod (expr, decls)
     tcSetDefaultTys defaultDefaultTys $
 
        -- Typecheck the extra declarations
-    tcExtraDecls pcs this_mod decls    `thenTc` \ (new_pcs, env) ->
+    tcExtraDecls pcs hst this_mod decls        `thenTc` \ (new_pcs, env) ->
 
        -- Now typecheck the expression
     tcSetEnv env                       $
@@ -296,15 +296,17 @@ typecheckExtraDecls
 
 typecheckExtraDecls dflags pcs hst unqual this_mod decls
  = typecheck dflags pcs hst unqual $
-   tcExtraDecls pcs this_mod decls     `thenTc` \ (new_pcs, _) ->
+   tcExtraDecls pcs hst this_mod decls `thenTc` \ (new_pcs, _) ->
    returnTc new_pcs
 
 tcExtraDecls :: PersistentCompilerState
+            -> HomeSymbolTable
             -> Module          
             -> [RenamedHsDecl] 
             -> TcM (PersistentCompilerState, TcEnv)
+       -- Returned environment includes instances
 
-tcExtraDecls pcs this_mod decls
+tcExtraDecls pcs hst this_mod decls
   = tcIfaceImports this_mod decls      `thenTc` \ (env, all_things, dfuns, rules) ->
     addInstDFuns (pcs_insts pcs) dfuns `thenNF_Tc` \ new_pcs_insts ->
     let
@@ -317,8 +319,11 @@ tcExtraDecls pcs this_mod decls
                        pcs_rules = new_pcs_rules
                  }
     in
-       -- Add the new instances
-    tcSetEnv env (tcSetInstEnv new_pcs_insts tcGetEnv) `thenNF_Tc` \ new_env ->
+       -- Initialise the instance environment
+    tcSetEnv env (
+       initInstEnv new_pcs hst         `thenNF_Tc` \ inst_env ->
+       tcSetInstEnv inst_env tcGetEnv
+    )                                  `thenNF_Tc` \ new_env ->
     returnTc (new_pcs, new_env)
 \end{code}
 
@@ -386,10 +391,11 @@ tcModule pcs hst get_fixity this_mod decls
        tcSetEnv env1                           $
 
                -- Do the source-language instances, including derivings
-       tcInstDecls1 new_pcs hst unf_env 
+       initInstEnv new_pcs hst                 `thenNF_Tc` \ inst_env1 ->
+       tcInstDecls1 (pcs_PRS new_pcs) inst_env1
                     get_fixity this_mod 
-                    tycl_decls src_inst_decls  `thenTc` \ (inst_env, inst_info, deriv_binds) ->
-       tcSetInstEnv inst_env                   $
+                    tycl_decls src_inst_decls  `thenTc` \ (inst_env2, inst_info, deriv_binds) ->
+       tcSetInstEnv inst_env2                  $
 
         -- Foreign import declarations next
         traceTc (text "Tc4")                   `thenNF_Tc_`
index 88827cd..775cf75 100644 (file)
@@ -1738,7 +1738,6 @@ tcSimplifyDeriv tyvars theta
     simpleReduceLoop doc reduceMe wanteds              `thenTc` \ (frees, _, irreds) ->
     ASSERT( null frees )                       -- reduceMe never returns Free
 
-    doptsTc Opt_AllowUndecidableInstances              `thenNF_Tc` \ undecidable_ok ->
     let
        tv_set      = mkVarSet tvs
        simpl_theta = map dictPred irreds       -- reduceMe squashes all non-dicts
@@ -1746,8 +1745,11 @@ tcSimplifyDeriv tyvars theta
        check_pred pred
          -- Check that the returned dictionaries are all of form (C a b)
          --    (where a, b are type variables).  
-         -- Unless we have -fallow-undecidable-instances.
-         | not undecidable_ok && not (isTyVarClassPred pred)
+         -- At one time we allowed this if we had -fallow-undecidable-instances,
+         -- but that risks non-termination in the 'deriving' context-inference
+         -- fixpoint loop. If you want fancy stuff you just have to write the
+         -- instance decl yourself.
+         | not (isTyVarClassPred pred)
           = addErrTc (noInstErr pred)
   
          -- Check for a bizarre corner case, when the derived instance decl should