Big tidy-up of deriving code
[ghc-hetmet.git] / compiler / rename / RnSource.lhs
index 6053098..9653bdc 100644 (file)
@@ -23,11 +23,12 @@ import RnTypes              ( rnLHsType, rnLHsTypes, rnHsSigType, rnHsTypeFVs, rnContext )
 import RnBinds         ( rnTopBinds, rnMethodBinds, renameSigs, mkSigTvFn )
 import RnEnv           ( lookupLocalDataTcNames,
                          lookupLocatedTopBndrRn, lookupLocatedOccRn,
-                         lookupOccRn, newLocalsRn, 
+                         lookupOccRn, lookupTopBndrRn, newLocalsRn, 
                          bindLocatedLocalsFV, bindPatSigTyVarsFV,
                          bindTyVarsRn, extendTyVarEnvFVRn,
                          bindLocalNames, checkDupNames, mapFvRn
                        )
+import RnHsDoc          ( rnHsDoc, rnMbLHsDoc )
 import TcRnMonad
 
 import HscTypes                ( FixityEnv, FixItem(..),
@@ -68,11 +69,13 @@ rnSrcDecls :: HsGroup RdrName -> RnM (TcGblEnv, HsGroup Name)
 rnSrcDecls (HsGroup { hs_valds  = val_decls,
                      hs_tyclds = tycl_decls,
                      hs_instds = inst_decls,
+                      hs_derivds = deriv_decls,
                      hs_fixds  = fix_decls,
                      hs_depds  = deprec_decls,
                      hs_fords  = foreign_decls,
                      hs_defds  = default_decls,
-                     hs_ruleds = rule_decls })
+                     hs_ruleds = rule_decls,
+                      hs_docs   = docs })
 
  = do {                -- Deal with deprecations (returns only the extra deprecations)
        deprecs <- rnSrcDeprecDecls deprec_decls ;
@@ -98,28 +101,36 @@ rnSrcDecls (HsGroup { hs_valds  = val_decls,
                -- So we content ourselves with gathering uses only; that
                -- means we'll only report a declaration as unused if it isn't
                -- mentioned at all.  Ah well.
+       traceRn (text "Start rnTyClDecls") ;
        (rn_tycl_decls,    src_fvs1)
           <- mapFvRn (wrapLocFstM rnTyClDecl) tycl_decls ;
+       traceRn (text "finish rnTyClDecls") ;
        (rn_inst_decls,    src_fvs2)
           <- mapFvRn (wrapLocFstM rnSrcInstDecl) inst_decls ;
+       (rn_deriv_decls,    src_fvs_deriv)
+          <- mapFvRn (wrapLocFstM rnSrcDerivDecl) deriv_decls ;
        (rn_rule_decls,    src_fvs3)
           <- mapFvRn (wrapLocFstM rnHsRuleDecl) rule_decls ;
        (rn_foreign_decls, src_fvs4)
           <- mapFvRn (wrapLocFstM rnHsForeignDecl) foreign_decls ;
        (rn_default_decls, src_fvs5)
           <- mapFvRn (wrapLocFstM rnDefaultDecl) default_decls ;
-       
+
+       rn_docs <- rnDocEntities docs ;
+
        let {
           rn_group = HsGroup { hs_valds  = rn_val_decls,
                                hs_tyclds = rn_tycl_decls,
                                hs_instds = rn_inst_decls,
+                                hs_derivds = rn_deriv_decls,
                                hs_fixds  = rn_fix_decls,
                                hs_depds  = [],
                                hs_fords  = rn_foreign_decls,
                                hs_defds  = rn_default_decls,
-                               hs_ruleds = rn_rule_decls } ;
+                               hs_ruleds = rn_rule_decls,
+                                hs_docs   = rn_docs } ;
 
-          other_fvs = plusFVs [src_fvs1, src_fvs2, src_fvs3, 
+          other_fvs = plusFVs [src_fvs1, src_fvs2, src_fvs_deriv, src_fvs3, 
                                src_fvs4, src_fvs5] ;
           src_dus = bind_dus `plusDU` usesOnly other_fvs 
                -- Note: src_dus will contain *uses* for locally-defined types
@@ -146,6 +157,44 @@ addTcgDUs tcg_env dus = tcg_env { tcg_dus = tcg_dus tcg_env `plusDU` dus }
 
 %*********************************************************
 %*                                                      *
+       HsDoc stuff
+%*                                                      *
+%*********************************************************
+
+\begin{code}
+rnDocEntities :: [DocEntity RdrName] -> RnM [DocEntity Name]
+rnDocEntities ents
+  = ifErrsM (return []) $
+       -- Yuk: stop if we have found errors.  Otherwise
+       -- the rnDocEntity stuff reports the errors again.
+    mapM rnDocEntity ents 
+
+rnDocEntity :: DocEntity RdrName -> RnM (DocEntity Name)
+rnDocEntity (DocEntity docdecl) = do
+  rn_docdecl <- rnDocDecl docdecl
+  return (DocEntity rn_docdecl)
+rnDocEntity (DeclEntity name) = do
+  rn_name <- lookupTopBndrRn name
+  return (DeclEntity rn_name)
+
+rnDocDecl :: DocDecl RdrName -> RnM (DocDecl Name)
+rnDocDecl (DocCommentNext doc) = do 
+  rn_doc <- rnHsDoc doc
+  return (DocCommentNext rn_doc)
+rnDocDecl (DocCommentPrev doc) = do 
+  rn_doc <- rnHsDoc doc
+  return (DocCommentPrev rn_doc)
+rnDocDecl (DocCommentNamed str doc) = do
+  rn_doc <- rnHsDoc doc
+  return (DocCommentNamed str rn_doc)
+rnDocDecl (DocGroup lev doc) = do
+  rn_doc <- rnHsDoc doc
+  return (DocGroup lev rn_doc)
+\end{code}
+
+
+%*********************************************************
+%*                                                      *
        Source-code fixity declarations
 %*                                                      *
 %*********************************************************
@@ -365,6 +414,19 @@ extendTyVarEnvForMethodBinds tyvars thing_inside
        thing_inside
 \end{code}
 
+%*********************************************************
+%*                                                     *
+\subsection{Stand-alone deriving declarations}
+%*                                                     *
+%*********************************************************
+
+\begin{code}
+rnSrcDerivDecl :: DerivDecl RdrName -> RnM (DerivDecl Name, FreeVars)
+rnSrcDerivDecl (DerivDecl ty)
+  = do ty' <- rnLHsType (text "a deriving decl") ty
+       let fvs = extractHsTyNames ty'
+       return (DerivDecl ty', fvs)
+\end{code}
 
 %*********************************************************
 %*                                                     *
@@ -593,34 +655,30 @@ rnTyClDecl tydecl@(TySynonym {tcdLName = name, tcdTyVars = tyvars,
 
 rnTyClDecl (ClassDecl {tcdCtxt = context, tcdLName = cname, 
                       tcdTyVars = tyvars, tcdFDs = fds, tcdSigs = sigs, 
-                      tcdMeths = mbinds, tcdATs = ats})
-  = lookupLocatedTopBndrRn cname               `thenM` \ cname' ->
+                      tcdMeths = mbinds, tcdATs = ats, tcdDocs = docs})
+  = do { cname' <- lookupLocatedTopBndrRn cname
 
        -- Tyvars scope over superclass context and method signatures
-    bindTyVarsRn cls_doc tyvars                        ( \ tyvars' ->
-       rnContext cls_doc context       `thenM` \ context' ->
-       rnFds cls_doc fds               `thenM` \ fds' ->
-       rnATs ats                       `thenM` \ (ats', ats_fvs) ->
-       renameSigs okClsDclSig sigs     `thenM` \ sigs' ->
-       returnM   (tyvars', context', fds', (ats', ats_fvs), sigs')
-    )  `thenM` \ (tyvars', context', fds', (ats', ats_fvs), sigs') ->
+       ; (tyvars', context', fds', ats', ats_fvs, sigs')
+           <- bindTyVarsRn cls_doc tyvars $ \ tyvars' -> do
+            { context' <- rnContext cls_doc context
+            ; fds' <- rnFds cls_doc fds
+            ; (ats', ats_fvs) <- rnATs ats
+            ; sigs' <- renameSigs okClsDclSig sigs
+            ; return   (tyvars', context', fds', ats', ats_fvs, sigs') }
 
        -- Check for duplicates among the associated types
-    let
-      at_rdr_names_w_locs      = [tcdLName ty | L _ ty <- ats]
-    in
-    checkDupNames at_doc at_rdr_names_w_locs   `thenM_`
+       ; let at_rdr_names_w_locs = [tcdLName ty | L _ ty <- ats]
+       ; checkDupNames at_doc at_rdr_names_w_locs
 
        -- Check the signatures
        -- First process the class op sigs (op_sigs), then the fixity sigs (non_op_sigs).
-    let
-       sig_rdr_names_w_locs   = [op | L _ (TypeSig op _) <- sigs]
-    in
-    checkDupNames sig_doc sig_rdr_names_w_locs `thenM_` 
-       -- Typechecker is responsible for checking that we only
-       -- give default-method bindings for things in this class.
-       -- The renamer *could* check this for class decls, but can't
-       -- for instance decls.
+       ; let sig_rdr_names_w_locs = [op | L _ (TypeSig op _) <- sigs]
+       ; checkDupNames sig_doc sig_rdr_names_w_locs
+               -- Typechecker is responsible for checking that we only
+               -- give default-method bindings for things in this class.
+               -- The renamer *could* check this for class decls, but can't
+               -- for instance decls.
 
        -- The newLocals call is tiresome: given a generic class decl
        --      class C a where
@@ -630,28 +688,31 @@ rnTyClDecl (ClassDecl {tcdCtxt = context, tcdLName = cname,
        --        op {| a*b |} (a*b)   = ...
        -- we want to name both "x" tyvars with the same unique, so that they are
        -- easy to group together in the typechecker.  
-    extendTyVarEnvForMethodBinds tyvars' (
-        getLocalRdrEnv                                 `thenM` \ name_env ->
-        let
-            meth_rdr_names_w_locs = collectHsBindLocatedBinders mbinds
-            gen_rdr_tyvars_w_locs = 
-               [ tv | tv <- extractGenericPatTyVars mbinds,
-                     not (unLoc tv `elemLocalRdrEnv` name_env) ]
-        in
-        checkDupNames meth_doc meth_rdr_names_w_locs   `thenM_`
-        newLocalsRn gen_rdr_tyvars_w_locs      `thenM` \ gen_tyvars ->
-        rnMethodBinds (unLoc cname') (mkSigTvFn sigs') gen_tyvars mbinds
-    ) `thenM` \ (mbinds', meth_fvs) ->
-
-    returnM (ClassDecl { tcdCtxt = context', tcdLName = cname', 
-                        tcdTyVars = tyvars', tcdFDs = fds', tcdSigs = sigs',
-                        tcdMeths = mbinds', tcdATs = ats'},
-            delFVs (map hsLTyVarName tyvars')  $
-            extractHsCtxtTyNames context'          `plusFV`
-            plusFVs (map extractFunDepNames (map unLoc fds'))  `plusFV`
-            hsSigsFVs sigs'                        `plusFV`
-            meth_fvs                               `plusFV`
-            ats_fvs)
+       ; (mbinds', meth_fvs) 
+           <- extendTyVarEnvForMethodBinds tyvars' $ do
+           { name_env <- getLocalRdrEnv
+           ; let meth_rdr_names_w_locs = collectHsBindLocatedBinders mbinds
+                 gen_rdr_tyvars_w_locs = [ tv | tv <- extractGenericPatTyVars mbinds,
+                                                not (unLoc tv `elemLocalRdrEnv` name_env) ]
+           ; checkDupNames meth_doc meth_rdr_names_w_locs
+           ; gen_tyvars <- newLocalsRn gen_rdr_tyvars_w_locs
+           ; rnMethodBinds (unLoc cname') (mkSigTvFn sigs') gen_tyvars mbinds }
+
+       -- Sigh.  Check the Haddock docs after the methods, to avoid duplicate errors
+       -- Example: class { op :: a->a;  op2 x = x }
+       --      Don't want a duplicate complait about op2
+       ; docs' <- bindLocalNames (map hsLTyVarName tyvars') $ rnDocEntities docs
+
+       ; return (ClassDecl { tcdCtxt = context', tcdLName = cname', 
+                             tcdTyVars = tyvars', tcdFDs = fds', tcdSigs = sigs',
+                             tcdMeths = mbinds', tcdATs = ats', tcdDocs = docs'},
+
+                 delFVs (map hsLTyVarName tyvars')     $
+                 extractHsCtxtTyNames context'         `plusFV`
+                 plusFVs (map extractFunDepNames (map unLoc fds'))  `plusFV`
+                 hsSigsFVs sigs'                       `plusFV`
+                 meth_fvs                              `plusFV`
+                 ats_fvs) }
   where
     meth_doc = text "In the default-methods for class" <+> ppr cname
     cls_doc  = text "In the declaration for class"     <+> ppr cname
@@ -683,7 +744,7 @@ rnConDecls tycon condecls
   = mappM (wrapLocM rnConDecl) condecls
 
 rnConDecl :: ConDecl RdrName -> RnM (ConDecl Name)
-rnConDecl (ConDecl name expl tvs cxt details res_ty)
+rnConDecl (ConDecl name expl tvs cxt details res_ty mb_doc)
   = do { addLocM checkConName name
 
        ; new_name <- lookupLocatedTopBndrRn name
@@ -702,12 +763,14 @@ rnConDecl (ConDecl name expl tvs cxt details res_ty)
                        Explicit -> tvs
                        Implicit -> userHsTyVarBndrs implicit_tvs
 
+       ; mb_doc' <- rnMbLHsDoc mb_doc 
+
        ; bindTyVarsRn doc tvs' $ \new_tyvars -> do
        { new_context <- rnContext doc cxt
         ; new_details <- rnConDetails doc details
         ; (new_details', new_res_ty)  <- rnConResult doc new_details res_ty
-        ; return (ConDecl new_name expl new_tyvars new_context new_details' new_res_ty) }}
-  where
+        ; return (ConDecl new_name expl new_tyvars new_context new_details' new_res_ty mb_doc') }}
+ where
     doc = text "In the definition of data constructor" <+> quotes (ppr name)
     get_rdr_tvs tys  = extractHsRhoRdrTyVars cxt (noLoc (HsTupleTy Boxed tys))
 
@@ -736,12 +799,14 @@ rnConDetails doc (RecCon fields)
     mappM (rnField doc) fields         `thenM` \ new_fields ->
     returnM (RecCon new_fields)
   where
-    field_names = [fld | (fld, _) <- fields]
+    field_names = [ name | HsRecField name _ _ <- fields ]
 
-rnField doc (name, ty)
+-- Document comments are renamed to Nothing here
+rnField doc (HsRecField name ty haddock_doc)
   = lookupLocatedTopBndrRn name        `thenM` \ new_name ->
     rnLHsType doc ty           `thenM` \ new_ty ->
-    returnM (new_name, new_ty) 
+    rnMbLHsDoc haddock_doc      `thenM` \ new_haddock_doc ->
+    returnM (HsRecField new_name new_ty new_haddock_doc) 
 
 -- Rename kind signatures (signatures of indexed data types/newtypes and
 -- signatures of type functions)
@@ -765,8 +830,7 @@ rnTySig (tydecl@TyData {tcdCtxt = context, tcdLName = tycon,
       ASSERT( isNothing mb_typats ) -- won't have type patterns
       ASSERT( isNothing derivs )    -- won't have deriving
       ASSERT( isJust sig )          -- will have kind signature
-      do { checkM (not . null $ tyvars) $ addErr needOneIdx   -- #indexes >= 1
-        ; bindIdxVars (ksig_doc tycon) tyvars $ \tyvars' -> do {
+      do { bindIdxVars (ksig_doc tycon) tyvars $ \tyvars' -> do {
         ; tycon' <- lookupLocatedTopBndrRn tycon
         ; context' <- rnContext (ksig_doc tycon) context
         ; returnM (TyData {tcdND = tcdND tydecl, tcdCtxt = context',