\begin{code}
module RnBinds (
- rnTopBinds, rnTopMonoBinds,
- rnMethodBinds, renameSigs,
- rnBinds,
- unknownSigErr
+ rnTopBinds, rnBinds, rnBindsAndThen,
+ rnMethodBinds, renameSigs, checkSigs
) where
#include "HsVersions.h"
-import {-# SOURCE #-} RnSource ( rnHsSigType )
import HsSyn
-import HsBinds ( sigsForMe, cmpHsSig, sigName, hsSigDoc )
+import HsBinds ( hsSigDoc, eqHsSig )
import RdrHsSyn
import RnHsSyn
-import RnMonad
-import RnExpr ( rnMatch, rnGRHSs, rnPat, checkPrecMatch )
-import RnEnv ( bindLocatedLocalsRn, lookupBndrRn, lookupGlobalOccRn, lookupOccRn,
- warnUnusedLocalBinds, mapFvRn,
- FreeVars, emptyFVs, plusFV, plusFVs, unitFV, addOneFV,
- unknownNameErr
+import TcRnMonad
+import RnTypes ( rnHsSigType, rnLHsType, rnLPat )
+import RnExpr ( rnMatchGroup, rnMatch, rnGRHSs, checkPrecMatch )
+import RnEnv ( bindLocatedLocalsRn, lookupLocatedBndrRn,
+ lookupLocatedInstDeclBndr,
+ lookupLocatedSigOccRn, bindPatSigTyVars, bindPatSigTyVarsFV,
+ bindLocalFixities, bindSigTyVarsFV,
+ warnUnusedLocalBinds, mapFvRn, extendTyVarEnvFVRn,
)
-import CmdLineOpts ( opt_WarnMissingSigs )
-import Digraph ( stronglyConnComp, SCC(..) )
-import Name ( OccName, Name, nameOccName, mkUnboundName, isUnboundName )
+import DynFlags ( DynFlag(..) )
+import Digraph ( SCC(..), stronglyConnComp )
+import Name ( Name, nameOccName, nameSrcLoc )
import NameSet
-import RdrName ( RdrName, rdrNameOcc )
-import BasicTypes ( RecFlag(..), TopLevelFlag(..) )
-import Util ( thenCmp, removeDups )
-import List ( partition )
-import ListSetOps ( minusList )
-import Bag ( bagToList )
-import FiniteMap ( lookupFM, listToFM )
-import Maybe ( isJust )
+import PrelNames ( isUnboundName )
+import RdrName ( RdrName, rdrNameOcc )
+import BasicTypes ( RecFlag(..), TopLevelFlag(..), isTopLevel )
+import List ( unzip4 )
+import SrcLoc ( mkSrcSpan, Located(..), unLoc )
+import Bag
import Outputable
+import Monad ( foldM )
\end{code}
-- ToDo: Put the annotations into the monad, so that they arrive in the proper
within one @MonoBinds@, so that unique-Int plumbing is done explicitly
(heavy monad machinery not needed).
-\begin{code}
-type VertexTag = Int
-type Cycle = [VertexTag]
-type Edge = (VertexTag, VertexTag)
-\end{code}
%************************************************************************
%* *
%************************************************************************
%* *
-%* analysing polymorphic bindings (HsBinds, Bind, MonoBinds) *
+%* analysing polymorphic bindings (HsBindGroup, HsBind)
%* *
%************************************************************************
\Haskell{} programs, and this code should not be executed.
Monomorphic bindings contain information that is returned in a tuple
-(a @FlatMonoBindsInfo@) containing:
+(a @FlatMonoBinds@) containing:
\begin{enumerate}
\item
%* *
%************************************************************************
-@rnTopBinds@ assumes that the environment already
+@rnTopMonoBinds@ assumes that the environment already
contains bindings for the binders of this particular binding.
\begin{code}
-rnTopBinds :: RdrNameHsBinds -> RnMS (RenamedHsBinds, FreeVars)
-
-rnTopBinds EmptyBinds = returnRn (EmptyBinds, emptyFVs)
-rnTopBinds (MonoBind bind sigs _) = rnTopMonoBinds bind sigs
- -- The parser doesn't produce other forms
-
-
-rnTopMonoBinds EmptyMonoBinds sigs
- = returnRn (EmptyBinds, emptyFVs)
-
-rnTopMonoBinds mbinds sigs
- = mapRn lookupBndrRn binder_rdr_names `thenRn` \ binder_names ->
- renameSigs (okBindSig (mkNameSet binder_names)) sigs `thenRn` \ (siglist, sig_fvs) ->
- let
- type_sig_vars = [n | Sig n _ _ <- siglist]
- un_sigd_binders | opt_WarnMissingSigs = binder_names `minusList` type_sig_vars
- | otherwise = []
- in
- mapRn_ (addWarnRn.missingSigWarn) un_sigd_binders `thenRn_`
-
- rn_mono_binds siglist mbinds `thenRn` \ (final_binds, bind_fvs) ->
- returnRn (final_binds, bind_fvs `plusFV` sig_fvs)
- where
- binder_rdr_names = map fst (bagToList (collectMonoBinders mbinds))
+rnTopBinds :: LHsBinds RdrName
+ -> [LSig RdrName]
+ -> RnM ([HsBindGroup Name], DefUses)
+
+-- The binders of the binding are in scope already;
+-- the top level scope resolution does that
+
+rnTopBinds mbinds sigs
+ = do { is_boot <- tcIsHsBoot
+ ; if is_boot then
+ rnHsBoot mbinds sigs
+ else bindPatSigTyVars (collectSigTysFromHsBinds (bagToList mbinds)) $ \ _ ->
+ -- Hmm; by analogy with Ids, this doesn't look right
+ -- Top-level bound type vars should really scope over
+ -- everything, but we only scope them over the other bindings
+ rnBinds TopLevel mbinds sigs }
+
+rnHsBoot :: LHsBinds RdrName
+ -> [LSig RdrName]
+ -> RnM ([HsBindGroup Name], DefUses)
+-- A hs-boot file has no bindings.
+-- Return a single HsBindGroup with empty binds and renamed signatures
+rnHsBoot mbinds sigs
+ = do { checkErr (isEmptyLHsBinds mbinds) (bindsInHsBootFile mbinds)
+ ; sigs' <- renameSigs sigs
+ ; return ([HsBindGroup emptyLHsBinds sigs' NonRecursive],
+ usesOnly (hsSigsFVs sigs')) }
\end{code}
+
%************************************************************************
%* *
%* Nested binds
%* *
%************************************************************************
-\subsubsection{Nested binds}
-
-@rnMonoBinds@
-\begin{itemize}
-\item collects up the binders for this declaration group,
-\item checks that they form a set
-\item extends the environment to bind them to new local names
-\item calls @rnMonoBinds@ to do the real work
-\end{itemize}
-%
\begin{code}
-rnBinds :: RdrNameHsBinds
- -> (RenamedHsBinds -> RnMS (result, FreeVars))
- -> RnMS (result, FreeVars)
-
-rnBinds EmptyBinds thing_inside = thing_inside EmptyBinds
-rnBinds (MonoBind bind sigs _) thing_inside = rnMonoBinds bind sigs thing_inside
- -- the parser doesn't produce other forms
-
-
-rnMonoBinds :: RdrNameMonoBinds
- -> [RdrNameSig]
- -> (RenamedHsBinds -> RnMS (result, FreeVars))
- -> RnMS (result, FreeVars)
-
-rnMonoBinds EmptyMonoBinds sigs thing_inside = thing_inside EmptyBinds
-
-rnMonoBinds mbinds sigs thing_inside -- Non-empty monobinds
- = -- Extract all the binders in this group,
- -- and extend current scope, inventing new names for the new binders
+rnBindsAndThen :: Bag (LHsBind RdrName)
+ -> [LSig RdrName]
+ -> ([HsBindGroup Name] -> RnM (result, FreeVars))
+ -> RnM (result, FreeVars)
+
+rnBindsAndThen mbinds sigs thing_inside
+ = -- Extract all the binders in this group, and extend the
+ -- current scope, inventing new names for the new binders
-- This also checks that the names form a set
- bindLocatedLocalsRn (text "a binding group") mbinders_w_srclocs
- $ \ new_mbinders ->
- let
- binder_set = mkNameSet new_mbinders
- in
- -- Rename the signatures
- renameSigs (okBindSig binder_set) sigs `thenRn` \ (siglist, sig_fvs) ->
+ bindLocatedLocalsRn doc mbinders_w_srclocs $ \ _ ->
+ bindPatSigTyVarsFV (collectSigTysFromHsBinds (bagToList mbinds)) $
- -- Report the fixity declarations in this group that
- -- don't refer to any of the group's binders.
- -- Then install the fixity declarations that do apply here
+ -- Then install local fixity declarations
-- Notice that they scope over thing_inside too
- let
- fixity_sigs = [(name,sig) | FixSig sig@(FixitySig name _ _) <- siglist ]
- in
- extendFixityEnv fixity_sigs $
+ bindLocalFixities [sig | L _ (FixSig sig) <- sigs ] $
- rn_mono_binds siglist mbinds `thenRn` \ (binds, bind_fvs) ->
+ -- Do the business
+ rnBinds NotTopLevel mbinds sigs `thenM` \ (binds, bind_dus) ->
- -- Now do the "thing inside", and deal with the free-variable calculations
- thing_inside binds `thenRn` \ (result,result_fvs) ->
+ -- Now do the "thing inside"
+ thing_inside binds `thenM` \ (result,result_fvs) ->
+
+ -- Final error checking
let
- all_fvs = result_fvs `plusFV` bind_fvs `plusFV` sig_fvs
- unused_binders = nameSetToList (binder_set `minusNameSet` all_fvs)
+ all_uses = duUses bind_dus `plusFV` result_fvs
+ bndrs = duDefs bind_dus
+ unused_bndrs = nameSetToList (bndrs `minusNameSet` all_uses)
in
- warnUnusedLocalBinds unused_binders `thenRn_`
- returnRn (result, delListFromNameSet all_fvs new_mbinders)
+ warnUnusedLocalBinds unused_bndrs `thenM_`
+
+ returnM (result, all_uses `minusNameSet` bndrs)
+ -- duUses: It's important to return all the uses, not the 'real uses' used for
+ -- warning about unused bindings. Otherwise consider:
+ -- x = 3
+ -- y = let p = x in 'x' -- NB: p not used
+ -- If we don't "see" the dependency of 'y' on 'x', we may put the
+ -- bindings in the wrong order, and the type checker will complain
+ -- that x isn't in scope
where
- mbinders_w_srclocs = bagToList (collectMonoBinders mbinds)
+ mbinders_w_srclocs = collectHsBindLocatedBinders mbinds
+ doc = text "In the binding group for:"
+ <+> pprWithCommas ppr (map unLoc mbinders_w_srclocs)
\end{code}
%************************************************************************
%* *
-\subsubsection{ MonoBinds -- the main work is done here}
+\subsubsection{rnBinds -- the main work is done here}
%* *
%************************************************************************
-@rn_mono_binds@ is used by {\em both} top-level and nested bindings.
+@rnMonoBinds@ is used by {\em both} top-level and nested bindings.
It assumes that all variables bound in this group are already in scope.
This is done {\em either} by pass 3 (for the top-level bindings),
{\em or} by @rnMonoBinds@ (for the nested ones).
\begin{code}
-rn_mono_binds :: [RenamedSig] -- Signatures attached to this group
- -> RdrNameMonoBinds
- -> RnMS (RenamedHsBinds, --
- FreeVars) -- Free variables
-
-rn_mono_binds siglist mbinds
- =
- -- Rename the bindings, returning a MonoBindsInfo
+rnBinds :: TopLevelFlag
+ -> LHsBinds RdrName
+ -> [LSig RdrName]
+ -> RnM ([HsBindGroup Name], DefUses)
+
+-- Assumes the binders of the binding are in scope already
+
+rnBinds top_lvl mbinds sigs
+ = renameSigs sigs `thenM` \ siglist ->
+
+ -- Rename the bindings, returning a [HsBindVertex]
-- which is a list of indivisible vertices so far as
-- the strongly-connected-components (SCC) analysis is concerned
- flattenMonoBinds siglist mbinds `thenRn` \ mbinds_info ->
+ mkBindVertices siglist mbinds `thenM` \ mbinds_info ->
-- Do the SCC analysis
let
- edges = mkEdges (mbinds_info `zip` [(0::Int)..])
- scc_result = stronglyConnComp edges
- final_binds = foldr1 ThenBinds (map reconstructCycle scc_result)
-
- -- Deal with bound and free-var calculation
- rhs_fvs = plusFVs [fvs | (_,fvs,_,_) <- mbinds_info]
+ scc_result = rnSCC mbinds_info
+ (groups, bind_dus_s) = unzip (map reconstructCycle scc_result)
+ bind_dus = mkDUs bind_dus_s
+ binders = duDefs bind_dus
in
- returnRn (final_binds, rhs_fvs)
+ -- Check for duplicate or mis-placed signatures
+ checkSigs (okBindSig binders) siglist `thenM_`
+
+ -- Warn about missing signatures,
+ -- but only at top level, and not in interface mode
+ -- (The latter is important when renaming bindings from 'deriving' clauses.)
+ doptM Opt_WarnMissingSigs `thenM` \ warn_missing_sigs ->
+ (if isTopLevel top_lvl &&
+ warn_missing_sigs
+ then let
+ type_sig_vars = [ unLoc n | L _ (Sig n _) <- siglist]
+ un_sigd_binders = filter (not . (`elem` type_sig_vars))
+ (nameSetToList binders)
+ in
+ mappM_ missingSigWarn un_sigd_binders
+ else
+ returnM ()
+ ) `thenM_`
+
+ returnM (groups, bind_dus `plusDU` usesOnly (hsSigsFVs siglist))
\end{code}
-@flattenMonoBinds@ is ever-so-slightly magical in that it sticks
+@mkBindVertices@ is ever-so-slightly magical in that it sticks
unique ``vertex tags'' on its output; minor plumbing required.
-Sigh --- need to pass along the signatures for the group of bindings,
-in case any of them \fbox{\ ???\ }
-
\begin{code}
-flattenMonoBinds :: [RenamedSig] -- Signatures
- -> RdrNameMonoBinds
- -> RnMS [FlatMonoBindsInfo]
+mkBindVertices :: [LSig Name] -- Signatures
+ -> LHsBinds RdrName
+ -> RnM [BindVertex]
+mkBindVertices sigs = mapM (mkBindVertex sigs) . bagToList
-flattenMonoBinds sigs EmptyMonoBinds = returnRn []
-
-flattenMonoBinds sigs (AndMonoBinds bs1 bs2)
- = flattenMonoBinds sigs bs1 `thenRn` \ flat1 ->
- flattenMonoBinds sigs bs2 `thenRn` \ flat2 ->
- returnRn (flat1 ++ flat2)
-
-flattenMonoBinds sigs (PatMonoBind pat grhss locn)
- = pushSrcLocRn locn $
- rnPat pat `thenRn` \ (pat', pat_fvs) ->
+mkBindVertex :: [LSig Name] -> LHsBind RdrName -> RnM BindVertex
+mkBindVertex sigs (L loc (PatBind pat grhss ty))
+ = setSrcSpan loc $
+ rnLPat pat `thenM` \ (pat', pat_fvs) ->
-- Find which things are bound in this group
let
names_bound_here = mkNameSet (collectPatBinders pat')
- sigs_for_me = sigsForMe (`elemNameSet` names_bound_here) sigs
in
- rnGRHSs grhss `thenRn` \ (grhss', fvs) ->
- returnRn
- [(names_bound_here,
- fvs `plusFV` pat_fvs,
- PatMonoBind pat' grhss' locn,
- sigs_for_me
- )]
-
-flattenMonoBinds sigs (FunMonoBind name inf matches locn)
- = pushSrcLocRn locn $
- lookupBndrRn name `thenRn` \ new_name ->
+ sigsForMe names_bound_here sigs `thenM` \ sigs_for_me ->
+ bindSigTyVarsFV sigs_for_me (
+ rnGRHSs PatBindRhs grhss
+ ) `thenM` \ (grhss', fvs) ->
+ returnM
+ (names_bound_here, fvs `plusFV` pat_fvs,
+ L loc (PatBind pat' grhss' ty), sigs_for_me
+ )
+
+mkBindVertex sigs (L loc (FunBind name inf matches))
+ = setSrcSpan loc $
+ lookupLocatedBndrRn name `thenM` \ new_name ->
let
- sigs_for_me = sigsForMe (new_name ==) sigs
+ plain_name = unLoc new_name
+ names_bound_here = unitNameSet plain_name
in
- mapFvRn rnMatch matches `thenRn` \ (new_matches, fvs) ->
- mapRn_ (checkPrecMatch inf new_name) new_matches `thenRn_`
- returnRn
- [(unitNameSet new_name,
- fvs,
- FunMonoBind new_name inf new_matches locn,
- sigs_for_me
- )]
+ sigsForMe names_bound_here sigs `thenM` \ sigs_for_me ->
+ bindSigTyVarsFV sigs_for_me (
+ rnMatchGroup (FunRhs plain_name) matches
+ ) `thenM` \ (new_matches, fvs) ->
+ checkPrecMatch inf plain_name new_matches `thenM_`
+ returnM
+ (unitNameSet plain_name, fvs,
+ L loc (FunBind new_name inf new_matches), sigs_for_me
+ )
+
+sigsForMe names_bound_here sigs
+ = foldlM check [] (filter (sigForThisGroup names_bound_here) sigs)
+ where
+ -- sigForThisGroup only returns signatures for
+ -- which sigName returns a Just
+ eq sig1 sig2 = eqHsSig (unLoc sig1) (unLoc sig2)
+
+ check sigs sig = case filter (eq sig) sigs of
+ [] -> returnM (sig:sigs)
+ other -> dupSigDeclErr sig other `thenM_`
+ returnM sigs
\end{code}
@rnMethodBinds@ is used for the method bindings of a class and an instance
-declaration. Like @rnMonoBinds@ but without dependency analysis.
+declaration. Like @rnBinds@ but without dependency analysis.
NOTA BENE: we record each {\em binder} of a method-bind group as a free variable.
That's crucial when dealing with an instance decl:
a binder.
\begin{code}
-rnMethodBinds :: RdrNameMonoBinds -> RnMS (RenamedMonoBinds, FreeVars)
-
-rnMethodBinds EmptyMonoBinds = returnRn (EmptyMonoBinds, emptyFVs)
-
-rnMethodBinds (AndMonoBinds mb1 mb2)
- = rnMethodBinds mb1 `thenRn` \ (mb1', fvs1) ->
- rnMethodBinds mb2 `thenRn` \ (mb2', fvs2) ->
- returnRn (mb1' `AndMonoBinds` mb2', fvs1 `plusFV` fvs2)
-
-rnMethodBinds (FunMonoBind name inf matches locn)
- = pushSrcLocRn locn $
-
- lookupGlobalOccRn name `thenRn` \ sel_name ->
+rnMethodBinds :: Name -- Class name
+ -> [Name] -- Names for generic type variables
+ -> LHsBinds RdrName
+ -> RnM (LHsBinds Name, FreeVars)
+
+rnMethodBinds cls gen_tyvars binds
+ = foldM do_one (emptyBag,emptyFVs) (bagToList binds)
+ where do_one (binds,fvs) bind = do
+ (bind', fvs_bind) <- rnMethodBind cls gen_tyvars bind
+ return (bind' `unionBags` binds, fvs_bind `plusFV` fvs)
+
+rnMethodBind cls gen_tyvars (L loc (FunBind name inf (MatchGroup matches _)))
+ = setSrcSpan loc $
+ lookupLocatedInstDeclBndr cls name `thenM` \ sel_name ->
+ let plain_name = unLoc sel_name in
-- We use the selector name as the binder
- mapFvRn rnMatch matches `thenRn` \ (new_matches, fvs) ->
- mapRn_ (checkPrecMatch inf sel_name) new_matches `thenRn_`
- returnRn (FunMonoBind sel_name inf new_matches locn, fvs `addOneFV` sel_name)
+ mapFvRn (rn_match plain_name) matches `thenM` \ (new_matches, fvs) ->
+ let
+ new_group = MatchGroup new_matches placeHolderType
+ in
+ checkPrecMatch inf plain_name new_group `thenM_`
+ returnM (unitBag (L loc (FunBind sel_name inf new_group)), fvs `addOneFV` plain_name)
+ where
+ -- Truly gruesome; bring into scope the correct members of the generic
+ -- type variables. See comments in RnSource.rnSourceDecl(ClassDecl)
+ rn_match sel_name match@(L _ (Match (L _ (TypePat ty) : _) _ _))
+ = extendTyVarEnvFVRn gen_tvs $
+ rnMatch (FunRhs sel_name) match
+ where
+ tvs = map (rdrNameOcc.unLoc) (extractHsTyRdrTyVars ty)
+ gen_tvs = [tv | tv <- gen_tyvars, nameOccName tv `elem` tvs]
+
+ rn_match sel_name match = rnMatch (FunRhs sel_name) match
-rnMethodBinds (PatMonoBind (VarPatIn name) grhss locn)
- = pushSrcLocRn locn $
- lookupGlobalOccRn name `thenRn` \ sel_name ->
- rnGRHSs grhss `thenRn` \ (grhss', fvs) ->
- returnRn (PatMonoBind (VarPatIn sel_name) grhss' locn, fvs `addOneFV` sel_name)
-- Can't handle method pattern-bindings which bind multiple methods.
-rnMethodBinds mbind@(PatMonoBind other_pat _ locn)
- = pushSrcLocRn locn $
- failWithRn (EmptyMonoBinds, emptyFVs) (methodBindErr mbind)
+rnMethodBind cls gen_tyvars mbind@(L loc (PatBind other_pat _ _))
+ = addLocErr mbind methodBindErr `thenM_`
+ returnM (emptyBag, emptyFVs)
\end{code}
%************************************************************************
%* *
-\subsection[reconstruct-deps]{Reconstructing dependencies}
+ Strongly connected components
%* *
%************************************************************************
-This @MonoBinds@- and @ClassDecls@-specific code is segregated here,
-as the two cases are similar.
-
\begin{code}
-reconstructCycle :: SCC FlatMonoBindsInfo
- -> RenamedHsBinds
-
-reconstructCycle (AcyclicSCC (_, _, binds, sigs))
- = MonoBind binds sigs NonRecursive
-
-reconstructCycle (CyclicSCC cycle)
- = MonoBind this_gp_binds this_gp_sigs Recursive
- where
- this_gp_binds = foldr1 AndMonoBinds [binds | (_, _, binds, _) <- cycle]
- this_gp_sigs = foldr1 (++) [sigs | (_, _, _, sigs) <- cycle]
-\end{code}
-
-%************************************************************************
-%* *
-\subsubsection{ Manipulating FlatMonoBindInfo}
-%* *
-%************************************************************************
-
-During analysis a @MonoBinds@ is flattened to a @FlatMonoBindsInfo@.
-The @RenamedMonoBinds@ is always an empty bind, a pattern binding or
-a function binding, and has itself been dependency-analysed and
-renamed.
+type BindVertex = (Defs, Uses, LHsBind Name, [LSig Name])
+ -- Signatures, if any, for this vertex
-\begin{code}
-type FlatMonoBindsInfo
- = (NameSet, -- Set of names defined in this vertex
- NameSet, -- Set of names used in this vertex
- RenamedMonoBinds,
- [RenamedSig]) -- Signatures, if any, for this vertex
+rnSCC :: [BindVertex] -> [SCC BindVertex]
+rnSCC nodes = stronglyConnComp (mkEdges nodes)
-mkEdges :: [(FlatMonoBindsInfo, VertexTag)] -> [(FlatMonoBindsInfo, VertexTag, [VertexTag])]
+type VertexTag = Int
-mkEdges flat_info
- = [ (info, tag, dest_vertices (nameSetToList names_used))
- | (info@(names_defined, names_used, mbind, sigs), tag) <- flat_info
+mkEdges :: [BindVertex] -> [(BindVertex, VertexTag, [VertexTag])]
+ -- We keep the uses with the binding,
+ -- so we can track unused bindings better
+mkEdges nodes
+ = [ (thing, tag, dest_vertices uses)
+ | (thing@(_, uses, _, _), tag) <- tagged_nodes
]
where
+ tagged_nodes = nodes `zip` [0::VertexTag ..]
+
-- An edge (v,v') indicates that v depends on v'
- dest_vertices src_mentions = [ target_vertex
- | ((names_defined, _, _, _), target_vertex) <- flat_info,
- mentioned_name <- src_mentions,
- mentioned_name `elemNameSet` names_defined
- ]
+ dest_vertices uses = [ target_vertex
+ | ((defs, _, _, _), target_vertex) <- tagged_nodes,
+ defs `intersectsNameSet` uses
+ ]
+
+reconstructCycle :: SCC BindVertex -> (HsBindGroup Name, (Defs,Uses))
+reconstructCycle (AcyclicSCC (defs, uses, bind, sigs))
+ = (HsBindGroup (unitBag bind) sigs NonRecursive, (defs, uses))
+reconstructCycle (CyclicSCC cycle)
+ = (HsBindGroup this_gp_binds this_gp_sigs Recursive,
+ (unionManyNameSets defs_s, unionManyNameSets uses_s))
+ where
+ (defs_s, uses_s, binds_s, sigs_s) = unzip4 cycle
+ this_gp_binds = listToBag binds_s
+ this_gp_sigs = foldr1 (++) sigs_s
\end{code}
signatures. We'd only need this if we wanted to report unused tyvars.
\begin{code}
-renameSigs :: (RenamedSig -> Bool) -- OK-sig predicate
- -> [RdrNameSig]
- -> RnMS ([RenamedSig], FreeVars)
-
-renameSigs ok_sig [] = returnRn ([], emptyFVs) -- Common shortcut
-
-renameSigs ok_sig sigs
- = -- Rename the signatures
- mapFvRn renameSig sigs `thenRn` \ (sigs', fvs) ->
-
+checkSigs :: (LSig Name -> Bool) -- OK-sig predicbate
+ -> [LSig Name]
+ -> RnM ()
+checkSigs ok_sig sigs
-- Check for (a) duplicate signatures
-- (b) signatures for things not in this group
- let
- in_scope = filter is_in_scope sigs'
- is_in_scope sig = case sigName sig of
- Just n -> not (isUnboundName n)
- Nothing -> True
- (not_dups, dups) = removeDups cmpHsSig in_scope
- (goods, bads) = partition ok_sig not_dups
- in
- mapRn_ unknownSigErr bads `thenRn_`
- mapRn_ dupSigDeclErr dups `thenRn_`
- returnRn (goods, fvs)
+ -- Well, I can't see the check for (a)... ToDo!
+ = mappM_ unknownSigErr (filter bad sigs)
+ where
+ bad sig = not (ok_sig sig) &&
+ case sigName sig of
+ Just n | isUnboundName n -> False
+ -- Don't complain about an unbound name again
+ other -> True
--- We use lookupOccRn in the signatures, which is a little bit unsatisfactory
+-- We use lookupSigOccRn in the signatures, which is a little bit unsatisfactory
-- because this won't work for:
-- instance Foo T where
-- {-# INLINE op #-}
-- is in scope. (I'm assuming that Baz.op isn't in scope unqualified.)
-- Doesn't seem worth much trouble to sort this.
-renameSig :: Sig RdrName -> RnMS (Sig Name, FreeVars)
-
-renameSig (Sig v ty src_loc)
- = pushSrcLocRn src_loc $
- lookupOccRn v `thenRn` \ new_v ->
- rnHsSigType (quotes (ppr v)) ty `thenRn` \ (new_ty,fvs) ->
- returnRn (Sig new_v new_ty src_loc, fvs `addOneFV` new_v)
-
-renameSig (SpecInstSig ty src_loc)
- = pushSrcLocRn src_loc $
- rnHsSigType (text "A SPECIALISE instance pragma") ty `thenRn` \ (new_ty, fvs) ->
- returnRn (SpecInstSig new_ty src_loc, fvs)
-
-renameSig (SpecSig v ty src_loc)
- = pushSrcLocRn src_loc $
- lookupOccRn v `thenRn` \ new_v ->
- rnHsSigType (quotes (ppr v)) ty `thenRn` \ (new_ty,fvs) ->
- returnRn (SpecSig new_v new_ty src_loc, fvs `addOneFV` new_v)
-
-renameSig (FixSig (FixitySig v fix src_loc))
- = pushSrcLocRn src_loc $
- lookupOccRn v `thenRn` \ new_v ->
- returnRn (FixSig (FixitySig new_v fix src_loc), unitFV new_v)
-
-renameSig (DeprecSig (Deprecation ie txt) src_loc)
- = pushSrcLocRn src_loc $
- renameIE lookupOccRn ie `thenRn` \ (new_ie, fvs) ->
- returnRn (DeprecSig (Deprecation new_ie txt) src_loc, fvs)
-
-renameSig (InlineSig v p src_loc)
- = pushSrcLocRn src_loc $
- lookupOccRn v `thenRn` \ new_v ->
- returnRn (InlineSig new_v p src_loc, unitFV new_v)
-
-renameSig (NoInlineSig v p src_loc)
- = pushSrcLocRn src_loc $
- lookupOccRn v `thenRn` \ new_v ->
- returnRn (NoInlineSig new_v p src_loc, unitFV new_v)
-\end{code}
-
-\begin{code}
-renameIE :: (RdrName -> RnMS Name) -> IE RdrName -> RnMS (IE Name, FreeVars)
-renameIE lookup_occ_nm (IEVar v)
- = lookup_occ_nm v `thenRn` \ new_v ->
- returnRn (IEVar new_v, unitFV new_v)
-
-renameIE lookup_occ_nm (IEThingAbs v)
- = lookup_occ_nm v `thenRn` \ new_v ->
- returnRn (IEThingAbs new_v, unitFV new_v)
-
-renameIE lookup_occ_nm (IEThingAll v)
- = lookup_occ_nm v `thenRn` \ new_v ->
- returnRn (IEThingAll new_v, unitFV new_v)
-
-renameIE lookup_occ_nm (IEThingWith v vs)
- = lookup_occ_nm v `thenRn` \ new_v ->
- mapRn lookup_occ_nm vs `thenRn` \ new_vs ->
- returnRn (IEThingWith new_v new_vs, plusFVs [ unitFV x | x <- new_v:new_vs ])
-
-renameIE lookup_occ_nm (IEModuleContents m)
- = returnRn (IEModuleContents m, emptyFVs)
+renameSigs :: [LSig RdrName] -> RnM [LSig Name]
+renameSigs sigs = mappM (wrapLocM renameSig) (filter (not . isFixityLSig) sigs)
+ -- Remove fixity sigs which have been dealt with already
+
+renameSig :: Sig RdrName -> RnM (Sig Name)
+-- FixitSig is renamed elsewhere.
+renameSig (Sig v ty)
+ = lookupLocatedSigOccRn v `thenM` \ new_v ->
+ rnHsSigType (quotes (ppr v)) ty `thenM` \ new_ty ->
+ returnM (Sig new_v new_ty)
+
+renameSig (SpecInstSig ty)
+ = rnLHsType (text "A SPECIALISE instance pragma") ty `thenM` \ new_ty ->
+ returnM (SpecInstSig new_ty)
+
+renameSig (SpecSig v ty)
+ = lookupLocatedSigOccRn v `thenM` \ new_v ->
+ rnHsSigType (quotes (ppr v)) ty `thenM` \ new_ty ->
+ returnM (SpecSig new_v new_ty)
+
+renameSig (InlineSig b v p)
+ = lookupLocatedSigOccRn v `thenM` \ new_v ->
+ returnM (InlineSig b new_v p)
\end{code}
%************************************************************************
\begin{code}
-dupSigDeclErr (sig:sigs)
- = pushSrcLocRn loc $
- addErrRn (sep [ptext SLIT("Duplicate") <+> ptext what_it_is <> colon,
- ppr sig])
+dupSigDeclErr (L loc sig) sigs
+ = addErrAt loc $
+ vcat [ptext SLIT("Duplicate") <+> what_it_is <> colon,
+ nest 2 (vcat (map ppr_sig (L loc sig:sigs)))]
where
- (what_it_is, loc) = hsSigDoc sig
+ what_it_is = hsSigDoc sig
+ ppr_sig (L loc sig) = ppr loc <> colon <+> ppr sig
-unknownSigErr sig
- = pushSrcLocRn loc $
- addErrRn (sep [ptext SLIT("Misplaced") <+> ptext what_it_is <> colon,
- ppr sig])
+unknownSigErr (L loc sig)
+ = addErrAt loc $
+ sep [ptext SLIT("Misplaced") <+> what_it_is <> colon, ppr sig]
where
- (what_it_is, loc) = hsSigDoc sig
+ what_it_is = hsSigDoc sig
missingSigWarn var
- = sep [ptext SLIT("definition but no type signature for"), quotes (ppr var)]
+ = addWarnAt (mkSrcSpan loc loc) $
+ sep [ptext SLIT("Definition but no type signature for"), quotes (ppr var)]
+ where
+ loc = nameSrcLoc var -- TODO: make a proper span
methodBindErr mbind
- = hang (ptext SLIT("Can't handle multiple methods defined by one pattern binding"))
- 4 (ppr mbind)
+ = hang (ptext SLIT("Pattern bindings (except simple variables) not allowed in instance declarations"))
+ 2 (ppr mbind)
+
+bindsInHsBootFile mbinds
+ = hang (ptext SLIT("Bindings in hs-boot files are not allowed"))
+ 2 (ppr mbinds)
\end{code}