Print infix function definitions correctly in HsSyn
[ghc-hetmet.git] / compiler / rename / RnSource.lhs
index ca237dd..59ca11b 100644 (file)
@@ -84,15 +84,10 @@ rnSrcDecls (HsGroup { hs_valds  = val_decls,
                -- Deal with top-level fixity decls 
                -- (returns the total new fixity env)
         rn_fix_decls <- rnSrcFixityDecls fix_decls ;
-       fix_env <- rnSrcFixityDeclsEnv rn_fix_decls ;
-       updGblEnv (\gbl -> gbl { tcg_fix_env = fix_env })
-                 $ do {
-
-               -- Rename other declarations
-       traceRn (text "Start rnmono") ;
-       (rn_val_decls, bind_dus) <- rnTopBinds val_decls ;
-       traceRn (text "finish rnmono" <+> ppr rn_val_decls) ;
+       tcg_env      <- extendGblFixityEnv rn_fix_decls ;
+       setGblEnv tcg_env $ do {
 
+               -- Rename type and class decls
                -- You might think that we could build proper def/use information
                -- for type and class declarations, but they can be involved
                -- in mutual recursion across modules, and we only do the SCC
@@ -101,21 +96,25 @@ rnSrcDecls (HsGroup { hs_valds  = val_decls,
                -- 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 ;
-
-  -- Haddock docs
+       (rn_tycl_decls,    src_fvs1) <- rnList rnTyClDecl tycl_decls ;
+
+               -- Extract the mapping from data constructors to field names
+       tcg_env <- extendRecordFieldEnv rn_tycl_decls ;
+       setGblEnv tcg_env $ do {
+
+               -- Value declarations
+       traceRn (text "Start rnmono") ;
+       (rn_val_decls, bind_dus) <- rnTopBinds val_decls ;
+       traceRn (text "finish rnmono" <+> ppr rn_val_decls) ;
+
+               -- Other decls
+       (rn_inst_decls,    src_fvs2) <- rnList rnSrcInstDecl   inst_decls ;
+       (rn_rule_decls,    src_fvs3) <- rnList rnHsRuleDecl    rule_decls ;
+       (rn_foreign_decls, src_fvs4) <- rnList rnHsForeignDecl foreign_decls ;
+       (rn_default_decls, src_fvs5) <- rnList rnDefaultDecl   default_decls ;
+       (rn_deriv_decls,   src_fvs6) <- rnList rnSrcDerivDecl  deriv_decls ;
+
+  -- Haddock docs; no free vars
        rn_docs <- mapM (wrapLocM rnDocDecl) docs ;
 
        let {
@@ -130,7 +129,7 @@ rnSrcDecls (HsGroup { hs_valds  = val_decls,
                                hs_ruleds = rn_rule_decls,
             hs_docs   = rn_docs } ;
 
-          other_fvs = plusFVs [src_fvs1, src_fvs2, src_fvs_deriv, src_fvs3, 
+          other_fvs = plusFVs [src_fvs1, src_fvs2, src_fvs6, src_fvs3, 
                                src_fvs4, src_fvs5] ;
           src_dus = bind_dus `plusDU` usesOnly other_fvs 
                -- Note: src_dus will contain *uses* for locally-defined types
@@ -141,17 +140,19 @@ rnSrcDecls (HsGroup { hs_valds  = val_decls,
 
        traceRn (text "finish rnSrc" <+> ppr rn_group) ;
        traceRn (text "finish Dus" <+> ppr src_dus ) ;
-       tcg_env <- getGblEnv ;
        return (tcg_env `addTcgDUs` src_dus, rn_group)
-    }}}
+    }}}}
 
 rnTyClDecls :: [LTyClDecl RdrName] -> RnM [LTyClDecl Name]
-rnTyClDecls tycl_decls = do 
-  (decls', fvs) <- mapFvRn (wrapLocFstM rnTyClDecl) tycl_decls
-  return decls'
+-- Used for external core
+rnTyClDecls tycl_decls = do  (decls', fvs) <- rnList rnTyClDecl tycl_decls
+                            return decls'
 
 addTcgDUs :: TcGblEnv -> DefUses -> TcGblEnv 
 addTcgDUs tcg_env dus = tcg_env { tcg_dus = tcg_dus tcg_env `plusDU` dus }
+
+rnList :: (a -> RnM (b, FreeVars)) -> [Located a] -> RnM ([Located b], FreeVars)
+rnList f xs = mapFvRn (wrapLocFstM f) xs
 \end{code}
 
 
@@ -186,38 +187,39 @@ rnDocDecl (DocGroup lev doc) = do
 
 \begin{code}
 rnSrcFixityDecls :: [LFixitySig RdrName] -> RnM [LFixitySig Name]
+-- First rename the fixity decls, so we can put
+-- the renamed decls in the renamed syntax tre
 rnSrcFixityDecls fix_decls
-    = do fix_decls <- mapM rnFixityDecl fix_decls
-         return (concat fix_decls)
-
-rnFixityDecl :: LFixitySig RdrName -> RnM [LFixitySig Name]
-rnFixityDecl (L loc (FixitySig (L nameLoc rdr_name) fixity))
-    = setSrcSpan nameLoc $
+  = do fix_decls <- mapM rn_decl fix_decls
+       return (concat fix_decls)
+  where
+    rn_decl :: LFixitySig RdrName -> RnM [LFixitySig Name]
         -- GHC extension: look up both the tycon and data con 
-       -- for con-like things
+       -- for con-like things; hence returning a list
        -- If neither are in scope, report an error; otherwise
        -- add both to the fixity env
-      do names <- lookupLocalDataTcNames rdr_name
-         return [ L loc (FixitySig (L nameLoc name) fixity)
-                      | name <- names ]
-
-rnSrcFixityDeclsEnv :: [LFixitySig Name] -> RnM FixityEnv
-rnSrcFixityDeclsEnv fix_decls
-  = getGblEnv                                  `thenM` \ gbl_env ->
-    foldlM rnFixityDeclEnv (tcg_fix_env gbl_env) 
-           fix_decls                                   `thenM` \ fix_env ->
-    traceRn (text "fixity env" <+> pprFixEnv fix_env)  `thenM_`
-    returnM fix_env
-
-rnFixityDeclEnv :: FixityEnv -> LFixitySig Name -> RnM FixityEnv
-rnFixityDeclEnv fix_env (L loc (FixitySig (L nameLoc name) fixity))
-  = case lookupNameEnv fix_env name of
-      Just (FixItem _ _ loc') 
-         -> do addLocErr (L nameLoc name) (dupFixityDecl loc')
-               return fix_env
-      Nothing
-          -> return (extendNameEnv fix_env name fix_item)
-    where fix_item = FixItem (nameOccName name) fixity nameLoc
+    rn_decl (L loc (FixitySig (L name_loc rdr_name) fixity))
+      = setSrcSpan name_loc $
+        do names <- lookupLocalDataTcNames rdr_name
+           return [ L loc (FixitySig (L name_loc name) fixity)
+                  | name <- names ]
+
+extendGblFixityEnv :: [LFixitySig Name] -> RnM TcGblEnv
+-- Extend the global envt with fixity decls, checking for duplicate decls
+extendGblFixityEnv decls
+  = do { env <- getGblEnv
+       ; fix_env' <- foldlM add_one (tcg_fix_env env) decls
+       ; return (env { tcg_fix_env = fix_env' }) }
+  where
+    add_one fix_env (L loc (FixitySig (L name_loc name) fixity))
+       | Just (FixItem _ _ loc') <- lookupNameEnv fix_env name
+       = do { setSrcSpan loc $
+              addLocErr (L name_loc name) (dupFixityDecl loc')
+            ; return fix_env }
+       | otherwise
+       = return (extendNameEnv fix_env name fix_item)
+      where 
+       fix_item = FixItem (nameOccName name) fixity loc
 
 pprFixEnv :: FixityEnv -> SDoc
 pprFixEnv env 
@@ -284,7 +286,7 @@ rnHsForeignDecl (ForeignImport name ty spec)
 rnHsForeignDecl (ForeignExport name ty spec)
   = lookupLocatedOccRn name            `thenM` \ name' ->
     rnHsTypeFVs (fo_decl_msg name) ty          `thenM` \ (ty', fvs) ->
-    returnM (ForeignExport name' ty' spec, fvs )
+    returnM (ForeignExport name' ty' spec, fvs `addOneFV` unLoc name')
        -- NB: a foreign export is an *occurrence site* for name, so 
        --     we add it to the free-variable list.  It might, for example,
        --     be imported from another module
@@ -362,8 +364,7 @@ Renaming of the associated types in instances.
 
 \begin{code}
 rnATInsts :: [LTyClDecl RdrName] -> RnM ([LTyClDecl Name], FreeVars)
-rnATInsts atDecls = 
-  mapFvRn (wrapLocFstM rnATInst) atDecls
+rnATInsts atDecls = rnList rnATInst atDecls
   where
     rnATInst tydecl@TyData     {} = rnTyClDecl tydecl
     rnATInst tydecl@TySynonym  {} = rnTyClDecl tydecl
@@ -377,11 +378,11 @@ type variable environment iff -fglasgow-exts
 
 \begin{code}
 extendTyVarEnvForMethodBinds tyvars thing_inside
-  = doptM Opt_GlasgowExts                      `thenM` \ opt_GlasgowExts ->
-    if opt_GlasgowExts then
-       extendTyVarEnvFVRn (map hsLTyVarName tyvars) thing_inside
-    else
-       thing_inside
+  = do { scoped_tvs <- doptM Opt_ScopedTypeVariables
+       ; if scoped_tvs then
+               extendTyVarEnvFVRn (map hsLTyVarName tyvars) thing_inside
+         else
+               thing_inside }
 \end{code}
 
 %*********************************************************
@@ -724,7 +725,7 @@ rnConDecl (ConDecl name expl tvs cxt details res_ty mb_doc)
        -- For GADT syntax, the tvs are all the quantified tyvars
        -- Hence the 'filter' in the ResTyH98 case only
        ; let not_in_scope  = not . (`elemLocalRdrEnv` name_env) . unLoc
-             arg_tys       = hsConArgs details
+             arg_tys       = hsConDeclArgTys details
              implicit_tvs  = case res_ty of
                                ResTyH98 -> filter not_in_scope $
                                                get_rdr_tvs arg_tys
@@ -737,7 +738,7 @@ rnConDecl (ConDecl name expl tvs cxt details res_ty mb_doc)
 
        ; bindTyVarsRn doc tvs' $ \new_tyvars -> do
        { new_context <- rnContext doc cxt
-        ; new_details <- rnConDetails doc details
+        ; new_details <- rnConDeclDetails 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 mb_doc') }}
  where
@@ -755,28 +756,25 @@ rnConResult doc details (ResTyGADT ty) = do
        RecCon fields -> return (details, ResTyGADT ty')
        InfixCon {}   -> panic "rnConResult"
 
-rnConDetails doc (PrefixCon tys)
+rnConDeclDetails doc (PrefixCon tys)
   = mappM (rnLHsType doc) tys  `thenM` \ new_tys  ->
     returnM (PrefixCon new_tys)
 
-rnConDetails doc (InfixCon ty1 ty2)
+rnConDeclDetails doc (InfixCon ty1 ty2)
   = rnLHsType doc ty1                  `thenM` \ new_ty1 ->
     rnLHsType doc ty2                  `thenM` \ new_ty2 ->
     returnM (InfixCon new_ty1 new_ty2)
 
-rnConDetails doc (RecCon fields)
-  = checkDupNames doc field_names      `thenM_`
-    mappM (rnField doc) fields         `thenM` \ new_fields ->
-    returnM (RecCon new_fields)
-  where
-    field_names = [ name | HsRecField name _ _ <- fields ]
+rnConDeclDetails doc (RecCon fields)
+  = do { checkDupNames doc (map cd_fld_name fields)
+       ; new_fields <- mappM (rnField doc) fields
+       ; return (RecCon new_fields) }
 
--- Document comments are renamed to Nothing here
-rnField doc (HsRecField name ty haddock_doc)
+rnField doc (ConDeclField name ty haddock_doc)
   = lookupLocatedTopBndrRn name        `thenM` \ new_name ->
     rnLHsType doc ty           `thenM` \ new_ty ->
     rnMbLHsDoc haddock_doc      `thenM` \ new_haddock_doc ->
-    returnM (HsRecField new_name new_ty new_haddock_doc) 
+    returnM (ConDeclField new_name new_ty new_haddock_doc) 
 
 -- Rename family declarations
 --
@@ -802,8 +800,8 @@ rnFamily (tydecl@TyFamily {tcdFlavour = flavour,
                    emptyFVs) 
          } }
       where
-        isDataFlavour (DataFamily _) = True
-       isDataFlavour _              = False
+        isDataFlavour DataFamily = True
+       isDataFlavour _          = False
 
 family_doc tycon = text "In the family declaration for" <+> quotes (ppr tycon)
 needOneIdx = text "Type family declarations requires at least one type index"
@@ -874,6 +872,30 @@ badDataCon name
 
 %*********************************************************
 %*                                                     *
+\subsection{Support code for type/data declarations}
+%*                                                     *
+%*********************************************************
+
+Get the mapping from constructors to fields for this module.
+It's convenient to do this after the data type decls have been renamed
+\begin{code}
+extendRecordFieldEnv :: [LTyClDecl Name] -> TcM TcGblEnv
+extendRecordFieldEnv decls 
+  = do { tcg_env <- getGblEnv
+       ; let field_env' = foldr get (tcg_field_env tcg_env) decls
+       ; return (tcg_env { tcg_field_env = field_env' }) }
+  where
+    get (L _ (TyData { tcdCons = cons })) env = foldr get_con env cons
+    get other                            env = env
+
+    get_con (L _ (ConDecl { con_name = con, con_details = RecCon flds })) env
+       = extendNameEnv env (unLoc con) (map (unLoc . cd_fld_name) flds)
+    get_con other env
+       = env
+\end{code}
+
+%*********************************************************
+%*                                                     *
 \subsection{Support code to rename types}
 %*                                                     *
 %*********************************************************