Improve the handling of deriving, in error cases
[ghc-hetmet.git] / compiler / typecheck / TcDeriv.lhs
index 1a9a881..b973ec4 100644 (file)
@@ -47,6 +47,8 @@ import Util
 import ListSetOps
 import Outputable
 import Bag
+
+import Monad (unless)
 \end{code}
 
 %************************************************************************
@@ -395,7 +397,7 @@ mkEqnHelp orig tvs cls cls_tys tc_app
              full_tc_args = tc_args ++ mkTyVarTys extra_tvs
              full_tvs = tvs ++ extra_tvs
                
-       ; (rep_tc, rep_tc_args) <- tcLookupFamInst tycon full_tc_args
+       ; (rep_tc, rep_tc_args) <- tcLookupFamInstExact tycon full_tc_args
 
        ; gla_exts <- doptM Opt_GlasgowExts
        ; overlap_flag <- getOverlapFlag
@@ -415,6 +417,27 @@ mkEqnHelp orig tvs cls cls_tys tc_app
 baleOut err = addErrTc err >> returnM (Nothing, Nothing) 
 \end{code}
 
+Auxiliary lookup wrapper which requires that looked up family instances are
+not type instances.
+
+\begin{code}
+tcLookupFamInstExact :: TyCon -> [Type] -> TcM (TyCon, [Type])
+tcLookupFamInstExact tycon tys
+  = do { result@(rep_tycon, rep_tys) <- tcLookupFamInst tycon tys
+       ; let { tvs                   = map (Type.getTyVar 
+                                               "TcDeriv.tcLookupFamInstExact") 
+                                           rep_tys
+            ; variable_only_subst = all Type.isTyVarTy rep_tys &&
+                                    sizeVarSet (mkVarSet tvs) == length tvs
+                                       -- renaming may have no repetitions
+             }
+       ; unless variable_only_subst $
+           famInstNotFound tycon tys [result]
+       ; return result
+       }
+       
+\end{code}
+
 
 %************************************************************************
 %*                                                                     *
@@ -843,11 +866,11 @@ solveDerivEqns overlap_flag orig_eqns
     gen_soln :: DerivEqn -> TcM [PredType]
     gen_soln (loc, orig, _, tyvars, clas, inst_ty, deriv_rhs)
       = setSrcSpan loc $
+       addErrCtxt (derivInstCtxt clas [inst_ty]) $ 
        do { theta <- tcSimplifyDeriv orig tyvars deriv_rhs
-          ; addErrCtxt (derivInstCtxt theta clas [inst_ty]) $ 
-       do { checkNoErrs (checkValidInstance tyvars theta clas [inst_ty])
-               -- See Note [Deriving context]
-               -- If this fails, don't continue
+               -- checkValidInstance tyvars theta clas [inst_ty]
+               -- Not necessary; see Note [Exotic derived instance contexts]
+               --                in TcSimplify
 
                  -- Check for a bizarre corner case, when the derived instance decl should
                  -- have form  instance C a b => D (T a) where ...
@@ -861,7 +884,7 @@ solveDerivEqns overlap_flag orig_eqns
                -- Claim: the result instance declaration is guaranteed valid
                -- Hence no need to call:
                --   checkValidInstance tyvars theta clas inst_tys
-          ; return (sortLe (<=) theta) } }     -- Canonicalise before returning the solution
+          ; return (sortLe (<=) theta) }       -- Canonicalise before returning the solution
 
     ------------------------------------------------------------------
     mk_inst_spec :: DerivEqn -> DerivSoln -> Instance
@@ -880,25 +903,6 @@ extendLocalInstEnv dfuns thing_inside
       ; setGblEnv env' thing_inside }
 \end{code}
 
-Note [Deriving context]
-~~~~~~~~~~~~~~~~~~~~~~~
-With -fglasgow-exts, we allow things like (C Int a) in the simplified
-context for a derived instance declaration, because at a use of this
-instance, we might know that a=Bool, and have an instance for (C Int
-Bool)
-
-We nevertheless insist that each predicate meets the termination
-conditions. If not, the deriving mechanism generates larger and larger
-constraints.  Example:
-  data Succ a = S a
-  data Seq a = Cons a (Seq (Succ a)) | Nil deriving Show
-
-Note the lack of a Show instance for Succ.  First we'll generate
-  instance (Show (Succ a), Show a) => Show (Seq a)
-and then
-  instance (Show (Succ (Succ a)), Show (Succ a), Show a) => Show (Seq a)
-and so on.  Instead we want to complain of no instance for (Show (Succ a)).
-  
 
 %************************************************************************
 %*                                                                     *
@@ -980,7 +984,7 @@ genInst spec
 
           -- In case of a family instance, we need to use the representation
           -- tycon (after all, it has the data constructors)
-        ; (tycon, _) <- tcLookupFamInst visible_tycon tyArgs
+        ; (tycon, _) <- tcLookupFamInstExact visible_tycon tyArgs
        ; let (meth_binds, aux_binds) = genDerivBinds clas fix_env tycon
 
        -- Bring the right type variables into 
@@ -1114,10 +1118,8 @@ derivingThingErr clas tys ty why
 standaloneCtxt :: LHsType Name -> SDoc
 standaloneCtxt ty = ptext SLIT("In the stand-alone deriving instance for") <+> quotes (ppr ty)
 
-derivInstCtxt theta clas inst_tys
-  = hang (ptext SLIT("In the derived instance:"))
-        2 (pprThetaArrow theta <+> pprClassPred clas inst_tys)
--- Used for the ...Thetas variants; all top level
+derivInstCtxt clas inst_tys
+  = ptext SLIT("When deriving the instance for") <+> parens (pprClassPred clas inst_tys)
 
 badDerivedPred pred
   = vcat [ptext SLIT("Can't derive instances where the instance context mentions"),