summaryrefslogtreecommitdiff
path: root/compiler/rename
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rename')
-rw-r--r--compiler/rename/RnBinds.hs1334
-rw-r--r--compiler/rename/RnEnv.hs1702
-rw-r--r--compiler/rename/RnExpr.hs2210
-rw-r--r--compiler/rename/RnExpr.hs-boot17
-rw-r--r--compiler/rename/RnFixity.hs214
-rw-r--r--compiler/rename/RnHsDoc.hs25
-rw-r--r--compiler/rename/RnNames.hs1783
-rw-r--r--compiler/rename/RnPat.hs897
-rw-r--r--compiler/rename/RnSource.hs2415
-rw-r--r--compiler/rename/RnSplice.hs902
-rw-r--r--compiler/rename/RnSplice.hs-boot14
-rw-r--r--compiler/rename/RnTypes.hs1784
-rw-r--r--compiler/rename/RnUnbound.hs381
-rw-r--r--compiler/rename/RnUtils.hs514
-rw-r--r--compiler/rename/rename.tex18
15 files changed, 0 insertions, 14210 deletions
diff --git a/compiler/rename/RnBinds.hs b/compiler/rename/RnBinds.hs
deleted file mode 100644
index 9b93af907b..0000000000
--- a/compiler/rename/RnBinds.hs
+++ /dev/null
@@ -1,1334 +0,0 @@
-{-# LANGUAGE ScopedTypeVariables, BangPatterns #-}
-{-# LANGUAGE TypeFamilies #-}
-
-{-
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-\section[RnBinds]{Renaming and dependency analysis of bindings}
-
-This module does renaming and dependency analysis on value bindings in
-the abstract syntax. It does {\em not} do cycle-checks on class or
-type-synonym declarations; those cannot be done at this stage because
-they may be affected by renaming (which isn't fully worked out yet).
--}
-
-module RnBinds (
- -- Renaming top-level bindings
- rnTopBindsLHS, rnTopBindsBoot, rnValBindsRHS,
-
- -- Renaming local bindings
- rnLocalBindsAndThen, rnLocalValBindsLHS, rnLocalValBindsRHS,
-
- -- Other bindings
- rnMethodBinds, renameSigs,
- rnMatchGroup, rnGRHSs, rnGRHS, rnSrcFixityDecl,
- makeMiniFixityEnv, MiniFixityEnv,
- HsSigCtxt(..)
- ) where
-
-import GhcPrelude
-
-import {-# SOURCE #-} RnExpr( rnLExpr, rnStmts )
-
-import GHC.Hs
-import TcRnMonad
-import RnTypes
-import RnPat
-import RnNames
-import RnEnv
-import RnFixity
-import RnUtils ( HsDocContext(..), mapFvRn, extendTyVarEnvFVRn
- , checkDupRdrNames, warnUnusedLocalBinds,
- checkUnusedRecordWildcard
- , checkDupAndShadowedNames, bindLocalNamesFV )
-import DynFlags
-import Module
-import Name
-import NameEnv
-import NameSet
-import RdrName ( RdrName, rdrNameOcc )
-import SrcLoc
-import ListSetOps ( findDupsEq )
-import BasicTypes ( RecFlag(..), TypeOrKind(..) )
-import Digraph ( SCC(..) )
-import Bag
-import Util
-import Outputable
-import UniqSet
-import Maybes ( orElse )
-import OrdList
-import qualified GHC.LanguageExtensions as LangExt
-
-import Control.Monad
-import Data.Foldable ( toList )
-import Data.List ( partition, sort )
-import Data.List.NonEmpty ( NonEmpty(..) )
-
-{-
--- ToDo: Put the annotations into the monad, so that they arrive in the proper
--- place and can be used when complaining.
-
-The code tree received by the function @rnBinds@ contains definitions
-in where-clauses which are all apparently mutually recursive, but which may
-not really depend upon each other. For example, in the top level program
-\begin{verbatim}
-f x = y where a = x
- y = x
-\end{verbatim}
-the definitions of @a@ and @y@ do not depend on each other at all.
-Unfortunately, the typechecker cannot always check such definitions.
-\footnote{Mycroft, A. 1984. Polymorphic type schemes and recursive
-definitions. In Proceedings of the International Symposium on Programming,
-Toulouse, pp. 217-39. LNCS 167. Springer Verlag.}
-However, the typechecker usually can check definitions in which only the
-strongly connected components have been collected into recursive bindings.
-This is precisely what the function @rnBinds@ does.
-
-ToDo: deal with case where a single monobinds binds the same variable
-twice.
-
-The vertag tag is a unique @Int@; the tags only need to be unique
-within one @MonoBinds@, so that unique-Int plumbing is done explicitly
-(heavy monad machinery not needed).
-
-
-************************************************************************
-* *
-* naming conventions *
-* *
-************************************************************************
-
-\subsection[name-conventions]{Name conventions}
-
-The basic algorithm involves walking over the tree and returning a tuple
-containing the new tree plus its free variables. Some functions, such
-as those walking polymorphic bindings (HsBinds) and qualifier lists in
-list comprehensions (@Quals@), return the variables bound in local
-environments. These are then used to calculate the free variables of the
-expression evaluated in these environments.
-
-Conventions for variable names are as follows:
-\begin{itemize}
-\item
-new code is given a prime to distinguish it from the old.
-
-\item
-a set of variables defined in @Exp@ is written @dvExp@
-
-\item
-a set of variables free in @Exp@ is written @fvExp@
-\end{itemize}
-
-************************************************************************
-* *
-* analysing polymorphic bindings (HsBindGroup, HsBind)
-* *
-************************************************************************
-
-\subsubsection[dep-HsBinds]{Polymorphic bindings}
-
-Non-recursive expressions are reconstructed without any changes at top
-level, although their component expressions may have to be altered.
-However, non-recursive expressions are currently not expected as
-\Haskell{} programs, and this code should not be executed.
-
-Monomorphic bindings contain information that is returned in a tuple
-(a @FlatMonoBinds@) containing:
-
-\begin{enumerate}
-\item
-a unique @Int@ that serves as the ``vertex tag'' for this binding.
-
-\item
-the name of a function or the names in a pattern. These are a set
-referred to as @dvLhs@, the defined variables of the left hand side.
-
-\item
-the free variables of the body. These are referred to as @fvBody@.
-
-\item
-the definition's actual code. This is referred to as just @code@.
-\end{enumerate}
-
-The function @nonRecDvFv@ returns two sets of variables. The first is
-the set of variables defined in the set of monomorphic bindings, while the
-second is the set of free variables in those bindings.
-
-The set of variables defined in a non-recursive binding is just the
-union of all of them, as @union@ removes duplicates. However, the
-free variables in each successive set of cumulative bindings is the
-union of those in the previous set plus those of the newest binding after
-the defined variables of the previous set have been removed.
-
-@rnMethodBinds@ deals only with the declarations in class and
-instance declarations. It expects only to see @FunMonoBind@s, and
-it expects the global environment to contain bindings for the binders
-(which are all class operations).
-
-************************************************************************
-* *
-\subsubsection{ Top-level bindings}
-* *
-************************************************************************
--}
-
--- for top-level bindings, we need to make top-level names,
--- so we have a different entry point than for local bindings
-rnTopBindsLHS :: MiniFixityEnv
- -> HsValBinds GhcPs
- -> RnM (HsValBindsLR GhcRn GhcPs)
-rnTopBindsLHS fix_env binds
- = rnValBindsLHS (topRecNameMaker fix_env) binds
-
-rnTopBindsBoot :: NameSet -> HsValBindsLR GhcRn GhcPs
- -> RnM (HsValBinds GhcRn, DefUses)
--- A hs-boot file has no bindings.
--- Return a single HsBindGroup with empty binds and renamed signatures
-rnTopBindsBoot bound_names (ValBinds _ mbinds sigs)
- = do { checkErr (isEmptyLHsBinds mbinds) (bindsInHsBootFile mbinds)
- ; (sigs', fvs) <- renameSigs (HsBootCtxt bound_names) sigs
- ; return (XValBindsLR (NValBinds [] sigs'), usesOnly fvs) }
-rnTopBindsBoot _ b = pprPanic "rnTopBindsBoot" (ppr b)
-
-{-
-*********************************************************
-* *
- HsLocalBinds
-* *
-*********************************************************
--}
-
-rnLocalBindsAndThen :: HsLocalBinds GhcPs
- -> (HsLocalBinds GhcRn -> FreeVars -> RnM (result, FreeVars))
- -> RnM (result, FreeVars)
--- This version (a) assumes that the binding vars are *not* already in scope
--- (b) removes the binders from the free vars of the thing inside
--- The parser doesn't produce ThenBinds
-rnLocalBindsAndThen (EmptyLocalBinds x) thing_inside =
- thing_inside (EmptyLocalBinds x) emptyNameSet
-
-rnLocalBindsAndThen (HsValBinds x val_binds) thing_inside
- = rnLocalValBindsAndThen val_binds $ \ val_binds' ->
- thing_inside (HsValBinds x val_binds')
-
-rnLocalBindsAndThen (HsIPBinds x binds) thing_inside = do
- (binds',fv_binds) <- rnIPBinds binds
- (thing, fvs_thing) <- thing_inside (HsIPBinds x binds') fv_binds
- return (thing, fvs_thing `plusFV` fv_binds)
-
-rnLocalBindsAndThen (XHsLocalBindsLR nec) _ = noExtCon nec
-
-rnIPBinds :: HsIPBinds GhcPs -> RnM (HsIPBinds GhcRn, FreeVars)
-rnIPBinds (IPBinds _ ip_binds ) = do
- (ip_binds', fvs_s) <- mapAndUnzipM (wrapLocFstM rnIPBind) ip_binds
- return (IPBinds noExtField ip_binds', plusFVs fvs_s)
-rnIPBinds (XHsIPBinds nec) = noExtCon nec
-
-rnIPBind :: IPBind GhcPs -> RnM (IPBind GhcRn, FreeVars)
-rnIPBind (IPBind _ ~(Left n) expr) = do
- (expr',fvExpr) <- rnLExpr expr
- return (IPBind noExtField (Left n) expr', fvExpr)
-rnIPBind (XIPBind nec) = noExtCon nec
-
-{-
-************************************************************************
-* *
- ValBinds
-* *
-************************************************************************
--}
-
--- Renaming local binding groups
--- Does duplicate/shadow check
-rnLocalValBindsLHS :: MiniFixityEnv
- -> HsValBinds GhcPs
- -> RnM ([Name], HsValBindsLR GhcRn GhcPs)
-rnLocalValBindsLHS fix_env binds
- = do { binds' <- rnValBindsLHS (localRecNameMaker fix_env) binds
-
- -- Check for duplicates and shadowing
- -- Must do this *after* renaming the patterns
- -- See Note [Collect binders only after renaming] in GHC.Hs.Utils
-
- -- We need to check for dups here because we
- -- don't don't bind all of the variables from the ValBinds at once
- -- with bindLocatedLocals any more.
- --
- -- Note that we don't want to do this at the top level, since
- -- sorting out duplicates and shadowing there happens elsewhere.
- -- The behavior is even different. For example,
- -- import A(f)
- -- f = ...
- -- should not produce a shadowing warning (but it will produce
- -- an ambiguity warning if you use f), but
- -- import A(f)
- -- g = let f = ... in f
- -- should.
- ; let bound_names = collectHsValBinders binds'
- -- There should be only Ids, but if there are any bogus
- -- pattern synonyms, we'll collect them anyway, so that
- -- we don't generate subsequent out-of-scope messages
- ; envs <- getRdrEnvs
- ; checkDupAndShadowedNames envs bound_names
-
- ; return (bound_names, binds') }
-
--- renames the left-hand sides
--- generic version used both at the top level and for local binds
--- does some error checking, but not what gets done elsewhere at the top level
-rnValBindsLHS :: NameMaker
- -> HsValBinds GhcPs
- -> RnM (HsValBindsLR GhcRn GhcPs)
-rnValBindsLHS topP (ValBinds x mbinds sigs)
- = do { mbinds' <- mapBagM (wrapLocM (rnBindLHS topP doc)) mbinds
- ; return $ ValBinds x mbinds' sigs }
- where
- bndrs = collectHsBindsBinders mbinds
- doc = text "In the binding group for:" <+> pprWithCommas ppr bndrs
-
-rnValBindsLHS _ b = pprPanic "rnValBindsLHSFromDoc" (ppr b)
-
--- General version used both from the top-level and for local things
--- Assumes the LHS vars are in scope
---
--- Does not bind the local fixity declarations
-rnValBindsRHS :: HsSigCtxt
- -> HsValBindsLR GhcRn GhcPs
- -> RnM (HsValBinds GhcRn, DefUses)
-
-rnValBindsRHS ctxt (ValBinds _ mbinds sigs)
- = do { (sigs', sig_fvs) <- renameSigs ctxt sigs
- ; binds_w_dus <- mapBagM (rnLBind (mkScopedTvFn sigs')) mbinds
- ; let !(anal_binds, anal_dus) = depAnalBinds binds_w_dus
-
- ; let patsyn_fvs = foldr (unionNameSet . psb_ext) emptyNameSet $
- getPatSynBinds anal_binds
- -- The uses in binds_w_dus for PatSynBinds do not include
- -- variables used in the patsyn builders; see
- -- Note [Pattern synonym builders don't yield dependencies]
- -- But psb_fvs /does/ include those builder fvs. So we
- -- add them back in here to avoid bogus warnings about
- -- unused variables (#12548)
-
- valbind'_dus = anal_dus `plusDU` usesOnly sig_fvs
- `plusDU` usesOnly patsyn_fvs
- -- Put the sig uses *after* the bindings
- -- so that the binders are removed from
- -- the uses in the sigs
-
- ; return (XValBindsLR (NValBinds anal_binds sigs'), valbind'_dus) }
-
-rnValBindsRHS _ b = pprPanic "rnValBindsRHS" (ppr b)
-
--- Wrapper for local binds
---
--- The *client* of this function is responsible for checking for unused binders;
--- it doesn't (and can't: we don't have the thing inside the binds) happen here
---
--- The client is also responsible for bringing the fixities into scope
-rnLocalValBindsRHS :: NameSet -- names bound by the LHSes
- -> HsValBindsLR GhcRn GhcPs
- -> RnM (HsValBinds GhcRn, DefUses)
-rnLocalValBindsRHS bound_names binds
- = rnValBindsRHS (LocalBindCtxt bound_names) binds
-
--- for local binds
--- wrapper that does both the left- and right-hand sides
---
--- here there are no local fixity decls passed in;
--- the local fixity decls come from the ValBinds sigs
-rnLocalValBindsAndThen
- :: HsValBinds GhcPs
- -> (HsValBinds GhcRn -> FreeVars -> RnM (result, FreeVars))
- -> RnM (result, FreeVars)
-rnLocalValBindsAndThen binds@(ValBinds _ _ sigs) thing_inside
- = do { -- (A) Create the local fixity environment
- new_fixities <- makeMiniFixityEnv [ L loc sig
- | L loc (FixSig _ sig) <- sigs]
-
- -- (B) Rename the LHSes
- ; (bound_names, new_lhs) <- rnLocalValBindsLHS new_fixities binds
-
- -- ...and bring them (and their fixities) into scope
- ; bindLocalNamesFV bound_names $
- addLocalFixities new_fixities bound_names $ do
-
- { -- (C) Do the RHS and thing inside
- (binds', dus) <- rnLocalValBindsRHS (mkNameSet bound_names) new_lhs
- ; (result, result_fvs) <- thing_inside binds' (allUses dus)
-
- -- Report unused bindings based on the (accurate)
- -- findUses. E.g.
- -- let x = x in 3
- -- should report 'x' unused
- ; let real_uses = findUses dus result_fvs
- -- Insert fake uses for variables introduced implicitly by
- -- wildcards (#4404)
- rec_uses = hsValBindsImplicits binds'
- implicit_uses = mkNameSet $ concatMap snd
- $ rec_uses
- ; mapM_ (\(loc, ns) ->
- checkUnusedRecordWildcard loc real_uses (Just ns))
- rec_uses
- ; warnUnusedLocalBinds bound_names
- (real_uses `unionNameSet` implicit_uses)
-
- ; let
- -- The variables "used" in the val binds are:
- -- (1) the uses of the binds (allUses)
- -- (2) the FVs of the thing-inside
- all_uses = allUses dus `plusFV` result_fvs
- -- Note [Unused binding hack]
- -- ~~~~~~~~~~~~~~~~~~~~~~~~~~
- -- Note that *in contrast* to the above reporting of
- -- unused bindings, (1) above uses duUses to return *all*
- -- the uses, even if the binding is unused. 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
- --
- -- But note that this means we won't report 'x' as unused,
- -- whereas we would if we had { x = 3; p = x; y = 'x' }
-
- ; return (result, all_uses) }}
- -- The bound names are pruned out of all_uses
- -- by the bindLocalNamesFV call above
-
-rnLocalValBindsAndThen bs _ = pprPanic "rnLocalValBindsAndThen" (ppr bs)
-
-
----------------------
-
--- renaming a single bind
-
-rnBindLHS :: NameMaker
- -> SDoc
- -> HsBind GhcPs
- -- returns the renamed left-hand side,
- -- and the FreeVars *of the LHS*
- -- (i.e., any free variables of the pattern)
- -> RnM (HsBindLR GhcRn GhcPs)
-
-rnBindLHS name_maker _ bind@(PatBind { pat_lhs = pat })
- = do
- -- we don't actually use the FV processing of rnPatsAndThen here
- (pat',pat'_fvs) <- rnBindPat name_maker pat
- return (bind { pat_lhs = pat', pat_ext = pat'_fvs })
- -- We temporarily store the pat's FVs in bind_fvs;
- -- gets updated to the FVs of the whole bind
- -- when doing the RHS below
-
-rnBindLHS name_maker _ bind@(FunBind { fun_id = rdr_name })
- = do { name <- applyNameMaker name_maker rdr_name
- ; return (bind { fun_id = name
- , fun_ext = noExtField }) }
-
-rnBindLHS name_maker _ (PatSynBind x psb@PSB{ psb_id = rdrname })
- | isTopRecNameMaker name_maker
- = do { addLocM checkConName rdrname
- ; name <- lookupLocatedTopBndrRn rdrname -- Should be in scope already
- ; return (PatSynBind x psb{ psb_ext = noExtField, psb_id = name }) }
-
- | otherwise -- Pattern synonym, not at top level
- = do { addErr localPatternSynonymErr -- Complain, but make up a fake
- -- name so that we can carry on
- ; name <- applyNameMaker name_maker rdrname
- ; return (PatSynBind x psb{ psb_ext = noExtField, psb_id = name }) }
- where
- localPatternSynonymErr :: SDoc
- localPatternSynonymErr
- = hang (text "Illegal pattern synonym declaration for" <+> quotes (ppr rdrname))
- 2 (text "Pattern synonym declarations are only valid at top level")
-
-rnBindLHS _ _ b = pprPanic "rnBindHS" (ppr b)
-
-rnLBind :: (Name -> [Name]) -- Signature tyvar function
- -> LHsBindLR GhcRn GhcPs
- -> RnM (LHsBind GhcRn, [Name], Uses)
-rnLBind sig_fn (L loc bind)
- = setSrcSpan loc $
- do { (bind', bndrs, dus) <- rnBind sig_fn bind
- ; return (L loc bind', bndrs, dus) }
-
--- assumes the left-hands-side vars are in scope
-rnBind :: (Name -> [Name]) -- Signature tyvar function
- -> HsBindLR GhcRn GhcPs
- -> RnM (HsBind GhcRn, [Name], Uses)
-rnBind _ bind@(PatBind { pat_lhs = pat
- , pat_rhs = grhss
- -- pat fvs were stored in bind_fvs
- -- after processing the LHS
- , pat_ext = pat_fvs })
- = do { mod <- getModule
- ; (grhss', rhs_fvs) <- rnGRHSs PatBindRhs rnLExpr grhss
-
- -- No scoped type variables for pattern bindings
- ; let all_fvs = pat_fvs `plusFV` rhs_fvs
- fvs' = filterNameSet (nameIsLocalOrFrom mod) all_fvs
- -- Keep locally-defined Names
- -- As well as dependency analysis, we need these for the
- -- MonoLocalBinds test in TcBinds.decideGeneralisationPlan
- bndrs = collectPatBinders pat
- bind' = bind { pat_rhs = grhss'
- , pat_ext = fvs' }
-
- ok_nobind_pat
- = -- See Note [Pattern bindings that bind no variables]
- case unLoc pat of
- WildPat {} -> True
- BangPat {} -> True -- #9127, #13646
- SplicePat {} -> True
- _ -> False
-
- -- Warn if the pattern binds no variables
- -- See Note [Pattern bindings that bind no variables]
- ; whenWOptM Opt_WarnUnusedPatternBinds $
- when (null bndrs && not ok_nobind_pat) $
- addWarn (Reason Opt_WarnUnusedPatternBinds) $
- unusedPatBindWarn bind'
-
- ; fvs' `seq` -- See Note [Free-variable space leak]
- return (bind', bndrs, all_fvs) }
-
-rnBind sig_fn bind@(FunBind { fun_id = name
- , fun_matches = matches })
- -- invariant: no free vars here when it's a FunBind
- = do { let plain_name = unLoc name
-
- ; (matches', rhs_fvs) <- bindSigTyVarsFV (sig_fn plain_name) $
- -- bindSigTyVars tests for LangExt.ScopedTyVars
- rnMatchGroup (mkPrefixFunRhs name)
- rnLExpr matches
- ; let is_infix = isInfixFunBind bind
- ; when is_infix $ checkPrecMatch plain_name matches'
-
- ; mod <- getModule
- ; let fvs' = filterNameSet (nameIsLocalOrFrom mod) rhs_fvs
- -- Keep locally-defined Names
- -- As well as dependency analysis, we need these for the
- -- MonoLocalBinds test in TcBinds.decideGeneralisationPlan
-
- ; fvs' `seq` -- See Note [Free-variable space leak]
- return (bind { fun_matches = matches'
- , fun_ext = fvs' },
- [plain_name], rhs_fvs)
- }
-
-rnBind sig_fn (PatSynBind x bind)
- = do { (bind', name, fvs) <- rnPatSynBind sig_fn bind
- ; return (PatSynBind x bind', name, fvs) }
-
-rnBind _ b = pprPanic "rnBind" (ppr b)
-
-{- Note [Pattern bindings that bind no variables]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Generally, we want to warn about pattern bindings like
- Just _ = e
-because they don't do anything! But we have three exceptions:
-
-* A wildcard pattern
- _ = rhs
- which (a) is not that different from _v = rhs
- (b) is sometimes used to give a type sig for,
- or an occurrence of, a variable on the RHS
-
-* A strict pattern binding; that is, one with an outermost bang
- !Just _ = e
- This can fail, so unlike the lazy variant, it is not a no-op.
- Moreover, #13646 argues that even for single constructor
- types, you might want to write the constructor. See also #9127.
-
-* A splice pattern
- $(th-lhs) = rhs
- It is impossible to determine whether or not th-lhs really
- binds any variable. We should disable the warning for any pattern
- which contain splices, but that is a more expensive check.
-
-Note [Free-variable space leak]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We have
- fvs' = trim fvs
-and we seq fvs' before turning it as part of a record.
-
-The reason is that trim is sometimes something like
- \xs -> intersectNameSet (mkNameSet bound_names) xs
-and we don't want to retain the list bound_names. This showed up in
-trac ticket #1136.
--}
-
-{- *********************************************************************
-* *
- Dependency analysis and other support functions
-* *
-********************************************************************* -}
-
-depAnalBinds :: Bag (LHsBind GhcRn, [Name], Uses)
- -> ([(RecFlag, LHsBinds GhcRn)], DefUses)
--- Dependency analysis; this is important so that
--- unused-binding reporting is accurate
-depAnalBinds binds_w_dus
- = (map get_binds sccs, toOL $ map get_du sccs)
- where
- sccs = depAnal (\(_, defs, _) -> defs)
- (\(_, _, uses) -> nonDetEltsUniqSet uses)
- -- It's OK to use nonDetEltsUniqSet here as explained in
- -- Note [depAnal determinism] in NameEnv.
- (bagToList binds_w_dus)
-
- get_binds (AcyclicSCC (bind, _, _)) = (NonRecursive, unitBag bind)
- get_binds (CyclicSCC binds_w_dus) = (Recursive, listToBag [b | (b,_,_) <- binds_w_dus])
-
- get_du (AcyclicSCC (_, bndrs, uses)) = (Just (mkNameSet bndrs), uses)
- get_du (CyclicSCC binds_w_dus) = (Just defs, uses)
- where
- defs = mkNameSet [b | (_,bs,_) <- binds_w_dus, b <- bs]
- uses = unionNameSets [u | (_,_,u) <- binds_w_dus]
-
----------------------
--- Bind the top-level forall'd type variables in the sigs.
--- E.g f :: forall a. a -> a
--- f = rhs
--- The 'a' scopes over the rhs
---
--- NB: there'll usually be just one (for a function binding)
--- but if there are many, one may shadow the rest; too bad!
--- e.g x :: forall a. [a] -> [a]
--- y :: forall a. [(a,a)] -> a
--- (x,y) = e
--- In e, 'a' will be in scope, and it'll be the one from 'y'!
-
-mkScopedTvFn :: [LSig GhcRn] -> (Name -> [Name])
--- Return a lookup function that maps an Id Name to the names
--- of the type variables that should scope over its body.
-mkScopedTvFn sigs = \n -> lookupNameEnv env n `orElse` []
- where
- env = mkHsSigEnv get_scoped_tvs sigs
-
- get_scoped_tvs :: LSig GhcRn -> Maybe ([Located Name], [Name])
- -- Returns (binders, scoped tvs for those binders)
- get_scoped_tvs (L _ (ClassOpSig _ _ names sig_ty))
- = Just (names, hsScopedTvs sig_ty)
- get_scoped_tvs (L _ (TypeSig _ names sig_ty))
- = Just (names, hsWcScopedTvs sig_ty)
- get_scoped_tvs (L _ (PatSynSig _ names sig_ty))
- = Just (names, hsScopedTvs sig_ty)
- get_scoped_tvs _ = Nothing
-
--- Process the fixity declarations, making a FastString -> (Located Fixity) map
--- (We keep the location around for reporting duplicate fixity declarations.)
---
--- Checks for duplicates, but not that only locally defined things are fixed.
--- Note: for local fixity declarations, duplicates would also be checked in
--- check_sigs below. But we also use this function at the top level.
-
-makeMiniFixityEnv :: [LFixitySig GhcPs] -> RnM MiniFixityEnv
-
-makeMiniFixityEnv decls = foldlM add_one_sig emptyFsEnv decls
- where
- add_one_sig env (L loc (FixitySig _ names fixity)) =
- foldlM add_one env [ (loc,name_loc,name,fixity)
- | L name_loc name <- names ]
- add_one_sig _ (L _ (XFixitySig nec)) = noExtCon nec
-
- add_one env (loc, name_loc, name,fixity) = do
- { -- this fixity decl is a duplicate iff
- -- the ReaderName's OccName's FastString is already in the env
- -- (we only need to check the local fix_env because
- -- definitions of non-local will be caught elsewhere)
- let { fs = occNameFS (rdrNameOcc name)
- ; fix_item = L loc fixity };
-
- case lookupFsEnv env fs of
- Nothing -> return $ extendFsEnv env fs fix_item
- Just (L loc' _) -> do
- { setSrcSpan loc $
- addErrAt name_loc (dupFixityDecl loc' name)
- ; return env}
- }
-
-dupFixityDecl :: SrcSpan -> RdrName -> SDoc
-dupFixityDecl loc rdr_name
- = vcat [text "Multiple fixity declarations for" <+> quotes (ppr rdr_name),
- text "also at " <+> ppr loc]
-
-
-{- *********************************************************************
-* *
- Pattern synonym bindings
-* *
-********************************************************************* -}
-
-rnPatSynBind :: (Name -> [Name]) -- Signature tyvar function
- -> PatSynBind GhcRn GhcPs
- -> RnM (PatSynBind GhcRn GhcRn, [Name], Uses)
-rnPatSynBind sig_fn bind@(PSB { psb_id = L l name
- , psb_args = details
- , psb_def = pat
- , psb_dir = dir })
- -- invariant: no free vars here when it's a FunBind
- = do { pattern_synonym_ok <- xoptM LangExt.PatternSynonyms
- ; unless pattern_synonym_ok (addErr patternSynonymErr)
- ; let scoped_tvs = sig_fn name
-
- ; ((pat', details'), fvs1) <- bindSigTyVarsFV scoped_tvs $
- rnPat PatSyn pat $ \pat' ->
- -- We check the 'RdrName's instead of the 'Name's
- -- so that the binding locations are reported
- -- from the left-hand side
- case details of
- PrefixCon vars ->
- do { checkDupRdrNames vars
- ; names <- mapM lookupPatSynBndr vars
- ; return ( (pat', PrefixCon names)
- , mkFVs (map unLoc names)) }
- InfixCon var1 var2 ->
- do { checkDupRdrNames [var1, var2]
- ; name1 <- lookupPatSynBndr var1
- ; name2 <- lookupPatSynBndr var2
- -- ; checkPrecMatch -- TODO
- ; return ( (pat', InfixCon name1 name2)
- , mkFVs (map unLoc [name1, name2])) }
- RecCon vars ->
- do { checkDupRdrNames (map recordPatSynSelectorId vars)
- ; let rnRecordPatSynField
- (RecordPatSynField { recordPatSynSelectorId = visible
- , recordPatSynPatVar = hidden })
- = do { visible' <- lookupLocatedTopBndrRn visible
- ; hidden' <- lookupPatSynBndr hidden
- ; return $ RecordPatSynField { recordPatSynSelectorId = visible'
- , recordPatSynPatVar = hidden' } }
- ; names <- mapM rnRecordPatSynField vars
- ; return ( (pat', RecCon names)
- , mkFVs (map (unLoc . recordPatSynPatVar) names)) }
-
- ; (dir', fvs2) <- case dir of
- Unidirectional -> return (Unidirectional, emptyFVs)
- ImplicitBidirectional -> return (ImplicitBidirectional, emptyFVs)
- ExplicitBidirectional mg ->
- do { (mg', fvs) <- bindSigTyVarsFV scoped_tvs $
- rnMatchGroup (mkPrefixFunRhs (L l name))
- rnLExpr mg
- ; return (ExplicitBidirectional mg', fvs) }
-
- ; mod <- getModule
- ; let fvs = fvs1 `plusFV` fvs2
- fvs' = filterNameSet (nameIsLocalOrFrom mod) fvs
- -- Keep locally-defined Names
- -- As well as dependency analysis, we need these for the
- -- MonoLocalBinds test in TcBinds.decideGeneralisationPlan
-
- bind' = bind{ psb_args = details'
- , psb_def = pat'
- , psb_dir = dir'
- , psb_ext = fvs' }
- selector_names = case details' of
- RecCon names ->
- map (unLoc . recordPatSynSelectorId) names
- _ -> []
-
- ; fvs' `seq` -- See Note [Free-variable space leak]
- return (bind', name : selector_names , fvs1)
- -- Why fvs1? See Note [Pattern synonym builders don't yield dependencies]
- }
- where
- -- See Note [Renaming pattern synonym variables]
- lookupPatSynBndr = wrapLocM lookupLocalOccRn
-
- patternSynonymErr :: SDoc
- patternSynonymErr
- = hang (text "Illegal pattern synonym declaration")
- 2 (text "Use -XPatternSynonyms to enable this extension")
-
-rnPatSynBind _ (XPatSynBind nec) = noExtCon nec
-
-{-
-Note [Renaming pattern synonym variables]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-We rename pattern synonym declaractions backwards to normal to reuse
-the logic already implemented for renaming patterns.
-
-We first rename the RHS of a declaration which brings into
-scope the variables bound by the pattern (as they would be
-in normal function definitions). We then lookup the variables
-which we want to bind in this local environment.
-
-It is crucial that we then only lookup in the *local* environment which
-only contains the variables brought into scope by the pattern and nothing
-else. Amazingly no-one encountered this bug for 3 GHC versions but
-it was possible to define a pattern synonym which referenced global
-identifiers and worked correctly.
-
-```
-x = 5
-
-pattern P :: Int -> ()
-pattern P x <- _
-
-f (P x) = x
-
-> f () = 5
-```
-
-See #13470 for the original report.
-
-Note [Pattern synonym builders don't yield dependencies]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When renaming a pattern synonym that has an explicit builder,
-references in the builder definition should not be used when
-calculating dependencies. For example, consider the following pattern
-synonym definition:
-
-pattern P x <- C1 x where
- P x = f (C1 x)
-
-f (P x) = C2 x
-
-In this case, 'P' needs to be typechecked in two passes:
-
-1. Typecheck the pattern definition of 'P', which fully determines the
- type of 'P'. This step doesn't require knowing anything about 'f',
- since the builder definition is not looked at.
-
-2. Typecheck the builder definition, which needs the typechecked
- definition of 'f' to be in scope; done by calls oo tcPatSynBuilderBind
- in TcBinds.tcValBinds.
-
-This behaviour is implemented in 'tcValBinds', but it crucially
-depends on 'P' not being put in a recursive group with 'f' (which
-would make it look like a recursive pattern synonym a la 'pattern P =
-P' which is unsound and rejected).
-
-So:
- * We do not include builder fvs in the Uses returned by rnPatSynBind
- (which is then used for dependency analysis)
- * But we /do/ include them in the psb_fvs for the PatSynBind
- * In rnValBinds we record these builder uses, to avoid bogus
- unused-variable warnings (#12548)
--}
-
-{- *********************************************************************
-* *
- Class/instance method bindings
-* *
-********************************************************************* -}
-
-{- @rnMethodBinds@ is used for the method bindings of a class and an instance
-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:
-\begin{verbatim}
- instance Foo (T a) where
- op x = ...
-\end{verbatim}
-This might be the {\em sole} occurrence of @op@ for an imported class @Foo@,
-and unless @op@ occurs we won't treat the type signature of @op@ in the class
-decl for @Foo@ as a source of instance-decl gates. But we should! Indeed,
-in many ways the @op@ in an instance decl is just like an occurrence, not
-a binder.
--}
-
-rnMethodBinds :: Bool -- True <=> is a class declaration
- -> Name -- Class name
- -> [Name] -- Type variables from the class/instance header
- -> LHsBinds GhcPs -- Binds
- -> [LSig GhcPs] -- and signatures/pragmas
- -> RnM (LHsBinds GhcRn, [LSig GhcRn], FreeVars)
--- Used for
--- * the default method bindings in a class decl
--- * the method bindings in an instance decl
-rnMethodBinds is_cls_decl cls ktv_names binds sigs
- = do { checkDupRdrNames (collectMethodBinders binds)
- -- Check that the same method is not given twice in the
- -- same instance decl instance C T where
- -- f x = ...
- -- g y = ...
- -- f x = ...
- -- We must use checkDupRdrNames because the Name of the
- -- method is the Name of the class selector, whose SrcSpan
- -- points to the class declaration; and we use rnMethodBinds
- -- for instance decls too
-
- -- Rename the bindings LHSs
- ; binds' <- foldrM (rnMethodBindLHS is_cls_decl cls) emptyBag binds
-
- -- Rename the pragmas and signatures
- -- Annoyingly the type variables /are/ in scope for signatures, but
- -- /are not/ in scope in the SPECIALISE instance pramas; e.g.
- -- instance Eq a => Eq (T a) where
- -- (==) :: a -> a -> a
- -- {-# SPECIALISE instance Eq a => Eq (T [a]) #-}
- ; let (spec_inst_prags, other_sigs) = partition isSpecInstLSig sigs
- bound_nms = mkNameSet (collectHsBindsBinders binds')
- sig_ctxt | is_cls_decl = ClsDeclCtxt cls
- | otherwise = InstDeclCtxt bound_nms
- ; (spec_inst_prags', sip_fvs) <- renameSigs sig_ctxt spec_inst_prags
- ; (other_sigs', sig_fvs) <- extendTyVarEnvFVRn ktv_names $
- renameSigs sig_ctxt other_sigs
-
- -- Rename the bindings RHSs. Again there's an issue about whether the
- -- type variables from the class/instance head are in scope.
- -- Answer no in Haskell 2010, but yes if you have -XScopedTypeVariables
- ; scoped_tvs <- xoptM LangExt.ScopedTypeVariables
- ; (binds'', bind_fvs) <- maybe_extend_tyvar_env scoped_tvs $
- do { binds_w_dus <- mapBagM (rnLBind (mkScopedTvFn other_sigs')) binds'
- ; let bind_fvs = foldr (\(_,_,fv1) fv2 -> fv1 `plusFV` fv2)
- emptyFVs binds_w_dus
- ; return (mapBag fstOf3 binds_w_dus, bind_fvs) }
-
- ; return ( binds'', spec_inst_prags' ++ other_sigs'
- , sig_fvs `plusFV` sip_fvs `plusFV` bind_fvs) }
- where
- -- For the method bindings in class and instance decls, we extend
- -- the type variable environment iff -XScopedTypeVariables
- maybe_extend_tyvar_env scoped_tvs thing_inside
- | scoped_tvs = extendTyVarEnvFVRn ktv_names thing_inside
- | otherwise = thing_inside
-
-rnMethodBindLHS :: Bool -> Name
- -> LHsBindLR GhcPs GhcPs
- -> LHsBindsLR GhcRn GhcPs
- -> RnM (LHsBindsLR GhcRn GhcPs)
-rnMethodBindLHS _ cls (L loc bind@(FunBind { fun_id = name })) rest
- = setSrcSpan loc $ do
- do { sel_name <- wrapLocM (lookupInstDeclBndr cls (text "method")) name
- -- We use the selector name as the binder
- ; let bind' = bind { fun_id = sel_name, fun_ext = noExtField }
- ; return (L loc bind' `consBag` rest ) }
-
--- Report error for all other forms of bindings
--- This is why we use a fold rather than map
-rnMethodBindLHS is_cls_decl _ (L loc bind) rest
- = do { addErrAt loc $
- vcat [ what <+> text "not allowed in" <+> decl_sort
- , nest 2 (ppr bind) ]
- ; return rest }
- where
- decl_sort | is_cls_decl = text "class declaration:"
- | otherwise = text "instance declaration:"
- what = case bind of
- PatBind {} -> text "Pattern bindings (except simple variables)"
- PatSynBind {} -> text "Pattern synonyms"
- -- Associated pattern synonyms are not implemented yet
- _ -> pprPanic "rnMethodBind" (ppr bind)
-
-{-
-************************************************************************
-* *
-\subsubsection[dep-Sigs]{Signatures (and user-pragmas for values)}
-* *
-************************************************************************
-
-@renameSigs@ checks for:
-\begin{enumerate}
-\item more than one sig for one thing;
-\item signatures given for things not bound here;
-\end{enumerate}
-
-At the moment we don't gather free-var info from the types in
-signatures. We'd only need this if we wanted to report unused tyvars.
--}
-
-renameSigs :: HsSigCtxt
- -> [LSig GhcPs]
- -> RnM ([LSig GhcRn], FreeVars)
--- Renames the signatures and performs error checks
-renameSigs ctxt sigs
- = do { mapM_ dupSigDeclErr (findDupSigs sigs)
-
- ; checkDupMinimalSigs sigs
-
- ; (sigs', sig_fvs) <- mapFvRn (wrapLocFstM (renameSig ctxt)) sigs
-
- ; let (good_sigs, bad_sigs) = partition (okHsSig ctxt) sigs'
- ; mapM_ misplacedSigErr bad_sigs -- Misplaced
-
- ; return (good_sigs, sig_fvs) }
-
-----------------------
--- We use lookupSigOccRn in the signatures, which is a little bit unsatisfactory
--- because this won't work for:
--- instance Foo T where
--- {-# INLINE op #-}
--- Baz.op = ...
--- We'll just rename the INLINE prag to refer to whatever other '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 :: HsSigCtxt -> Sig GhcPs -> RnM (Sig GhcRn, FreeVars)
-renameSig _ (IdSig _ x)
- = return (IdSig noExtField x, emptyFVs) -- Actually this never occurs
-
-renameSig ctxt sig@(TypeSig _ vs ty)
- = do { new_vs <- mapM (lookupSigOccRn ctxt sig) vs
- ; let doc = TypeSigCtx (ppr_sig_bndrs vs)
- ; (new_ty, fvs) <- rnHsSigWcType BindUnlessForall doc ty
- ; return (TypeSig noExtField new_vs new_ty, fvs) }
-
-renameSig ctxt sig@(ClassOpSig _ is_deflt vs ty)
- = do { defaultSigs_on <- xoptM LangExt.DefaultSignatures
- ; when (is_deflt && not defaultSigs_on) $
- addErr (defaultSigErr sig)
- ; new_v <- mapM (lookupSigOccRn ctxt sig) vs
- ; (new_ty, fvs) <- rnHsSigType ty_ctxt TypeLevel ty
- ; return (ClassOpSig noExtField is_deflt new_v new_ty, fvs) }
- where
- (v1:_) = vs
- ty_ctxt = GenericCtx (text "a class method signature for"
- <+> quotes (ppr v1))
-
-renameSig _ (SpecInstSig _ src ty)
- = do { (new_ty, fvs) <- rnHsSigType SpecInstSigCtx TypeLevel ty
- ; return (SpecInstSig noExtField src new_ty,fvs) }
-
--- {-# SPECIALISE #-} pragmas can refer to imported Ids
--- so, in the top-level case (when mb_names is Nothing)
--- we use lookupOccRn. If there's both an imported and a local 'f'
--- then the SPECIALISE pragma is ambiguous, unlike all other signatures
-renameSig ctxt sig@(SpecSig _ v tys inl)
- = do { new_v <- case ctxt of
- TopSigCtxt {} -> lookupLocatedOccRn v
- _ -> lookupSigOccRn ctxt sig v
- ; (new_ty, fvs) <- foldM do_one ([],emptyFVs) tys
- ; return (SpecSig noExtField new_v new_ty inl, fvs) }
- where
- ty_ctxt = GenericCtx (text "a SPECIALISE signature for"
- <+> quotes (ppr v))
- do_one (tys,fvs) ty
- = do { (new_ty, fvs_ty) <- rnHsSigType ty_ctxt TypeLevel ty
- ; return ( new_ty:tys, fvs_ty `plusFV` fvs) }
-
-renameSig ctxt sig@(InlineSig _ v s)
- = do { new_v <- lookupSigOccRn ctxt sig v
- ; return (InlineSig noExtField new_v s, emptyFVs) }
-
-renameSig ctxt (FixSig _ fsig)
- = do { new_fsig <- rnSrcFixityDecl ctxt fsig
- ; return (FixSig noExtField new_fsig, emptyFVs) }
-
-renameSig ctxt sig@(MinimalSig _ s (L l bf))
- = do new_bf <- traverse (lookupSigOccRn ctxt sig) bf
- return (MinimalSig noExtField s (L l new_bf), emptyFVs)
-
-renameSig ctxt sig@(PatSynSig _ vs ty)
- = do { new_vs <- mapM (lookupSigOccRn ctxt sig) vs
- ; (ty', fvs) <- rnHsSigType ty_ctxt TypeLevel ty
- ; return (PatSynSig noExtField new_vs ty', fvs) }
- where
- ty_ctxt = GenericCtx (text "a pattern synonym signature for"
- <+> ppr_sig_bndrs vs)
-
-renameSig ctxt sig@(SCCFunSig _ st v s)
- = do { new_v <- lookupSigOccRn ctxt sig v
- ; return (SCCFunSig noExtField st new_v s, emptyFVs) }
-
--- COMPLETE Sigs can refer to imported IDs which is why we use
--- lookupLocatedOccRn rather than lookupSigOccRn
-renameSig _ctxt sig@(CompleteMatchSig _ s (L l bf) mty)
- = do new_bf <- traverse lookupLocatedOccRn bf
- new_mty <- traverse lookupLocatedOccRn mty
-
- this_mod <- fmap tcg_mod getGblEnv
- unless (any (nameIsLocalOrFrom this_mod . unLoc) new_bf) $ do
- -- Why 'any'? See Note [Orphan COMPLETE pragmas]
- addErrCtxt (text "In" <+> ppr sig) $ failWithTc orphanError
-
- return (CompleteMatchSig noExtField s (L l new_bf) new_mty, emptyFVs)
- where
- orphanError :: SDoc
- orphanError =
- text "Orphan COMPLETE pragmas not supported" $$
- text "A COMPLETE pragma must mention at least one data constructor" $$
- text "or pattern synonym defined in the same module."
-
-renameSig _ (XSig nec) = noExtCon nec
-
-{-
-Note [Orphan COMPLETE pragmas]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We define a COMPLETE pragma to be a non-orphan if it includes at least
-one conlike defined in the current module. Why is this sufficient?
-Well if you have a pattern match
-
- case expr of
- P1 -> ...
- P2 -> ...
- P3 -> ...
-
-any COMPLETE pragma which mentions a conlike other than P1, P2 or P3
-will not be of any use in verifying that the pattern match is
-exhaustive. So as we have certainly read the interface files that
-define P1, P2 and P3, we will have loaded all non-orphan COMPLETE
-pragmas that could be relevant to this pattern match.
-
-For now we simply disallow orphan COMPLETE pragmas, as the added
-complexity of supporting them properly doesn't seem worthwhile.
--}
-
-ppr_sig_bndrs :: [Located RdrName] -> SDoc
-ppr_sig_bndrs bs = quotes (pprWithCommas ppr bs)
-
-okHsSig :: HsSigCtxt -> LSig (GhcPass a) -> Bool
-okHsSig ctxt (L _ sig)
- = case (sig, ctxt) of
- (ClassOpSig {}, ClsDeclCtxt {}) -> True
- (ClassOpSig {}, InstDeclCtxt {}) -> True
- (ClassOpSig {}, _) -> False
-
- (TypeSig {}, ClsDeclCtxt {}) -> False
- (TypeSig {}, InstDeclCtxt {}) -> False
- (TypeSig {}, _) -> True
-
- (PatSynSig {}, TopSigCtxt{}) -> True
- (PatSynSig {}, _) -> False
-
- (FixSig {}, InstDeclCtxt {}) -> False
- (FixSig {}, _) -> True
-
- (IdSig {}, TopSigCtxt {}) -> True
- (IdSig {}, InstDeclCtxt {}) -> True
- (IdSig {}, _) -> False
-
- (InlineSig {}, HsBootCtxt {}) -> False
- (InlineSig {}, _) -> True
-
- (SpecSig {}, TopSigCtxt {}) -> True
- (SpecSig {}, LocalBindCtxt {}) -> True
- (SpecSig {}, InstDeclCtxt {}) -> True
- (SpecSig {}, _) -> False
-
- (SpecInstSig {}, InstDeclCtxt {}) -> True
- (SpecInstSig {}, _) -> False
-
- (MinimalSig {}, ClsDeclCtxt {}) -> True
- (MinimalSig {}, _) -> False
-
- (SCCFunSig {}, HsBootCtxt {}) -> False
- (SCCFunSig {}, _) -> True
-
- (CompleteMatchSig {}, TopSigCtxt {} ) -> True
- (CompleteMatchSig {}, _) -> False
-
- (XSig nec, _) -> noExtCon nec
-
--------------------
-findDupSigs :: [LSig GhcPs] -> [NonEmpty (Located RdrName, Sig GhcPs)]
--- Check for duplicates on RdrName version,
--- because renamed version has unboundName for
--- not-in-scope binders, which gives bogus dup-sig errors
--- NB: in a class decl, a 'generic' sig is not considered
--- equal to an ordinary sig, so we allow, say
--- class C a where
--- op :: a -> a
--- default op :: Eq a => a -> a
-findDupSigs sigs
- = findDupsEq matching_sig (concatMap (expand_sig . unLoc) sigs)
- where
- expand_sig sig@(FixSig _ (FixitySig _ ns _)) = zip ns (repeat sig)
- expand_sig sig@(InlineSig _ n _) = [(n,sig)]
- expand_sig sig@(TypeSig _ ns _) = [(n,sig) | n <- ns]
- expand_sig sig@(ClassOpSig _ _ ns _) = [(n,sig) | n <- ns]
- expand_sig sig@(PatSynSig _ ns _ ) = [(n,sig) | n <- ns]
- expand_sig sig@(SCCFunSig _ _ n _) = [(n,sig)]
- expand_sig _ = []
-
- matching_sig (L _ n1,sig1) (L _ n2,sig2) = n1 == n2 && mtch sig1 sig2
- mtch (FixSig {}) (FixSig {}) = True
- mtch (InlineSig {}) (InlineSig {}) = True
- mtch (TypeSig {}) (TypeSig {}) = True
- mtch (ClassOpSig _ d1 _ _) (ClassOpSig _ d2 _ _) = d1 == d2
- mtch (PatSynSig _ _ _) (PatSynSig _ _ _) = True
- mtch (SCCFunSig{}) (SCCFunSig{}) = True
- mtch _ _ = False
-
--- Warn about multiple MINIMAL signatures
-checkDupMinimalSigs :: [LSig GhcPs] -> RnM ()
-checkDupMinimalSigs sigs
- = case filter isMinimalLSig sigs of
- minSigs@(_:_:_) -> dupMinimalSigErr minSigs
- _ -> return ()
-
-{-
-************************************************************************
-* *
-\subsection{Match}
-* *
-************************************************************************
--}
-
-rnMatchGroup :: Outputable (body GhcPs) => HsMatchContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> MatchGroup GhcPs (Located (body GhcPs))
- -> RnM (MatchGroup GhcRn (Located (body GhcRn)), FreeVars)
-rnMatchGroup ctxt rnBody (MG { mg_alts = L _ ms, mg_origin = origin })
- = do { empty_case_ok <- xoptM LangExt.EmptyCase
- ; when (null ms && not empty_case_ok) (addErr (emptyCaseErr ctxt))
- ; (new_ms, ms_fvs) <- mapFvRn (rnMatch ctxt rnBody) ms
- ; return (mkMatchGroup origin new_ms, ms_fvs) }
-rnMatchGroup _ _ (XMatchGroup nec) = noExtCon nec
-
-rnMatch :: Outputable (body GhcPs) => HsMatchContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> LMatch GhcPs (Located (body GhcPs))
- -> RnM (LMatch GhcRn (Located (body GhcRn)), FreeVars)
-rnMatch ctxt rnBody = wrapLocFstM (rnMatch' ctxt rnBody)
-
-rnMatch' :: Outputable (body GhcPs) => HsMatchContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> Match GhcPs (Located (body GhcPs))
- -> RnM (Match GhcRn (Located (body GhcRn)), FreeVars)
-rnMatch' ctxt rnBody (Match { m_ctxt = mf, m_pats = pats, m_grhss = grhss })
- = do { -- Note that there are no local fixity decls for matches
- ; rnPats ctxt pats $ \ pats' -> do
- { (grhss', grhss_fvs) <- rnGRHSs ctxt rnBody grhss
- ; let mf' = case (ctxt, mf) of
- (FunRhs { mc_fun = L _ funid }, FunRhs { mc_fun = L lf _ })
- -> mf { mc_fun = L lf funid }
- _ -> ctxt
- ; return (Match { m_ext = noExtField, m_ctxt = mf', m_pats = pats'
- , m_grhss = grhss'}, grhss_fvs ) }}
-rnMatch' _ _ (XMatch nec) = noExtCon nec
-
-emptyCaseErr :: HsMatchContext Name -> SDoc
-emptyCaseErr ctxt = hang (text "Empty list of alternatives in" <+> pp_ctxt)
- 2 (text "Use EmptyCase to allow this")
- where
- pp_ctxt = case ctxt of
- CaseAlt -> text "case expression"
- LambdaExpr -> text "\\case expression"
- _ -> text "(unexpected)" <+> pprMatchContextNoun ctxt
-
-{-
-************************************************************************
-* *
-\subsubsection{Guarded right-hand sides (GRHSs)}
-* *
-************************************************************************
--}
-
-rnGRHSs :: HsMatchContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> GRHSs GhcPs (Located (body GhcPs))
- -> RnM (GRHSs GhcRn (Located (body GhcRn)), FreeVars)
-rnGRHSs ctxt rnBody (GRHSs _ grhss (L l binds))
- = rnLocalBindsAndThen binds $ \ binds' _ -> do
- (grhss', fvGRHSs) <- mapFvRn (rnGRHS ctxt rnBody) grhss
- return (GRHSs noExtField grhss' (L l binds'), fvGRHSs)
-rnGRHSs _ _ (XGRHSs nec) = noExtCon nec
-
-rnGRHS :: HsMatchContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> LGRHS GhcPs (Located (body GhcPs))
- -> RnM (LGRHS GhcRn (Located (body GhcRn)), FreeVars)
-rnGRHS ctxt rnBody = wrapLocFstM (rnGRHS' ctxt rnBody)
-
-rnGRHS' :: HsMatchContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> GRHS GhcPs (Located (body GhcPs))
- -> RnM (GRHS GhcRn (Located (body GhcRn)), FreeVars)
-rnGRHS' ctxt rnBody (GRHS _ guards rhs)
- = do { pattern_guards_allowed <- xoptM LangExt.PatternGuards
- ; ((guards', rhs'), fvs) <- rnStmts (PatGuard ctxt) rnLExpr guards $ \ _ ->
- rnBody rhs
-
- ; unless (pattern_guards_allowed || is_standard_guard guards')
- (addWarn NoReason (nonStdGuardErr guards'))
-
- ; return (GRHS noExtField guards' rhs', fvs) }
- where
- -- Standard Haskell 1.4 guards are just a single boolean
- -- expression, rather than a list of qualifiers as in the
- -- Glasgow extension
- is_standard_guard [] = True
- is_standard_guard [L _ (BodyStmt {})] = True
- is_standard_guard _ = False
-rnGRHS' _ _ (XGRHS nec) = noExtCon nec
-
-{-
-*********************************************************
-* *
- Source-code fixity declarations
-* *
-*********************************************************
--}
-
-rnSrcFixityDecl :: HsSigCtxt -> FixitySig GhcPs -> RnM (FixitySig GhcRn)
--- Rename a fixity decl, so we can put
--- the renamed decl in the renamed syntax tree
--- Errors if the thing being fixed is not defined locally.
-rnSrcFixityDecl sig_ctxt = rn_decl
- where
- rn_decl :: FixitySig GhcPs -> RnM (FixitySig GhcRn)
- -- GHC extension: look up both the tycon and data con
- -- for con-like things; hence returning a list
- -- If neither are in scope, report an error; otherwise
- -- return a fixity sig for each (slightly odd)
- rn_decl (FixitySig _ fnames fixity)
- = do names <- concatMapM lookup_one fnames
- return (FixitySig noExtField names fixity)
- rn_decl (XFixitySig nec) = noExtCon nec
-
- lookup_one :: Located RdrName -> RnM [Located Name]
- lookup_one (L name_loc rdr_name)
- = setSrcSpan name_loc $
- -- This lookup will fail if the name is not defined in the
- -- same binding group as this fixity declaration.
- do names <- lookupLocalTcNames sig_ctxt what rdr_name
- return [ L name_loc name | (_, name) <- names ]
- what = text "fixity signature"
-
-{-
-************************************************************************
-* *
-\subsection{Error messages}
-* *
-************************************************************************
--}
-
-dupSigDeclErr :: NonEmpty (Located RdrName, Sig GhcPs) -> RnM ()
-dupSigDeclErr pairs@((L loc name, sig) :| _)
- = addErrAt loc $
- vcat [ text "Duplicate" <+> what_it_is
- <> text "s for" <+> quotes (ppr name)
- , text "at" <+> vcat (map ppr $ sort
- $ map (getLoc . fst)
- $ toList pairs)
- ]
- where
- what_it_is = hsSigDoc sig
-
-misplacedSigErr :: LSig GhcRn -> RnM ()
-misplacedSigErr (L loc sig)
- = addErrAt loc $
- sep [text "Misplaced" <+> hsSigDoc sig <> colon, ppr sig]
-
-defaultSigErr :: Sig GhcPs -> SDoc
-defaultSigErr sig = vcat [ hang (text "Unexpected default signature:")
- 2 (ppr sig)
- , text "Use DefaultSignatures to enable default signatures" ]
-
-bindsInHsBootFile :: LHsBindsLR GhcRn GhcPs -> SDoc
-bindsInHsBootFile mbinds
- = hang (text "Bindings in hs-boot files are not allowed")
- 2 (ppr mbinds)
-
-nonStdGuardErr :: Outputable body => [LStmtLR GhcRn GhcRn body] -> SDoc
-nonStdGuardErr guards
- = hang (text "accepting non-standard pattern guards (use PatternGuards to suppress this message)")
- 4 (interpp'SP guards)
-
-unusedPatBindWarn :: HsBind GhcRn -> SDoc
-unusedPatBindWarn bind
- = hang (text "This pattern-binding binds no variables:")
- 2 (ppr bind)
-
-dupMinimalSigErr :: [LSig GhcPs] -> RnM ()
-dupMinimalSigErr sigs@(L loc _ : _)
- = addErrAt loc $
- vcat [ text "Multiple minimal complete definitions"
- , text "at" <+> vcat (map ppr $ sort $ map getLoc sigs)
- , text "Combine alternative minimal complete definitions with `|'" ]
-dupMinimalSigErr [] = panic "dupMinimalSigErr"
diff --git a/compiler/rename/RnEnv.hs b/compiler/rename/RnEnv.hs
deleted file mode 100644
index 4ce5805785..0000000000
--- a/compiler/rename/RnEnv.hs
+++ /dev/null
@@ -1,1702 +0,0 @@
-{-
-(c) The GRASP/AQUA Project, Glasgow University, 1992-2006
-
-RnEnv contains functions which convert RdrNames into Names.
-
--}
-
-{-# LANGUAGE CPP, MultiWayIf, NamedFieldPuns #-}
-
-module RnEnv (
- newTopSrcBinder,
- lookupLocatedTopBndrRn, lookupTopBndrRn,
- lookupLocatedOccRn, lookupOccRn, lookupOccRn_maybe,
- lookupLocalOccRn_maybe, lookupInfoOccRn,
- lookupLocalOccThLvl_maybe, lookupLocalOccRn,
- lookupTypeOccRn,
- lookupGlobalOccRn, lookupGlobalOccRn_maybe,
- lookupOccRn_overloaded, lookupGlobalOccRn_overloaded, lookupExactOcc,
-
- ChildLookupResult(..),
- lookupSubBndrOcc_helper,
- combineChildLookupResult, -- Called by lookupChildrenExport
-
- HsSigCtxt(..), lookupLocalTcNames, lookupSigOccRn,
- lookupSigCtxtOccRn,
-
- lookupInstDeclBndr, lookupRecFieldOcc, lookupFamInstName,
- lookupConstructorFields,
-
- lookupGreAvailRn,
-
- -- Rebindable Syntax
- lookupSyntaxName, lookupSyntaxName', lookupSyntaxNames,
- lookupIfThenElse,
-
- -- Constructing usage information
- addUsedGRE, addUsedGREs, addUsedDataCons,
-
-
-
- dataTcOccs, --TODO: Move this somewhere, into utils?
-
- ) where
-
-#include "HsVersions.h"
-
-import GhcPrelude
-
-import GHC.Iface.Load ( loadInterfaceForName, loadSrcInterface_maybe )
-import GHC.Iface.Env
-import GHC.Hs
-import RdrName
-import HscTypes
-import TcEnv
-import TcRnMonad
-import RdrHsSyn ( filterCTuple, setRdrNameSpace )
-import TysWiredIn
-import Name
-import NameSet
-import NameEnv
-import Avail
-import Module
-import ConLike
-import DataCon
-import TyCon
-import ErrUtils ( MsgDoc )
-import PrelNames ( rOOT_MAIN )
-import BasicTypes ( pprWarningTxtForMsg, TopLevelFlag(..))
-import SrcLoc
-import Outputable
-import UniqSet ( uniqSetAny )
-import Util
-import Maybes
-import DynFlags
-import FastString
-import Control.Monad
-import ListSetOps ( minusList )
-import qualified GHC.LanguageExtensions as LangExt
-import RnUnbound
-import RnUtils
-import qualified Data.Semigroup as Semi
-import Data.Either ( partitionEithers )
-import Data.List (find)
-
-{-
-*********************************************************
-* *
- Source-code binders
-* *
-*********************************************************
-
-Note [Signature lazy interface loading]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-GHC's lazy interface loading can be a bit confusing, so this Note is an
-empirical description of what happens in one interesting case. When
-compiling a signature module against an its implementation, we do NOT
-load interface files associated with its names until after the type
-checking phase. For example:
-
- module ASig where
- data T
- f :: T -> T
-
-Suppose we compile this with -sig-of "A is ASig":
-
- module B where
- data T = T
- f T = T
-
- module A(module B) where
- import B
-
-During type checking, we'll load A.hi because we need to know what the
-RdrEnv for the module is, but we DO NOT load the interface for B.hi!
-It's wholly unnecessary: our local definition 'data T' in ASig is all
-the information we need to finish type checking. This is contrast to
-type checking of ordinary Haskell files, in which we would not have the
-local definition "data T" and would need to consult B.hi immediately.
-(Also, this situation never occurs for hs-boot files, since you're not
-allowed to reexport from another module.)
-
-After type checking, we then check that the types we provided are
-consistent with the backing implementation (in checkHiBootOrHsigIface).
-At this point, B.hi is loaded, because we need something to compare
-against.
-
-I discovered this behavior when trying to figure out why type class
-instances for Data.Map weren't in the EPS when I was type checking a
-test very much like ASig (sigof02dm): the associated interface hadn't
-been loaded yet! (The larger issue is a moot point, since an instance
-declared in a signature can never be a duplicate.)
-
-This behavior might change in the future. Consider this
-alternate module B:
-
- module B where
- {-# DEPRECATED T, f "Don't use" #-}
- data T = T
- f T = T
-
-One might conceivably want to report deprecation warnings when compiling
-ASig with -sig-of B, in which case we need to look at B.hi to find the
-deprecation warnings during renaming. At the moment, you don't get any
-warning until you use the identifier further downstream. This would
-require adjusting addUsedGRE so that during signature compilation,
-we do not report deprecation warnings for LocalDef. See also
-Note [Handling of deprecations]
--}
-
-newTopSrcBinder :: Located RdrName -> RnM Name
-newTopSrcBinder (L loc rdr_name)
- | Just name <- isExact_maybe rdr_name
- = -- This is here to catch
- -- (a) Exact-name binders created by Template Haskell
- -- (b) The PrelBase defn of (say) [] and similar, for which
- -- the parser reads the special syntax and returns an Exact RdrName
- -- We are at a binding site for the name, so check first that it
- -- the current module is the correct one; otherwise GHC can get
- -- very confused indeed. This test rejects code like
- -- data T = (,) Int Int
- -- unless we are in GHC.Tup
- if isExternalName name then
- do { this_mod <- getModule
- ; unless (this_mod == nameModule name)
- (addErrAt loc (badOrigBinding rdr_name))
- ; return name }
- else -- See Note [Binders in Template Haskell] in Convert.hs
- do { this_mod <- getModule
- ; externaliseName this_mod name }
-
- | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name
- = do { this_mod <- getModule
- ; unless (rdr_mod == this_mod || rdr_mod == rOOT_MAIN)
- (addErrAt loc (badOrigBinding rdr_name))
- -- When reading External Core we get Orig names as binders,
- -- but they should agree with the module gotten from the monad
- --
- -- We can get built-in syntax showing up here too, sadly. If you type
- -- data T = (,,,)
- -- the constructor is parsed as a type, and then RdrHsSyn.tyConToDataCon
- -- uses setRdrNameSpace to make it into a data constructors. At that point
- -- the nice Exact name for the TyCon gets swizzled to an Orig name.
- -- Hence the badOrigBinding error message.
- --
- -- Except for the ":Main.main = ..." definition inserted into
- -- the Main module; ugh!
-
- -- Because of this latter case, we call newGlobalBinder with a module from
- -- the RdrName, not from the environment. In principle, it'd be fine to
- -- have an arbitrary mixture of external core definitions in a single module,
- -- (apart from module-initialisation issues, perhaps).
- ; newGlobalBinder rdr_mod rdr_occ loc }
-
- | otherwise
- = do { when (isQual rdr_name)
- (addErrAt loc (badQualBndrErr rdr_name))
- -- Binders should not be qualified; if they are, and with a different
- -- module name, we get a confusing "M.T is not in scope" error later
-
- ; stage <- getStage
- ; if isBrackStage stage then
- -- We are inside a TH bracket, so make an *Internal* name
- -- See Note [Top-level Names in Template Haskell decl quotes] in RnNames
- do { uniq <- newUnique
- ; return (mkInternalName uniq (rdrNameOcc rdr_name) loc) }
- else
- do { this_mod <- getModule
- ; traceRn "newTopSrcBinder" (ppr this_mod $$ ppr rdr_name $$ ppr loc)
- ; newGlobalBinder this_mod (rdrNameOcc rdr_name) loc }
- }
-
-{-
-*********************************************************
-* *
- Source code occurrences
-* *
-*********************************************************
-
-Looking up a name in the RnEnv.
-
-Note [Type and class operator definitions]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We want to reject all of these unless we have -XTypeOperators (#3265)
- data a :*: b = ...
- class a :*: b where ...
- data (:*:) a b = ....
- class (:*:) a b where ...
-The latter two mean that we are not just looking for a
-*syntactically-infix* declaration, but one that uses an operator
-OccName. We use OccName.isSymOcc to detect that case, which isn't
-terribly efficient, but there seems to be no better way.
--}
-
--- Can be made to not be exposed
--- Only used unwrapped in rnAnnProvenance
-lookupTopBndrRn :: RdrName -> RnM Name
-lookupTopBndrRn n = do nopt <- lookupTopBndrRn_maybe n
- case nopt of
- Just n' -> return n'
- Nothing -> do traceRn "lookupTopBndrRn fail" (ppr n)
- unboundName WL_LocalTop n
-
-lookupLocatedTopBndrRn :: Located RdrName -> RnM (Located Name)
-lookupLocatedTopBndrRn = wrapLocM lookupTopBndrRn
-
-lookupTopBndrRn_maybe :: RdrName -> RnM (Maybe Name)
--- Look up a top-level source-code binder. We may be looking up an unqualified 'f',
--- and there may be several imported 'f's too, which must not confuse us.
--- For example, this is OK:
--- import Foo( f )
--- infix 9 f -- The 'f' here does not need to be qualified
--- f x = x -- Nor here, of course
--- So we have to filter out the non-local ones.
---
--- A separate function (importsFromLocalDecls) reports duplicate top level
--- decls, so here it's safe just to choose an arbitrary one.
---
--- There should never be a qualified name in a binding position in Haskell,
--- but there can be if we have read in an external-Core file.
--- The Haskell parser checks for the illegal qualified name in Haskell
--- source files, so we don't need to do so here.
-
-lookupTopBndrRn_maybe rdr_name =
- lookupExactOrOrig rdr_name Just $
- do { -- Check for operators in type or class declarations
- -- See Note [Type and class operator definitions]
- let occ = rdrNameOcc rdr_name
- ; when (isTcOcc occ && isSymOcc occ)
- (do { op_ok <- xoptM LangExt.TypeOperators
- ; unless op_ok (addErr (opDeclErr rdr_name)) })
-
- ; env <- getGlobalRdrEnv
- ; case filter isLocalGRE (lookupGRE_RdrName rdr_name env) of
- [gre] -> return (Just (gre_name gre))
- _ -> return Nothing -- Ambiguous (can't happen) or unbound
- }
-
------------------------------------------------
--- | Lookup an @Exact@ @RdrName@. See Note [Looking up Exact RdrNames].
--- This adds an error if the name cannot be found.
-lookupExactOcc :: Name -> RnM Name
-lookupExactOcc name
- = do { result <- lookupExactOcc_either name
- ; case result of
- Left err -> do { addErr err
- ; return name }
- Right name' -> return name' }
-
--- | Lookup an @Exact@ @RdrName@. See Note [Looking up Exact RdrNames].
--- This never adds an error, but it may return one.
-lookupExactOcc_either :: Name -> RnM (Either MsgDoc Name)
--- See Note [Looking up Exact RdrNames]
-lookupExactOcc_either name
- | Just thing <- wiredInNameTyThing_maybe name
- , Just tycon <- case thing of
- ATyCon tc -> Just tc
- AConLike (RealDataCon dc) -> Just (dataConTyCon dc)
- _ -> Nothing
- , isTupleTyCon tycon
- = do { checkTupSize (tyConArity tycon)
- ; return (Right name) }
-
- | isExternalName name
- = return (Right name)
-
- | otherwise
- = do { env <- getGlobalRdrEnv
- ; let -- See Note [Splicing Exact names]
- main_occ = nameOccName name
- demoted_occs = case demoteOccName main_occ of
- Just occ -> [occ]
- Nothing -> []
- gres = [ gre | occ <- main_occ : demoted_occs
- , gre <- lookupGlobalRdrEnv env occ
- , gre_name gre == name ]
- ; case gres of
- [gre] -> return (Right (gre_name gre))
-
- [] -> -- See Note [Splicing Exact names]
- do { lcl_env <- getLocalRdrEnv
- ; if name `inLocalRdrEnvScope` lcl_env
- then return (Right name)
- else
- do { th_topnames_var <- fmap tcg_th_topnames getGblEnv
- ; th_topnames <- readTcRef th_topnames_var
- ; if name `elemNameSet` th_topnames
- then return (Right name)
- else return (Left exact_nm_err)
- }
- }
- gres -> return (Left (sameNameErr gres)) -- Ugh! See Note [Template Haskell ambiguity]
- }
- where
- exact_nm_err = hang (text "The exact Name" <+> quotes (ppr name) <+> ptext (sLit "is not in scope"))
- 2 (vcat [ text "Probable cause: you used a unique Template Haskell name (NameU), "
- , text "perhaps via newName, but did not bind it"
- , text "If that's it, then -ddump-splices might be useful" ])
-
-sameNameErr :: [GlobalRdrElt] -> MsgDoc
-sameNameErr [] = panic "addSameNameErr: empty list"
-sameNameErr gres@(_ : _)
- = hang (text "Same exact name in multiple name-spaces:")
- 2 (vcat (map pp_one sorted_names) $$ th_hint)
- where
- sorted_names = sortWith nameSrcLoc (map gre_name gres)
- pp_one name
- = hang (pprNameSpace (occNameSpace (getOccName name))
- <+> quotes (ppr name) <> comma)
- 2 (text "declared at:" <+> ppr (nameSrcLoc name))
-
- th_hint = vcat [ text "Probable cause: you bound a unique Template Haskell name (NameU),"
- , text "perhaps via newName, in different name-spaces."
- , text "If that's it, then -ddump-splices might be useful" ]
-
-
------------------------------------------------
-lookupInstDeclBndr :: Name -> SDoc -> RdrName -> RnM Name
--- This is called on the method name on the left-hand side of an
--- instance declaration binding. eg. instance Functor T where
--- fmap = ...
--- ^^^^ called on this
--- Regardless of how many unqualified fmaps are in scope, we want
--- the one that comes from the Functor class.
---
--- Furthermore, note that we take no account of whether the
--- name is only in scope qualified. I.e. even if method op is
--- in scope as M.op, we still allow plain 'op' on the LHS of
--- an instance decl
---
--- The "what" parameter says "method" or "associated type",
--- depending on what we are looking up
-lookupInstDeclBndr cls what rdr
- = do { when (isQual rdr)
- (addErr (badQualBndrErr rdr))
- -- In an instance decl you aren't allowed
- -- to use a qualified name for the method
- -- (Although it'd make perfect sense.)
- ; mb_name <- lookupSubBndrOcc
- False -- False => we don't give deprecated
- -- warnings when a deprecated class
- -- method is defined. We only warn
- -- when it's used
- cls doc rdr
- ; case mb_name of
- Left err -> do { addErr err; return (mkUnboundNameRdr rdr) }
- Right nm -> return nm }
- where
- doc = what <+> text "of class" <+> quotes (ppr cls)
-
------------------------------------------------
-lookupFamInstName :: Maybe Name -> Located RdrName
- -> RnM (Located Name)
--- Used for TyData and TySynonym family instances only,
--- See Note [Family instance binders]
-lookupFamInstName (Just cls) tc_rdr -- Associated type; c.f RnBinds.rnMethodBind
- = wrapLocM (lookupInstDeclBndr cls (text "associated type")) tc_rdr
-lookupFamInstName Nothing tc_rdr -- Family instance; tc_rdr is an *occurrence*
- = lookupLocatedOccRn tc_rdr
-
------------------------------------------------
-lookupConstructorFields :: Name -> RnM [FieldLabel]
--- Look up the fields of a given constructor
--- * For constructors from this module, use the record field env,
--- which is itself gathered from the (as yet un-typechecked)
--- data type decls
---
--- * For constructors from imported modules, use the *type* environment
--- since imported modles are already compiled, the info is conveniently
--- right there
-
-lookupConstructorFields con_name
- = do { this_mod <- getModule
- ; if nameIsLocalOrFrom this_mod con_name then
- do { field_env <- getRecFieldEnv
- ; traceTc "lookupCF" (ppr con_name $$ ppr (lookupNameEnv field_env con_name) $$ ppr field_env)
- ; return (lookupNameEnv field_env con_name `orElse` []) }
- else
- do { con <- tcLookupConLike con_name
- ; traceTc "lookupCF 2" (ppr con)
- ; return (conLikeFieldLabels con) } }
-
-
--- In CPS style as `RnM r` is monadic
-lookupExactOrOrig :: RdrName -> (Name -> r) -> RnM r -> RnM r
-lookupExactOrOrig rdr_name res k
- | Just n <- isExact_maybe rdr_name -- This happens in derived code
- = res <$> lookupExactOcc n
- | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name
- = res <$> lookupOrig rdr_mod rdr_occ
- | otherwise = k
-
-
-
------------------------------------------------
--- | Look up an occurrence of a field in record construction or pattern
--- matching (but not update). When the -XDisambiguateRecordFields
--- flag is on, take account of the data constructor name to
--- disambiguate which field to use.
---
--- See Note [DisambiguateRecordFields].
-lookupRecFieldOcc :: Maybe Name -- Nothing => just look it up as usual
- -- Just con => use data con to disambiguate
- -> RdrName
- -> RnM Name
-lookupRecFieldOcc mb_con rdr_name
- | Just con <- mb_con
- , isUnboundName con -- Avoid error cascade
- = return (mkUnboundNameRdr rdr_name)
- | Just con <- mb_con
- = do { flds <- lookupConstructorFields con
- ; env <- getGlobalRdrEnv
- ; let lbl = occNameFS (rdrNameOcc rdr_name)
- mb_field = do fl <- find ((== lbl) . flLabel) flds
- -- We have the label, now check it is in
- -- scope (with the correct qualifier if
- -- there is one, hence calling pickGREs).
- gre <- lookupGRE_FieldLabel env fl
- guard (not (isQual rdr_name
- && null (pickGREs rdr_name [gre])))
- return (fl, gre)
- ; case mb_field of
- Just (fl, gre) -> do { addUsedGRE True gre
- ; return (flSelector fl) }
- Nothing -> lookupGlobalOccRn rdr_name }
- -- See Note [Fall back on lookupGlobalOccRn in lookupRecFieldOcc]
- | otherwise
- -- This use of Global is right as we are looking up a selector which
- -- can only be defined at the top level.
- = lookupGlobalOccRn rdr_name
-
-{- Note [DisambiguateRecordFields]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When we are looking up record fields in record construction or pattern
-matching, we can take advantage of the data constructor name to
-resolve fields that would otherwise be ambiguous (provided the
--XDisambiguateRecordFields flag is on).
-
-For example, consider:
-
- data S = MkS { x :: Int }
- data T = MkT { x :: Int }
-
- e = MkS { x = 3 }
-
-When we are renaming the occurrence of `x` in `e`, instead of looking
-`x` up directly (and finding both fields), lookupRecFieldOcc will
-search the fields of `MkS` to find the only possible `x` the user can
-mean.
-
-Of course, we still have to check the field is in scope, using
-lookupGRE_FieldLabel. The handling of qualified imports is slightly
-subtle: the occurrence may be unqualified even if the field is
-imported only qualified (but if the occurrence is qualified, the
-qualifier must be correct). For example:
-
- module A where
- data S = MkS { x :: Int }
- data T = MkT { x :: Int }
-
- module B where
- import qualified A (S(..))
- import A (T(MkT))
-
- e1 = MkT { x = 3 } -- x not in scope, so fail
- e2 = A.MkS { B.x = 3 } -- module qualifier is wrong, so fail
- e3 = A.MkS { x = 3 } -- x in scope (lack of module qualifier permitted)
-
-In case `e1`, lookupGRE_FieldLabel will return Nothing. In case `e2`,
-lookupGRE_FieldLabel will return the GRE for `A.x`, but then the guard
-will fail because the field RdrName `B.x` is qualified and pickGREs
-rejects the GRE. In case `e3`, lookupGRE_FieldLabel will return the
-GRE for `A.x` and the guard will succeed because the field RdrName `x`
-is unqualified.
-
-
-Note [Fall back on lookupGlobalOccRn in lookupRecFieldOcc]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Whenever we fail to find the field or it is not in scope, mb_field
-will be False, and we fall back on looking it up normally using
-lookupGlobalOccRn. We don't report an error immediately because the
-actual problem might be located elsewhere. For example (#9975):
-
- data Test = Test { x :: Int }
- pattern Test wat = Test { x = wat }
-
-Here there are multiple declarations of Test (as a data constructor
-and as a pattern synonym), which will be reported as an error. We
-shouldn't also report an error about the occurrence of `x` in the
-pattern synonym RHS. However, if the pattern synonym gets added to
-the environment first, we will try and fail to find `x` amongst the
-(nonexistent) fields of the pattern synonym.
-
-Alternatively, the scope check can fail due to Template Haskell.
-Consider (#12130):
-
- module Foo where
- import M
- b = $(funny)
-
- module M(funny) where
- data T = MkT { x :: Int }
- funny :: Q Exp
- funny = [| MkT { x = 3 } |]
-
-When we splice, `MkT` is not lexically in scope, so
-lookupGRE_FieldLabel will fail. But there is no need for
-disambiguation anyway, because `x` is an original name, and
-lookupGlobalOccRn will find it.
--}
-
-
-
--- | Used in export lists to lookup the children.
-lookupSubBndrOcc_helper :: Bool -> Bool -> Name -> RdrName
- -> RnM ChildLookupResult
-lookupSubBndrOcc_helper must_have_parent warn_if_deprec parent rdr_name
- | isUnboundName parent
- -- Avoid an error cascade
- = return (FoundName NoParent (mkUnboundNameRdr rdr_name))
-
- | otherwise = do
- gre_env <- getGlobalRdrEnv
-
- let original_gres = lookupGlobalRdrEnv gre_env (rdrNameOcc rdr_name)
- -- Disambiguate the lookup based on the parent information.
- -- The remaining GREs are things that we *could* export here, note that
- -- this includes things which have `NoParent`. Those are sorted in
- -- `checkPatSynParent`.
- traceRn "parent" (ppr parent)
- traceRn "lookupExportChild original_gres:" (ppr original_gres)
- traceRn "lookupExportChild picked_gres:" (ppr $ picked_gres original_gres)
- case picked_gres original_gres of
- NoOccurrence ->
- noMatchingParentErr original_gres
- UniqueOccurrence g ->
- if must_have_parent then noMatchingParentErr original_gres
- else checkFld g
- DisambiguatedOccurrence g ->
- checkFld g
- AmbiguousOccurrence gres ->
- mkNameClashErr gres
- where
- -- Convert into FieldLabel if necessary
- checkFld :: GlobalRdrElt -> RnM ChildLookupResult
- checkFld g@GRE{gre_name, gre_par} = do
- addUsedGRE warn_if_deprec g
- return $ case gre_par of
- FldParent _ mfs ->
- FoundFL (fldParentToFieldLabel gre_name mfs)
- _ -> FoundName gre_par gre_name
-
- fldParentToFieldLabel :: Name -> Maybe FastString -> FieldLabel
- fldParentToFieldLabel name mfs =
- case mfs of
- Nothing ->
- let fs = occNameFS (nameOccName name)
- in FieldLabel fs False name
- Just fs -> FieldLabel fs True name
-
- -- Called when we find no matching GREs after disambiguation but
- -- there are three situations where this happens.
- -- 1. There were none to begin with.
- -- 2. None of the matching ones were the parent but
- -- a. They were from an overloaded record field so we can report
- -- a better error
- -- b. The original lookup was actually ambiguous.
- -- For example, the case where overloading is off and two
- -- record fields are in scope from different record
- -- constructors, neither of which is the parent.
- noMatchingParentErr :: [GlobalRdrElt] -> RnM ChildLookupResult
- noMatchingParentErr original_gres = do
- overload_ok <- xoptM LangExt.DuplicateRecordFields
- case original_gres of
- [] -> return NameNotFound
- [g] -> return $ IncorrectParent parent
- (gre_name g) (ppr $ gre_name g)
- [p | Just p <- [getParent g]]
- gss@(g:_:_) ->
- if all isRecFldGRE gss && overload_ok
- then return $
- IncorrectParent parent
- (gre_name g)
- (ppr $ expectJust "noMatchingParentErr" (greLabel g))
- [p | x <- gss, Just p <- [getParent x]]
- else mkNameClashErr gss
-
- mkNameClashErr :: [GlobalRdrElt] -> RnM ChildLookupResult
- mkNameClashErr gres = do
- addNameClashErrRn rdr_name gres
- return (FoundName (gre_par (head gres)) (gre_name (head gres)))
-
- getParent :: GlobalRdrElt -> Maybe Name
- getParent (GRE { gre_par = p } ) =
- case p of
- ParentIs cur_parent -> Just cur_parent
- FldParent { par_is = cur_parent } -> Just cur_parent
- NoParent -> Nothing
-
- picked_gres :: [GlobalRdrElt] -> DisambigInfo
- -- For Unqual, find GREs that are in scope qualified or unqualified
- -- For Qual, find GREs that are in scope with that qualification
- picked_gres gres
- | isUnqual rdr_name
- = mconcat (map right_parent gres)
- | otherwise
- = mconcat (map right_parent (pickGREs rdr_name gres))
-
- right_parent :: GlobalRdrElt -> DisambigInfo
- right_parent p
- = case getParent p of
- Just cur_parent
- | parent == cur_parent -> DisambiguatedOccurrence p
- | otherwise -> NoOccurrence
- Nothing -> UniqueOccurrence p
-
-
--- This domain specific datatype is used to record why we decided it was
--- possible that a GRE could be exported with a parent.
-data DisambigInfo
- = NoOccurrence
- -- The GRE could never be exported. It has the wrong parent.
- | UniqueOccurrence GlobalRdrElt
- -- The GRE has no parent. It could be a pattern synonym.
- | DisambiguatedOccurrence GlobalRdrElt
- -- The parent of the GRE is the correct parent
- | AmbiguousOccurrence [GlobalRdrElt]
- -- For example, two normal identifiers with the same name are in
- -- scope. They will both be resolved to "UniqueOccurrence" and the
- -- monoid will combine them to this failing case.
-
-instance Outputable DisambigInfo where
- ppr NoOccurrence = text "NoOccurence"
- ppr (UniqueOccurrence gre) = text "UniqueOccurrence:" <+> ppr gre
- ppr (DisambiguatedOccurrence gre) = text "DiambiguatedOccurrence:" <+> ppr gre
- ppr (AmbiguousOccurrence gres) = text "Ambiguous:" <+> ppr gres
-
-instance Semi.Semigroup DisambigInfo where
- -- This is the key line: We prefer disambiguated occurrences to other
- -- names.
- _ <> DisambiguatedOccurrence g' = DisambiguatedOccurrence g'
- DisambiguatedOccurrence g' <> _ = DisambiguatedOccurrence g'
-
- NoOccurrence <> m = m
- m <> NoOccurrence = m
- UniqueOccurrence g <> UniqueOccurrence g'
- = AmbiguousOccurrence [g, g']
- UniqueOccurrence g <> AmbiguousOccurrence gs
- = AmbiguousOccurrence (g:gs)
- AmbiguousOccurrence gs <> UniqueOccurrence g'
- = AmbiguousOccurrence (g':gs)
- AmbiguousOccurrence gs <> AmbiguousOccurrence gs'
- = AmbiguousOccurrence (gs ++ gs')
-
-instance Monoid DisambigInfo where
- mempty = NoOccurrence
- mappend = (Semi.<>)
-
--- Lookup SubBndrOcc can never be ambiguous
---
--- Records the result of looking up a child.
-data ChildLookupResult
- = NameNotFound -- We couldn't find a suitable name
- | IncorrectParent Name -- Parent
- Name -- Name of thing we were looking for
- SDoc -- How to print the name
- [Name] -- List of possible parents
- | FoundName Parent Name -- We resolved to a normal name
- | FoundFL FieldLabel -- We resolved to a FL
-
--- | Specialised version of msum for RnM ChildLookupResult
-combineChildLookupResult :: [RnM ChildLookupResult] -> RnM ChildLookupResult
-combineChildLookupResult [] = return NameNotFound
-combineChildLookupResult (x:xs) = do
- res <- x
- case res of
- NameNotFound -> combineChildLookupResult xs
- _ -> return res
-
-instance Outputable ChildLookupResult where
- ppr NameNotFound = text "NameNotFound"
- ppr (FoundName p n) = text "Found:" <+> ppr p <+> ppr n
- ppr (FoundFL fls) = text "FoundFL:" <+> ppr fls
- ppr (IncorrectParent p n td ns) = text "IncorrectParent"
- <+> hsep [ppr p, ppr n, td, ppr ns]
-
-lookupSubBndrOcc :: Bool
- -> Name -- Parent
- -> SDoc
- -> RdrName
- -> RnM (Either MsgDoc Name)
--- Find all the things the rdr-name maps to
--- and pick the one with the right parent namep
-lookupSubBndrOcc warn_if_deprec the_parent doc rdr_name = do
- res <-
- lookupExactOrOrig rdr_name (FoundName NoParent) $
- -- This happens for built-in classes, see mod052 for example
- lookupSubBndrOcc_helper True warn_if_deprec the_parent rdr_name
- case res of
- NameNotFound -> return (Left (unknownSubordinateErr doc rdr_name))
- FoundName _p n -> return (Right n)
- FoundFL fl -> return (Right (flSelector fl))
- IncorrectParent {}
- -- See [Mismatched class methods and associated type families]
- -- in TcInstDecls.
- -> return $ Left (unknownSubordinateErr doc rdr_name)
-
-{-
-Note [Family instance binders]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
- data family F a
- data instance F T = X1 | X2
-
-The 'data instance' decl has an *occurrence* of F (and T), and *binds*
-X1 and X2. (This is unlike a normal data type declaration which would
-bind F too.) So we want an AvailTC F [X1,X2].
-
-Now consider a similar pair:
- class C a where
- data G a
- instance C S where
- data G S = Y1 | Y2
-
-The 'data G S' *binds* Y1 and Y2, and has an *occurrence* of G.
-
-But there is a small complication: in an instance decl, we don't use
-qualified names on the LHS; instead we use the class to disambiguate.
-Thus:
- module M where
- import Blib( G )
- class C a where
- data G a
- instance C S where
- data G S = Y1 | Y2
-Even though there are two G's in scope (M.G and Blib.G), the occurrence
-of 'G' in the 'instance C S' decl is unambiguous, because C has only
-one associated type called G. This is exactly what happens for methods,
-and it is only consistent to do the same thing for types. That's the
-role of the function lookupTcdName; the (Maybe Name) give the class of
-the encloseing instance decl, if any.
-
-Note [Looking up Exact RdrNames]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Exact RdrNames are generated by Template Haskell. See Note [Binders
-in Template Haskell] in Convert.
-
-For data types and classes have Exact system Names in the binding
-positions for constructors, TyCons etc. For example
- [d| data T = MkT Int |]
-when we splice in and Convert to HsSyn RdrName, we'll get
- data (Exact (system Name "T")) = (Exact (system Name "MkT")) ...
-These System names are generated by Convert.thRdrName
-
-But, constructors and the like need External Names, not System Names!
-So we do the following
-
- * In RnEnv.newTopSrcBinder we spot Exact RdrNames that wrap a
- non-External Name, and make an External name for it. This is
- the name that goes in the GlobalRdrEnv
-
- * When looking up an occurrence of an Exact name, done in
- RnEnv.lookupExactOcc, we find the Name with the right unique in the
- GlobalRdrEnv, and use the one from the envt -- it will be an
- External Name in the case of the data type/constructor above.
-
- * Exact names are also use for purely local binders generated
- by TH, such as \x_33. x_33
- Both binder and occurrence are Exact RdrNames. The occurrence
- gets looked up in the LocalRdrEnv by RnEnv.lookupOccRn, and
- misses, because lookupLocalRdrEnv always returns Nothing for
- an Exact Name. Now we fall through to lookupExactOcc, which
- will find the Name is not in the GlobalRdrEnv, so we just use
- the Exact supplied Name.
-
-Note [Splicing Exact names]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider the splice $(do { x <- newName "x"; return (VarE x) })
-This will generate a (HsExpr RdrName) term that mentions the
-Exact RdrName "x_56" (or whatever), but does not bind it. So
-when looking such Exact names we want to check that it's in scope,
-otherwise the type checker will get confused. To do this we need to
-keep track of all the Names in scope, and the LocalRdrEnv does just that;
-we consult it with RdrName.inLocalRdrEnvScope.
-
-There is another wrinkle. With TH and -XDataKinds, consider
- $( [d| data Nat = Zero
- data T = MkT (Proxy 'Zero) |] )
-After splicing, but before renaming we get this:
- data Nat_77{tc} = Zero_78{d}
- data T_79{tc} = MkT_80{d} (Proxy 'Zero_78{tc}) |] )
-The occurrence of 'Zero in the data type for T has the right unique,
-but it has a TcClsName name-space in its OccName. (This is set by
-the ctxt_ns argument of Convert.thRdrName.) When we check that is
-in scope in the GlobalRdrEnv, we need to look up the DataName namespace
-too. (An alternative would be to make the GlobalRdrEnv also have
-a Name -> GRE mapping.)
-
-Note [Template Haskell ambiguity]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The GlobalRdrEnv invariant says that if
- occ -> [gre1, ..., gren]
-then the gres have distinct Names (INVARIANT 1 of GlobalRdrEnv).
-This is guaranteed by extendGlobalRdrEnvRn (the dups check in add_gre).
-
-So how can we get multiple gres in lookupExactOcc_maybe? Because in
-TH we might use the same TH NameU in two different name spaces.
-eg (#7241):
- $(newName "Foo" >>= \o -> return [DataD [] o [] [RecC o []] [''Show]])
-Here we generate a type constructor and data constructor with the same
-unique, but different name spaces.
-
-It'd be nicer to rule this out in extendGlobalRdrEnvRn, but that would
-mean looking up the OccName in every name-space, just in case, and that
-seems a bit brutal. So it's just done here on lookup. But we might
-need to revisit that choice.
-
-Note [Usage for sub-bndrs]
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-If you have this
- import qualified M( C( f ) )
- instance M.C T where
- f x = x
-then is the qualified import M.f used? Obviously yes.
-But the RdrName used in the instance decl is unqualified. In effect,
-we fill in the qualification by looking for f's whose class is M.C
-But when adding to the UsedRdrNames we must make that qualification
-explicit (saying "used M.f"), otherwise we get "Redundant import of M.f".
-
-So we make up a suitable (fake) RdrName. But be careful
- import qualified M
- import M( C(f) )
- instance C T where
- f x = x
-Here we want to record a use of 'f', not of 'M.f', otherwise
-we'll miss the fact that the qualified import is redundant.
-
---------------------------------------------------
--- Occurrences
---------------------------------------------------
--}
-
-
-lookupLocatedOccRn :: Located RdrName -> RnM (Located Name)
-lookupLocatedOccRn = wrapLocM lookupOccRn
-
-lookupLocalOccRn_maybe :: RdrName -> RnM (Maybe Name)
--- Just look in the local environment
-lookupLocalOccRn_maybe rdr_name
- = do { local_env <- getLocalRdrEnv
- ; return (lookupLocalRdrEnv local_env rdr_name) }
-
-lookupLocalOccThLvl_maybe :: Name -> RnM (Maybe (TopLevelFlag, ThLevel))
--- Just look in the local environment
-lookupLocalOccThLvl_maybe name
- = do { lcl_env <- getLclEnv
- ; return (lookupNameEnv (tcl_th_bndrs lcl_env) name) }
-
--- lookupOccRn looks up an occurrence of a RdrName
-lookupOccRn :: RdrName -> RnM Name
-lookupOccRn rdr_name
- = do { mb_name <- lookupOccRn_maybe rdr_name
- ; case mb_name of
- Just name -> return name
- Nothing -> reportUnboundName rdr_name }
-
--- Only used in one place, to rename pattern synonym binders.
--- See Note [Renaming pattern synonym variables] in RnBinds
-lookupLocalOccRn :: RdrName -> RnM Name
-lookupLocalOccRn rdr_name
- = do { mb_name <- lookupLocalOccRn_maybe rdr_name
- ; case mb_name of
- Just name -> return name
- Nothing -> unboundName WL_LocalOnly rdr_name }
-
--- lookupPromotedOccRn looks up an optionally promoted RdrName.
-lookupTypeOccRn :: RdrName -> RnM Name
--- see Note [Demotion]
-lookupTypeOccRn rdr_name
- | isVarOcc (rdrNameOcc rdr_name) -- See Note [Promoted variables in types]
- = badVarInType rdr_name
- | otherwise
- = do { mb_name <- lookupOccRn_maybe rdr_name
- ; case mb_name of
- Just name -> return name
- Nothing -> lookup_demoted rdr_name }
-
-lookup_demoted :: RdrName -> RnM Name
-lookup_demoted rdr_name
- | Just demoted_rdr <- demoteRdrName rdr_name
- -- Maybe it's the name of a *data* constructor
- = do { data_kinds <- xoptM LangExt.DataKinds
- ; star_is_type <- xoptM LangExt.StarIsType
- ; let star_info = starInfo star_is_type rdr_name
- ; if data_kinds
- then do { mb_demoted_name <- lookupOccRn_maybe demoted_rdr
- ; case mb_demoted_name of
- Nothing -> unboundNameX WL_Any rdr_name star_info
- Just demoted_name ->
- do { whenWOptM Opt_WarnUntickedPromotedConstructors $
- addWarn
- (Reason Opt_WarnUntickedPromotedConstructors)
- (untickedPromConstrWarn demoted_name)
- ; return demoted_name } }
- else do { -- We need to check if a data constructor of this name is
- -- in scope to give good error messages. However, we do
- -- not want to give an additional error if the data
- -- constructor happens to be out of scope! See #13947.
- mb_demoted_name <- discardErrs $
- lookupOccRn_maybe demoted_rdr
- ; let suggestion | isJust mb_demoted_name = suggest_dk
- | otherwise = star_info
- ; unboundNameX WL_Any rdr_name suggestion } }
-
- | otherwise
- = reportUnboundName rdr_name
-
- where
- suggest_dk = text "A data constructor of that name is in scope; did you mean DataKinds?"
- untickedPromConstrWarn name =
- text "Unticked promoted constructor" <> colon <+> quotes (ppr name) <> dot
- $$
- hsep [ text "Use"
- , quotes (char '\'' <> ppr name)
- , text "instead of"
- , quotes (ppr name) <> dot ]
-
-badVarInType :: RdrName -> RnM Name
-badVarInType rdr_name
- = do { addErr (text "Illegal promoted term variable in a type:"
- <+> ppr rdr_name)
- ; return (mkUnboundNameRdr rdr_name) }
-
-{- Note [Promoted variables in types]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider this (#12686):
- x = True
- data Bad = Bad 'x
-
-The parser treats the quote in 'x as saying "use the term
-namespace", so we'll get (Bad x{v}), with 'x' in the
-VarName namespace. If we don't test for this, the renamer
-will happily rename it to the x bound at top level, and then
-the typecheck falls over because it doesn't have 'x' in scope
-when kind-checking.
-
-Note [Demotion]
-~~~~~~~~~~~~~~~
-When the user writes:
- data Nat = Zero | Succ Nat
- foo :: f Zero -> Int
-
-'Zero' in the type signature of 'foo' is parsed as:
- HsTyVar ("Zero", TcClsName)
-
-When the renamer hits this occurrence of 'Zero' it's going to realise
-that it's not in scope. But because it is renaming a type, it knows
-that 'Zero' might be a promoted data constructor, so it will demote
-its namespace to DataName and do a second lookup.
-
-The final result (after the renamer) will be:
- HsTyVar ("Zero", DataName)
--}
-
-lookupOccRnX_maybe :: (RdrName -> RnM (Maybe r)) -> (Name -> r) -> RdrName
- -> RnM (Maybe r)
-lookupOccRnX_maybe globalLookup wrapper rdr_name
- = runMaybeT . msum . map MaybeT $
- [ fmap wrapper <$> lookupLocalOccRn_maybe rdr_name
- , globalLookup rdr_name ]
-
-lookupOccRn_maybe :: RdrName -> RnM (Maybe Name)
-lookupOccRn_maybe = lookupOccRnX_maybe lookupGlobalOccRn_maybe id
-
-lookupOccRn_overloaded :: Bool -> RdrName
- -> RnM (Maybe (Either Name [Name]))
-lookupOccRn_overloaded overload_ok
- = lookupOccRnX_maybe global_lookup Left
- where
- global_lookup :: RdrName -> RnM (Maybe (Either Name [Name]))
- global_lookup n =
- runMaybeT . msum . map MaybeT $
- [ lookupGlobalOccRn_overloaded overload_ok n
- , fmap Left . listToMaybe <$> lookupQualifiedNameGHCi n ]
-
-
-
-lookupGlobalOccRn_maybe :: RdrName -> RnM (Maybe Name)
--- Looks up a RdrName occurrence in the top-level
--- environment, including using lookupQualifiedNameGHCi
--- for the GHCi case
--- No filter function; does not report an error on failure
--- Uses addUsedRdrName to record use and deprecations
-lookupGlobalOccRn_maybe rdr_name =
- lookupExactOrOrig rdr_name Just $
- runMaybeT . msum . map MaybeT $
- [ fmap gre_name <$> lookupGreRn_maybe rdr_name
- , listToMaybe <$> lookupQualifiedNameGHCi rdr_name ]
- -- This test is not expensive,
- -- and only happens for failed lookups
-
-lookupGlobalOccRn :: RdrName -> RnM Name
--- lookupGlobalOccRn is like lookupOccRn, except that it looks in the global
--- environment. Adds an error message if the RdrName is not in scope.
--- You usually want to use "lookupOccRn" which also looks in the local
--- environment.
-lookupGlobalOccRn rdr_name
- = do { mb_name <- lookupGlobalOccRn_maybe rdr_name
- ; case mb_name of
- Just n -> return n
- Nothing -> do { traceRn "lookupGlobalOccRn" (ppr rdr_name)
- ; unboundName WL_Global rdr_name } }
-
-lookupInfoOccRn :: RdrName -> RnM [Name]
--- lookupInfoOccRn is intended for use in GHCi's ":info" command
--- It finds all the GREs that RdrName could mean, not complaining
--- about ambiguity, but rather returning them all
--- C.f. #9881
-lookupInfoOccRn rdr_name =
- lookupExactOrOrig rdr_name (:[]) $
- do { rdr_env <- getGlobalRdrEnv
- ; let ns = map gre_name (lookupGRE_RdrName rdr_name rdr_env)
- ; qual_ns <- lookupQualifiedNameGHCi rdr_name
- ; return (ns ++ (qual_ns `minusList` ns)) }
-
--- | Like 'lookupOccRn_maybe', but with a more informative result if
--- the 'RdrName' happens to be a record selector:
---
--- * Nothing -> name not in scope (no error reported)
--- * Just (Left x) -> name uniquely refers to x,
--- or there is a name clash (reported)
--- * Just (Right xs) -> name refers to one or more record selectors;
--- if overload_ok was False, this list will be
--- a singleton.
-
-lookupGlobalOccRn_overloaded :: Bool -> RdrName
- -> RnM (Maybe (Either Name [Name]))
-lookupGlobalOccRn_overloaded overload_ok rdr_name =
- lookupExactOrOrig rdr_name (Just . Left) $
- do { res <- lookupGreRn_helper rdr_name
- ; case res of
- GreNotFound -> return Nothing
- OneNameMatch gre -> do
- let wrapper = if isRecFldGRE gre then Right . (:[]) else Left
- return $ Just (wrapper (gre_name gre))
- MultipleNames gres | all isRecFldGRE gres && overload_ok ->
- -- Don't record usage for ambiguous selectors
- -- until we know which is meant
- return $ Just (Right (map gre_name gres))
- MultipleNames gres -> do
- addNameClashErrRn rdr_name gres
- return (Just (Left (gre_name (head gres)))) }
-
-
---------------------------------------------------
--- Lookup in the Global RdrEnv of the module
---------------------------------------------------
-
-data GreLookupResult = GreNotFound
- | OneNameMatch GlobalRdrElt
- | MultipleNames [GlobalRdrElt]
-
-lookupGreRn_maybe :: RdrName -> RnM (Maybe GlobalRdrElt)
--- Look up the RdrName in the GlobalRdrEnv
--- Exactly one binding: records it as "used", return (Just gre)
--- No bindings: return Nothing
--- Many bindings: report "ambiguous", return an arbitrary (Just gre)
--- Uses addUsedRdrName to record use and deprecations
-lookupGreRn_maybe rdr_name
- = do
- res <- lookupGreRn_helper rdr_name
- case res of
- OneNameMatch gre -> return $ Just gre
- MultipleNames gres -> do
- traceRn "lookupGreRn_maybe:NameClash" (ppr gres)
- addNameClashErrRn rdr_name gres
- return $ Just (head gres)
- GreNotFound -> return Nothing
-
-{-
-
-Note [ Unbound vs Ambiguous Names ]
-
-lookupGreRn_maybe deals with failures in two different ways. If a name
-is unbound then we return a `Nothing` but if the name is ambiguous
-then we raise an error and return a dummy name.
-
-The reason for this is that when we call `lookupGreRn_maybe` we are
-speculatively looking for whatever we are looking up. If we don't find it,
-then we might have been looking for the wrong thing and can keep trying.
-On the other hand, if we find a clash then there is no way to recover as
-we found the thing we were looking for but can no longer resolve which
-the correct one is.
-
-One example of this is in `lookupTypeOccRn` which first looks in the type
-constructor namespace before looking in the data constructor namespace to
-deal with `DataKinds`.
-
-There is however, as always, one exception to this scheme. If we find
-an ambiguous occurrence of a record selector and DuplicateRecordFields
-is enabled then we defer the selection until the typechecker.
-
--}
-
-
-
-
--- Internal Function
-lookupGreRn_helper :: RdrName -> RnM GreLookupResult
-lookupGreRn_helper rdr_name
- = do { env <- getGlobalRdrEnv
- ; case lookupGRE_RdrName rdr_name env of
- [] -> return GreNotFound
- [gre] -> do { addUsedGRE True gre
- ; return (OneNameMatch gre) }
- gres -> return (MultipleNames gres) }
-
-lookupGreAvailRn :: RdrName -> RnM (Name, AvailInfo)
--- Used in export lists
--- If not found or ambiguous, add error message, and fake with UnboundName
--- Uses addUsedRdrName to record use and deprecations
-lookupGreAvailRn rdr_name
- = do
- mb_gre <- lookupGreRn_helper rdr_name
- case mb_gre of
- GreNotFound ->
- do
- traceRn "lookupGreAvailRn" (ppr rdr_name)
- name <- unboundName WL_Global rdr_name
- return (name, avail name)
- MultipleNames gres ->
- do
- addNameClashErrRn rdr_name gres
- let unbound_name = mkUnboundNameRdr rdr_name
- return (unbound_name, avail unbound_name)
- -- Returning an unbound name here prevents an error
- -- cascade
- OneNameMatch gre ->
- return (gre_name gre, availFromGRE gre)
-
-
-{-
-*********************************************************
-* *
- Deprecations
-* *
-*********************************************************
-
-Note [Handling of deprecations]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* We report deprecations at each *occurrence* of the deprecated thing
- (see #5867)
-
-* We do not report deprecations for locally-defined names. For a
- start, we may be exporting a deprecated thing. Also we may use a
- deprecated thing in the defn of another deprecated things. We may
- even use a deprecated thing in the defn of a non-deprecated thing,
- when changing a module's interface.
-
-* addUsedGREs: we do not report deprecations for sub-binders:
- - the ".." completion for records
- - the ".." in an export item 'T(..)'
- - the things exported by a module export 'module M'
--}
-
-addUsedDataCons :: GlobalRdrEnv -> TyCon -> RnM ()
--- Remember use of in-scope data constructors (#7969)
-addUsedDataCons rdr_env tycon
- = addUsedGREs [ gre
- | dc <- tyConDataCons tycon
- , Just gre <- [lookupGRE_Name rdr_env (dataConName dc)] ]
-
-addUsedGRE :: Bool -> GlobalRdrElt -> RnM ()
--- Called for both local and imported things
--- Add usage *and* warn if deprecated
-addUsedGRE warn_if_deprec gre
- = do { when warn_if_deprec (warnIfDeprecated gre)
- ; unless (isLocalGRE gre) $
- do { env <- getGblEnv
- ; traceRn "addUsedGRE" (ppr gre)
- ; updMutVar (tcg_used_gres env) (gre :) } }
-
-addUsedGREs :: [GlobalRdrElt] -> RnM ()
--- Record uses of any *imported* GREs
--- Used for recording used sub-bndrs
--- NB: no call to warnIfDeprecated; see Note [Handling of deprecations]
-addUsedGREs gres
- | null imp_gres = return ()
- | otherwise = do { env <- getGblEnv
- ; traceRn "addUsedGREs" (ppr imp_gres)
- ; updMutVar (tcg_used_gres env) (imp_gres ++) }
- where
- imp_gres = filterOut isLocalGRE gres
-
-warnIfDeprecated :: GlobalRdrElt -> RnM ()
-warnIfDeprecated gre@(GRE { gre_name = name, gre_imp = iss })
- | (imp_spec : _) <- iss
- = do { dflags <- getDynFlags
- ; this_mod <- getModule
- ; when (wopt Opt_WarnWarningsDeprecations dflags &&
- not (nameIsLocalOrFrom this_mod name)) $
- -- See Note [Handling of deprecations]
- do { iface <- loadInterfaceForName doc name
- ; case lookupImpDeprec iface gre of
- Just txt -> addWarn (Reason Opt_WarnWarningsDeprecations)
- (mk_msg imp_spec txt)
- Nothing -> return () } }
- | otherwise
- = return ()
- where
- occ = greOccName gre
- name_mod = ASSERT2( isExternalName name, ppr name ) nameModule name
- doc = text "The name" <+> quotes (ppr occ) <+> ptext (sLit "is mentioned explicitly")
-
- mk_msg imp_spec txt
- = sep [ sep [ text "In the use of"
- <+> pprNonVarNameSpace (occNameSpace occ)
- <+> quotes (ppr occ)
- , parens imp_msg <> colon ]
- , pprWarningTxtForMsg txt ]
- where
- imp_mod = importSpecModule imp_spec
- imp_msg = text "imported from" <+> ppr imp_mod <> extra
- extra | imp_mod == moduleName name_mod = Outputable.empty
- | otherwise = text ", but defined in" <+> ppr name_mod
-
-lookupImpDeprec :: ModIface -> GlobalRdrElt -> Maybe WarningTxt
-lookupImpDeprec iface gre
- = mi_warn_fn (mi_final_exts iface) (greOccName gre) `mplus` -- Bleat if the thing,
- case gre_par gre of -- or its parent, is warn'd
- ParentIs p -> mi_warn_fn (mi_final_exts iface) (nameOccName p)
- FldParent { par_is = p } -> mi_warn_fn (mi_final_exts iface) (nameOccName p)
- NoParent -> Nothing
-
-{-
-Note [Used names with interface not loaded]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-It's (just) possible to find a used
-Name whose interface hasn't been loaded:
-
-a) It might be a WiredInName; in that case we may not load
- its interface (although we could).
-
-b) It might be GHC.Real.fromRational, or GHC.Num.fromInteger
- These are seen as "used" by the renamer (if -XRebindableSyntax)
- is on), but the typechecker may discard their uses
- if in fact the in-scope fromRational is GHC.Read.fromRational,
- (see tcPat.tcOverloadedLit), and the typechecker sees that the type
- is fixed, say, to GHC.Base.Float (see Inst.lookupSimpleInst).
- In that obscure case it won't force the interface in.
-
-In both cases we simply don't permit deprecations;
-this is, after all, wired-in stuff.
-
-
-*********************************************************
-* *
- GHCi support
-* *
-*********************************************************
-
-A qualified name on the command line can refer to any module at
-all: we try to load the interface if we don't already have it, just
-as if there was an "import qualified M" declaration for every
-module.
-
-For example, writing `Data.List.sort` will load the interface file for
-`Data.List` as if the user had written `import qualified Data.List`.
-
-If we fail we just return Nothing, rather than bleating
-about "attempting to use module ‘D’ (./D.hs) which is not loaded"
-which is what loadSrcInterface does.
-
-It is enabled by default and disabled by the flag
-`-fno-implicit-import-qualified`.
-
-Note [Safe Haskell and GHCi]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We DON'T do this Safe Haskell as we need to check imports. We can
-and should instead check the qualified import but at the moment
-this requires some refactoring so leave as a TODO
--}
-
-
-
-lookupQualifiedNameGHCi :: RdrName -> RnM [Name]
-lookupQualifiedNameGHCi rdr_name
- = -- We want to behave as we would for a source file import here,
- -- and respect hiddenness of modules/packages, hence loadSrcInterface.
- do { dflags <- getDynFlags
- ; is_ghci <- getIsGHCi
- ; go_for_it dflags is_ghci }
-
- where
- go_for_it dflags is_ghci
- | Just (mod,occ) <- isQual_maybe rdr_name
- , is_ghci
- , gopt Opt_ImplicitImportQualified dflags -- Enables this GHCi behaviour
- , not (safeDirectImpsReq dflags) -- See Note [Safe Haskell and GHCi]
- = do { res <- loadSrcInterface_maybe doc mod False Nothing
- ; case res of
- Succeeded iface
- -> return [ name
- | avail <- mi_exports iface
- , name <- availNames avail
- , nameOccName name == occ ]
-
- _ -> -- Either we couldn't load the interface, or
- -- we could but we didn't find the name in it
- do { traceRn "lookupQualifiedNameGHCi" (ppr rdr_name)
- ; return [] } }
-
- | otherwise
- = do { traceRn "lookupQualifiedNameGHCi: off" (ppr rdr_name)
- ; return [] }
-
- doc = text "Need to find" <+> ppr rdr_name
-
-{-
-Note [Looking up signature names]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-lookupSigOccRn is used for type signatures and pragmas
-Is this valid?
- module A
- import M( f )
- f :: Int -> Int
- f x = x
-It's clear that the 'f' in the signature must refer to A.f
-The Haskell98 report does not stipulate this, but it will!
-So we must treat the 'f' in the signature in the same way
-as the binding occurrence of 'f', using lookupBndrRn
-
-However, consider this case:
- import M( f )
- f :: Int -> Int
- g x = x
-We don't want to say 'f' is out of scope; instead, we want to
-return the imported 'f', so that later on the renamer will
-correctly report "misplaced type sig".
-
-Note [Signatures for top level things]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-data HsSigCtxt = ... | TopSigCtxt NameSet | ....
-
-* The NameSet says what is bound in this group of bindings.
- We can't use isLocalGRE from the GlobalRdrEnv, because of this:
- f x = x
- $( ...some TH splice... )
- f :: Int -> Int
- When we encounter the signature for 'f', the binding for 'f'
- will be in the GlobalRdrEnv, and will be a LocalDef. Yet the
- signature is mis-placed
-
-* For type signatures the NameSet should be the names bound by the
- value bindings; for fixity declarations, the NameSet should also
- include class sigs and record selectors
-
- infix 3 `f` -- Yes, ok
- f :: C a => a -> a -- No, not ok
- class C a where
- f :: a -> a
--}
-
-data HsSigCtxt
- = TopSigCtxt NameSet -- At top level, binding these names
- -- See Note [Signatures for top level things]
- | LocalBindCtxt NameSet -- In a local binding, binding these names
- | ClsDeclCtxt Name -- Class decl for this class
- | InstDeclCtxt NameSet -- Instance decl whose user-written method
- -- bindings are for these methods
- | HsBootCtxt NameSet -- Top level of a hs-boot file, binding these names
- | RoleAnnotCtxt NameSet -- A role annotation, with the names of all types
- -- in the group
-
-instance Outputable HsSigCtxt where
- ppr (TopSigCtxt ns) = text "TopSigCtxt" <+> ppr ns
- ppr (LocalBindCtxt ns) = text "LocalBindCtxt" <+> ppr ns
- ppr (ClsDeclCtxt n) = text "ClsDeclCtxt" <+> ppr n
- ppr (InstDeclCtxt ns) = text "InstDeclCtxt" <+> ppr ns
- ppr (HsBootCtxt ns) = text "HsBootCtxt" <+> ppr ns
- ppr (RoleAnnotCtxt ns) = text "RoleAnnotCtxt" <+> ppr ns
-
-lookupSigOccRn :: HsSigCtxt
- -> Sig GhcPs
- -> Located RdrName -> RnM (Located Name)
-lookupSigOccRn ctxt sig = lookupSigCtxtOccRn ctxt (hsSigDoc sig)
-
--- | Lookup a name in relation to the names in a 'HsSigCtxt'
-lookupSigCtxtOccRn :: HsSigCtxt
- -> SDoc -- ^ description of thing we're looking up,
- -- like "type family"
- -> Located RdrName -> RnM (Located Name)
-lookupSigCtxtOccRn ctxt what
- = wrapLocM $ \ rdr_name ->
- do { mb_name <- lookupBindGroupOcc ctxt what rdr_name
- ; case mb_name of
- Left err -> do { addErr err; return (mkUnboundNameRdr rdr_name) }
- Right name -> return name }
-
-lookupBindGroupOcc :: HsSigCtxt
- -> SDoc
- -> RdrName -> RnM (Either MsgDoc Name)
--- Looks up the RdrName, expecting it to resolve to one of the
--- bound names passed in. If not, return an appropriate error message
---
--- See Note [Looking up signature names]
-lookupBindGroupOcc ctxt what rdr_name
- | Just n <- isExact_maybe rdr_name
- = lookupExactOcc_either n -- allow for the possibility of missing Exacts;
- -- see Note [dataTcOccs and Exact Names]
- -- Maybe we should check the side conditions
- -- but it's a pain, and Exact things only show
- -- up when you know what you are doing
-
- | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name
- = do { n' <- lookupOrig rdr_mod rdr_occ
- ; return (Right n') }
-
- | otherwise
- = case ctxt of
- HsBootCtxt ns -> lookup_top (`elemNameSet` ns)
- TopSigCtxt ns -> lookup_top (`elemNameSet` ns)
- RoleAnnotCtxt ns -> lookup_top (`elemNameSet` ns)
- LocalBindCtxt ns -> lookup_group ns
- ClsDeclCtxt cls -> lookup_cls_op cls
- InstDeclCtxt ns -> if uniqSetAny isUnboundName ns -- #16610
- then return (Right $ mkUnboundNameRdr rdr_name)
- else lookup_top (`elemNameSet` ns)
- where
- lookup_cls_op cls
- = lookupSubBndrOcc True cls doc rdr_name
- where
- doc = text "method of class" <+> quotes (ppr cls)
-
- lookup_top keep_me
- = do { env <- getGlobalRdrEnv
- ; let all_gres = lookupGlobalRdrEnv env (rdrNameOcc rdr_name)
- names_in_scope = -- If rdr_name lacks a binding, only
- -- recommend alternatives from related
- -- namespaces. See #17593.
- filter (\n -> nameSpacesRelated
- (rdrNameSpace rdr_name)
- (nameNameSpace n))
- $ map gre_name
- $ filter isLocalGRE
- $ globalRdrEnvElts env
- candidates_msg = candidates names_in_scope
- ; case filter (keep_me . gre_name) all_gres of
- [] | null all_gres -> bale_out_with candidates_msg
- | otherwise -> bale_out_with local_msg
- (gre:_) -> return (Right (gre_name gre)) }
-
- lookup_group bound_names -- Look in the local envt (not top level)
- = do { mname <- lookupLocalOccRn_maybe rdr_name
- ; env <- getLocalRdrEnv
- ; let candidates_msg = candidates $ localRdrEnvElts env
- ; case mname of
- Just n
- | n `elemNameSet` bound_names -> return (Right n)
- | otherwise -> bale_out_with local_msg
- Nothing -> bale_out_with candidates_msg }
-
- bale_out_with msg
- = return (Left (sep [ text "The" <+> what
- <+> text "for" <+> quotes (ppr rdr_name)
- , nest 2 $ text "lacks an accompanying binding"]
- $$ nest 2 msg))
-
- local_msg = parens $ text "The" <+> what <+> ptext (sLit "must be given where")
- <+> quotes (ppr rdr_name) <+> text "is declared"
-
- -- Identify all similar names and produce a message listing them
- candidates :: [Name] -> MsgDoc
- candidates names_in_scope
- = case similar_names of
- [] -> Outputable.empty
- [n] -> text "Perhaps you meant" <+> pp_item n
- _ -> sep [ text "Perhaps you meant one of these:"
- , nest 2 (pprWithCommas pp_item similar_names) ]
- where
- similar_names
- = fuzzyLookup (unpackFS $ occNameFS $ rdrNameOcc rdr_name)
- $ map (\x -> ((unpackFS $ occNameFS $ nameOccName x), x))
- names_in_scope
-
- pp_item x = quotes (ppr x) <+> parens (pprDefinedAt x)
-
-
----------------
-lookupLocalTcNames :: HsSigCtxt -> SDoc -> RdrName -> RnM [(RdrName, Name)]
--- GHC extension: look up both the tycon and data con or variable.
--- Used for top-level fixity signatures and deprecations.
--- Complain if neither is in scope.
--- See Note [Fixity signature lookup]
-lookupLocalTcNames ctxt what rdr_name
- = do { mb_gres <- mapM lookup (dataTcOccs rdr_name)
- ; let (errs, names) = partitionEithers mb_gres
- ; when (null names) $ addErr (head errs) -- Bleat about one only
- ; return names }
- where
- lookup rdr = do { this_mod <- getModule
- ; nameEither <- lookupBindGroupOcc ctxt what rdr
- ; return (guard_builtin_syntax this_mod rdr nameEither) }
-
- -- Guard against the built-in syntax (ex: `infixl 6 :`), see #15233
- guard_builtin_syntax this_mod rdr (Right name)
- | Just _ <- isBuiltInOcc_maybe (occName rdr)
- , this_mod /= nameModule name
- = Left (hsep [text "Illegal", what, text "of built-in syntax:", ppr rdr])
- | otherwise
- = Right (rdr, name)
- guard_builtin_syntax _ _ (Left err) = Left err
-
-dataTcOccs :: RdrName -> [RdrName]
--- Return both the given name and the same name promoted to the TcClsName
--- namespace. This is useful when we aren't sure which we are looking at.
--- See also Note [dataTcOccs and Exact Names]
-dataTcOccs rdr_name
- | isDataOcc occ || isVarOcc occ
- = [rdr_name, rdr_name_tc]
- | otherwise
- = [rdr_name]
- where
- occ = rdrNameOcc rdr_name
- rdr_name_tc =
- case rdr_name of
- -- The (~) type operator is always in scope, so we need a special case
- -- for it here, or else :info (~) fails in GHCi.
- -- See Note [eqTyCon (~) is built-in syntax]
- Unqual occ | occNameFS occ == fsLit "~" -> eqTyCon_RDR
- _ -> setRdrNameSpace rdr_name tcName
-
-{-
-Note [dataTcOccs and Exact Names]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Exact RdrNames can occur in code generated by Template Haskell, and generally
-those references are, well, exact. However, the TH `Name` type isn't expressive
-enough to always track the correct namespace information, so we sometimes get
-the right Unique but wrong namespace. Thus, we still have to do the double-lookup
-for Exact RdrNames.
-
-There is also an awkward situation for built-in syntax. Example in GHCi
- :info []
-This parses as the Exact RdrName for nilDataCon, but we also want
-the list type constructor.
-
-Note that setRdrNameSpace on an Exact name requires the Name to be External,
-which it always is for built in syntax.
--}
-
-
-
-{-
-************************************************************************
-* *
- Rebindable names
- Dealing with rebindable syntax is driven by the
- Opt_RebindableSyntax dynamic flag.
-
- In "deriving" code we don't want to use rebindable syntax
- so we switch off the flag locally
-
-* *
-************************************************************************
-
-Haskell 98 says that when you say "3" you get the "fromInteger" from the
-Standard Prelude, regardless of what is in scope. However, to experiment
-with having a language that is less coupled to the standard prelude, we're
-trying a non-standard extension that instead gives you whatever "Prelude.fromInteger"
-happens to be in scope. Then you can
- import Prelude ()
- import MyPrelude as Prelude
-to get the desired effect.
-
-At the moment this just happens for
- * fromInteger, fromRational on literals (in expressions and patterns)
- * negate (in expressions)
- * minus (arising from n+k patterns)
- * "do" notation
-
-We store the relevant Name in the HsSyn tree, in
- * HsIntegral/HsFractional/HsIsString
- * NegApp
- * NPlusKPat
- * HsDo
-respectively. Initially, we just store the "standard" name (PrelNames.fromIntegralName,
-fromRationalName etc), but the renamer changes this to the appropriate user
-name if Opt_NoImplicitPrelude is on. That is what lookupSyntaxName does.
-
-We treat the original (standard) names as free-vars too, because the type checker
-checks the type of the user thing against the type of the standard thing.
--}
-
-lookupIfThenElse :: RnM (Maybe (SyntaxExpr GhcRn), FreeVars)
--- Different to lookupSyntaxName because in the non-rebindable
--- case we desugar directly rather than calling an existing function
--- Hence the (Maybe (SyntaxExpr GhcRn)) return type
-lookupIfThenElse
- = do { rebindable_on <- xoptM LangExt.RebindableSyntax
- ; if not rebindable_on
- then return (Nothing, emptyFVs)
- else do { ite <- lookupOccRn (mkVarUnqual (fsLit "ifThenElse"))
- ; return ( Just (mkRnSyntaxExpr ite)
- , unitFV ite ) } }
-
-lookupSyntaxName' :: Name -- ^ The standard name
- -> RnM Name -- ^ Possibly a non-standard name
-lookupSyntaxName' std_name
- = do { rebindable_on <- xoptM LangExt.RebindableSyntax
- ; if not rebindable_on then
- return std_name
- else
- -- Get the similarly named thing from the local environment
- lookupOccRn (mkRdrUnqual (nameOccName std_name)) }
-
-lookupSyntaxName :: Name -- The standard name
- -> RnM (SyntaxExpr GhcRn, FreeVars) -- Possibly a non-standard
- -- name
-lookupSyntaxName std_name
- = do { rebindable_on <- xoptM LangExt.RebindableSyntax
- ; if not rebindable_on then
- return (mkRnSyntaxExpr std_name, emptyFVs)
- else
- -- Get the similarly named thing from the local environment
- do { usr_name <- lookupOccRn (mkRdrUnqual (nameOccName std_name))
- ; return (mkRnSyntaxExpr usr_name, unitFV usr_name) } }
-
-lookupSyntaxNames :: [Name] -- Standard names
- -> RnM ([HsExpr GhcRn], FreeVars) -- See comments with HsExpr.ReboundNames
- -- this works with CmdTop, which wants HsExprs, not SyntaxExprs
-lookupSyntaxNames std_names
- = do { rebindable_on <- xoptM LangExt.RebindableSyntax
- ; if not rebindable_on then
- return (map (HsVar noExtField . noLoc) std_names, emptyFVs)
- else
- do { usr_names <- mapM (lookupOccRn . mkRdrUnqual . nameOccName) std_names
- ; return (map (HsVar noExtField . noLoc) usr_names, mkFVs usr_names) } }
-
--- Error messages
-
-
-opDeclErr :: RdrName -> SDoc
-opDeclErr n
- = hang (text "Illegal declaration of a type or class operator" <+> quotes (ppr n))
- 2 (text "Use TypeOperators to declare operators in type and declarations")
-
-badOrigBinding :: RdrName -> SDoc
-badOrigBinding name
- | Just _ <- isBuiltInOcc_maybe occ
- = text "Illegal binding of built-in syntax:" <+> ppr occ
- -- Use an OccName here because we don't want to print Prelude.(,)
- | otherwise
- = text "Cannot redefine a Name retrieved by a Template Haskell quote:"
- <+> ppr name
- -- This can happen when one tries to use a Template Haskell splice to
- -- define a top-level identifier with an already existing name, e.g.,
- --
- -- $(pure [ValD (VarP 'succ) (NormalB (ConE 'True)) []])
- --
- -- (See #13968.)
- where
- occ = rdrNameOcc $ filterCTuple name
diff --git a/compiler/rename/RnExpr.hs b/compiler/rename/RnExpr.hs
deleted file mode 100644
index 693d818f67..0000000000
--- a/compiler/rename/RnExpr.hs
+++ /dev/null
@@ -1,2210 +0,0 @@
-{-
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-\section[RnExpr]{Renaming of expressions}
-
-Basically dependency analysis.
-
-Handles @Match@, @GRHSs@, @HsExpr@, and @Qualifier@ datatypes. In
-general, all of these functions return a renamed thing, and a set of
-free variables.
--}
-
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE MultiWayIf #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE ViewPatterns #-}
-
-module RnExpr (
- rnLExpr, rnExpr, rnStmts
- ) where
-
-#include "HsVersions.h"
-
-import GhcPrelude
-
-import RnBinds ( rnLocalBindsAndThen, rnLocalValBindsLHS, rnLocalValBindsRHS,
- rnMatchGroup, rnGRHS, makeMiniFixityEnv)
-import GHC.Hs
-import TcEnv ( isBrackStage )
-import TcRnMonad
-import Module ( getModule )
-import RnEnv
-import RnFixity
-import RnUtils ( HsDocContext(..), bindLocalNamesFV, checkDupNames
- , bindLocalNames
- , mapMaybeFvRn, mapFvRn
- , warnUnusedLocalBinds, typeAppErr
- , checkUnusedRecordWildcard )
-import RnUnbound ( reportUnboundName )
-import RnSplice ( rnBracket, rnSpliceExpr, checkThLocalName )
-import RnTypes
-import RnPat
-import DynFlags
-import PrelNames
-
-import BasicTypes
-import Name
-import NameSet
-import RdrName
-import UniqSet
-import Data.List
-import Util
-import ListSetOps ( removeDups )
-import ErrUtils
-import Outputable
-import SrcLoc
-import FastString
-import Control.Monad
-import TysWiredIn ( nilDataConName )
-import qualified GHC.LanguageExtensions as LangExt
-
-import Data.Ord
-import Data.Array
-import qualified Data.List.NonEmpty as NE
-
-import Unique ( mkVarOccUnique )
-
-{-
-************************************************************************
-* *
-\subsubsection{Expressions}
-* *
-************************************************************************
--}
-
-rnExprs :: [LHsExpr GhcPs] -> RnM ([LHsExpr GhcRn], FreeVars)
-rnExprs ls = rnExprs' ls emptyUniqSet
- where
- rnExprs' [] acc = return ([], acc)
- rnExprs' (expr:exprs) acc =
- do { (expr', fvExpr) <- rnLExpr expr
- -- Now we do a "seq" on the free vars because typically it's small
- -- or empty, especially in very long lists of constants
- ; let acc' = acc `plusFV` fvExpr
- ; (exprs', fvExprs) <- acc' `seq` rnExprs' exprs acc'
- ; return (expr':exprs', fvExprs) }
-
--- Variables. We look up the variable and return the resulting name.
-
-rnLExpr :: LHsExpr GhcPs -> RnM (LHsExpr GhcRn, FreeVars)
-rnLExpr = wrapLocFstM rnExpr
-
-rnExpr :: HsExpr GhcPs -> RnM (HsExpr GhcRn, FreeVars)
-
-finishHsVar :: Located Name -> RnM (HsExpr GhcRn, FreeVars)
--- Separated from rnExpr because it's also used
--- when renaming infix expressions
-finishHsVar (L l name)
- = do { this_mod <- getModule
- ; when (nameIsLocalOrFrom this_mod name) $
- checkThLocalName name
- ; return (HsVar noExtField (L l name), unitFV name) }
-
-rnUnboundVar :: RdrName -> RnM (HsExpr GhcRn, FreeVars)
-rnUnboundVar v
- = do { if isUnqual v
- then -- Treat this as a "hole"
- -- Do not fail right now; instead, return HsUnboundVar
- -- and let the type checker report the error
- return (HsUnboundVar noExtField (rdrNameOcc v), emptyFVs)
-
- else -- Fail immediately (qualified name)
- do { n <- reportUnboundName v
- ; return (HsVar noExtField (noLoc n), emptyFVs) } }
-
-rnExpr (HsVar _ (L l v))
- = do { opt_DuplicateRecordFields <- xoptM LangExt.DuplicateRecordFields
- ; mb_name <- lookupOccRn_overloaded opt_DuplicateRecordFields v
- ; dflags <- getDynFlags
- ; case mb_name of {
- Nothing -> rnUnboundVar v ;
- Just (Left name)
- | name == nilDataConName -- Treat [] as an ExplicitList, so that
- -- OverloadedLists works correctly
- -- Note [Empty lists] in GHC.Hs.Expr
- , xopt LangExt.OverloadedLists dflags
- -> rnExpr (ExplicitList noExtField Nothing [])
-
- | otherwise
- -> finishHsVar (L l name) ;
- Just (Right [s]) ->
- return ( HsRecFld noExtField (Unambiguous s (L l v) ), unitFV s) ;
- Just (Right fs@(_:_:_)) ->
- return ( HsRecFld noExtField (Ambiguous noExtField (L l v))
- , mkFVs fs);
- Just (Right []) -> panic "runExpr/HsVar" } }
-
-rnExpr (HsIPVar x v)
- = return (HsIPVar x v, emptyFVs)
-
-rnExpr (HsUnboundVar x v)
- = return (HsUnboundVar x v, emptyFVs)
-
-rnExpr (HsOverLabel x _ v)
- = do { rebindable_on <- xoptM LangExt.RebindableSyntax
- ; if rebindable_on
- then do { fromLabel <- lookupOccRn (mkVarUnqual (fsLit "fromLabel"))
- ; return (HsOverLabel x (Just fromLabel) v, unitFV fromLabel) }
- else return (HsOverLabel x Nothing v, emptyFVs) }
-
-rnExpr (HsLit x lit@(HsString src s))
- = do { opt_OverloadedStrings <- xoptM LangExt.OverloadedStrings
- ; if opt_OverloadedStrings then
- rnExpr (HsOverLit x (mkHsIsString src s))
- else do {
- ; rnLit lit
- ; return (HsLit x (convertLit lit), emptyFVs) } }
-
-rnExpr (HsLit x lit)
- = do { rnLit lit
- ; return (HsLit x(convertLit lit), emptyFVs) }
-
-rnExpr (HsOverLit x lit)
- = do { ((lit', mb_neg), fvs) <- rnOverLit lit -- See Note [Negative zero]
- ; case mb_neg of
- Nothing -> return (HsOverLit x lit', fvs)
- Just neg -> return (HsApp x (noLoc neg) (noLoc (HsOverLit x lit'))
- , fvs ) }
-
-rnExpr (HsApp x fun arg)
- = do { (fun',fvFun) <- rnLExpr fun
- ; (arg',fvArg) <- rnLExpr arg
- ; return (HsApp x fun' arg', fvFun `plusFV` fvArg) }
-
-rnExpr (HsAppType x fun arg)
- = do { type_app <- xoptM LangExt.TypeApplications
- ; unless type_app $ addErr $ typeAppErr "type" $ hswc_body arg
- ; (fun',fvFun) <- rnLExpr fun
- ; (arg',fvArg) <- rnHsWcType HsTypeCtx arg
- ; return (HsAppType x fun' arg', fvFun `plusFV` fvArg) }
-
-rnExpr (OpApp _ e1 op e2)
- = do { (e1', fv_e1) <- rnLExpr e1
- ; (e2', fv_e2) <- rnLExpr e2
- ; (op', fv_op) <- rnLExpr op
-
- -- Deal with fixity
- -- When renaming code synthesised from "deriving" declarations
- -- we used to avoid fixity stuff, but we can't easily tell any
- -- more, so I've removed the test. Adding HsPars in TcGenDeriv
- -- should prevent bad things happening.
- ; fixity <- case op' of
- L _ (HsVar _ (L _ n)) -> lookupFixityRn n
- L _ (HsRecFld _ f) -> lookupFieldFixityRn f
- _ -> return (Fixity NoSourceText minPrecedence InfixL)
- -- c.f. lookupFixity for unbound
-
- ; final_e <- mkOpAppRn e1' op' fixity e2'
- ; return (final_e, fv_e1 `plusFV` fv_op `plusFV` fv_e2) }
-
-rnExpr (NegApp _ e _)
- = do { (e', fv_e) <- rnLExpr e
- ; (neg_name, fv_neg) <- lookupSyntaxName negateName
- ; final_e <- mkNegAppRn e' neg_name
- ; return (final_e, fv_e `plusFV` fv_neg) }
-
-------------------------------------------
--- Template Haskell extensions
-rnExpr e@(HsBracket _ br_body) = rnBracket e br_body
-
-rnExpr (HsSpliceE _ splice) = rnSpliceExpr splice
-
----------------------------------------------
--- Sections
--- See Note [Parsing sections] in Parser.y
-rnExpr (HsPar x (L loc (section@(SectionL {}))))
- = do { (section', fvs) <- rnSection section
- ; return (HsPar x (L loc section'), fvs) }
-
-rnExpr (HsPar x (L loc (section@(SectionR {}))))
- = do { (section', fvs) <- rnSection section
- ; return (HsPar x (L loc section'), fvs) }
-
-rnExpr (HsPar x e)
- = do { (e', fvs_e) <- rnLExpr e
- ; return (HsPar x e', fvs_e) }
-
-rnExpr expr@(SectionL {})
- = do { addErr (sectionErr expr); rnSection expr }
-rnExpr expr@(SectionR {})
- = do { addErr (sectionErr expr); rnSection expr }
-
----------------------------------------------
-rnExpr (HsPragE x prag expr)
- = do { (expr', fvs_expr) <- rnLExpr expr
- ; return (HsPragE x (rn_prag prag) expr', fvs_expr) }
- where
- rn_prag :: HsPragE GhcPs -> HsPragE GhcRn
- rn_prag (HsPragSCC x1 src ann) = HsPragSCC x1 src ann
- rn_prag (HsPragCore x1 src lbl) = HsPragCore x1 src lbl
- rn_prag (HsPragTick x1 src info srcInfo) = HsPragTick x1 src info srcInfo
- rn_prag (XHsPragE x) = noExtCon x
-
-rnExpr (HsLam x matches)
- = do { (matches', fvMatch) <- rnMatchGroup LambdaExpr rnLExpr matches
- ; return (HsLam x matches', fvMatch) }
-
-rnExpr (HsLamCase x matches)
- = do { (matches', fvs_ms) <- rnMatchGroup CaseAlt rnLExpr matches
- ; return (HsLamCase x matches', fvs_ms) }
-
-rnExpr (HsCase x expr matches)
- = do { (new_expr, e_fvs) <- rnLExpr expr
- ; (new_matches, ms_fvs) <- rnMatchGroup CaseAlt rnLExpr matches
- ; return (HsCase x new_expr new_matches, e_fvs `plusFV` ms_fvs) }
-
-rnExpr (HsLet x (L l binds) expr)
- = rnLocalBindsAndThen binds $ \binds' _ -> do
- { (expr',fvExpr) <- rnLExpr expr
- ; return (HsLet x (L l binds') expr', fvExpr) }
-
-rnExpr (HsDo x do_or_lc (L l stmts))
- = do { ((stmts', _), fvs) <-
- rnStmtsWithPostProcessing do_or_lc rnLExpr
- postProcessStmtsForApplicativeDo stmts
- (\ _ -> return ((), emptyFVs))
- ; return ( HsDo x do_or_lc (L l stmts'), fvs ) }
-
-rnExpr (ExplicitList x _ exps)
- = do { opt_OverloadedLists <- xoptM LangExt.OverloadedLists
- ; (exps', fvs) <- rnExprs exps
- ; if opt_OverloadedLists
- then do {
- ; (from_list_n_name, fvs') <- lookupSyntaxName fromListNName
- ; return (ExplicitList x (Just from_list_n_name) exps'
- , fvs `plusFV` fvs') }
- else
- return (ExplicitList x Nothing exps', fvs) }
-
-rnExpr (ExplicitTuple x tup_args boxity)
- = do { checkTupleSection tup_args
- ; checkTupSize (length tup_args)
- ; (tup_args', fvs) <- mapAndUnzipM rnTupArg tup_args
- ; return (ExplicitTuple x tup_args' boxity, plusFVs fvs) }
- where
- rnTupArg (L l (Present x e)) = do { (e',fvs) <- rnLExpr e
- ; return (L l (Present x e'), fvs) }
- rnTupArg (L l (Missing _)) = return (L l (Missing noExtField)
- , emptyFVs)
- rnTupArg (L _ (XTupArg nec)) = noExtCon nec
-
-rnExpr (ExplicitSum x alt arity expr)
- = do { (expr', fvs) <- rnLExpr expr
- ; return (ExplicitSum x alt arity expr', fvs) }
-
-rnExpr (RecordCon { rcon_con_name = con_id
- , rcon_flds = rec_binds@(HsRecFields { rec_dotdot = dd }) })
- = do { con_lname@(L _ con_name) <- lookupLocatedOccRn con_id
- ; (flds, fvs) <- rnHsRecFields (HsRecFieldCon con_name) mk_hs_var rec_binds
- ; (flds', fvss) <- mapAndUnzipM rn_field flds
- ; let rec_binds' = HsRecFields { rec_flds = flds', rec_dotdot = dd }
- ; return (RecordCon { rcon_ext = noExtField
- , rcon_con_name = con_lname, rcon_flds = rec_binds' }
- , fvs `plusFV` plusFVs fvss `addOneFV` con_name) }
- where
- mk_hs_var l n = HsVar noExtField (L l n)
- rn_field (L l fld) = do { (arg', fvs) <- rnLExpr (hsRecFieldArg fld)
- ; return (L l (fld { hsRecFieldArg = arg' }), fvs) }
-
-rnExpr (RecordUpd { rupd_expr = expr, rupd_flds = rbinds })
- = do { (expr', fvExpr) <- rnLExpr expr
- ; (rbinds', fvRbinds) <- rnHsRecUpdFields rbinds
- ; return (RecordUpd { rupd_ext = noExtField, rupd_expr = expr'
- , rupd_flds = rbinds' }
- , fvExpr `plusFV` fvRbinds) }
-
-rnExpr (ExprWithTySig _ expr pty)
- = do { (pty', fvTy) <- rnHsSigWcType BindUnlessForall ExprWithTySigCtx pty
- ; (expr', fvExpr) <- bindSigTyVarsFV (hsWcScopedTvs pty') $
- rnLExpr expr
- ; return (ExprWithTySig noExtField expr' pty', fvExpr `plusFV` fvTy) }
-
-rnExpr (HsIf x _ p b1 b2)
- = do { (p', fvP) <- rnLExpr p
- ; (b1', fvB1) <- rnLExpr b1
- ; (b2', fvB2) <- rnLExpr b2
- ; (mb_ite, fvITE) <- lookupIfThenElse
- ; return (HsIf x mb_ite p' b1' b2', plusFVs [fvITE, fvP, fvB1, fvB2]) }
-
-rnExpr (HsMultiIf x alts)
- = do { (alts', fvs) <- mapFvRn (rnGRHS IfAlt rnLExpr) alts
- -- ; return (HsMultiIf ty alts', fvs) }
- ; return (HsMultiIf x alts', fvs) }
-
-rnExpr (ArithSeq x _ seq)
- = do { opt_OverloadedLists <- xoptM LangExt.OverloadedLists
- ; (new_seq, fvs) <- rnArithSeq seq
- ; if opt_OverloadedLists
- then do {
- ; (from_list_name, fvs') <- lookupSyntaxName fromListName
- ; return (ArithSeq x (Just from_list_name) new_seq
- , fvs `plusFV` fvs') }
- else
- return (ArithSeq x Nothing new_seq, fvs) }
-
-{-
-************************************************************************
-* *
- Static values
-* *
-************************************************************************
-
-For the static form we check that it is not used in splices.
-We also collect the free variables of the term which come from
-this module. See Note [Grand plan for static forms] in StaticPtrTable.
--}
-
-rnExpr e@(HsStatic _ expr) = do
- -- Normally, you wouldn't be able to construct a static expression without
- -- first enabling -XStaticPointers in the first place, since that extension
- -- is what makes the parser treat `static` as a keyword. But this is not a
- -- sufficient safeguard, as one can construct static expressions by another
- -- mechanism: Template Haskell (see #14204). To ensure that GHC is
- -- absolutely prepared to cope with static forms, we check for
- -- -XStaticPointers here as well.
- unlessXOptM LangExt.StaticPointers $
- addErr $ hang (text "Illegal static expression:" <+> ppr e)
- 2 (text "Use StaticPointers to enable this extension")
- (expr',fvExpr) <- rnLExpr expr
- stage <- getStage
- case stage of
- Splice _ -> addErr $ sep
- [ text "static forms cannot be used in splices:"
- , nest 2 $ ppr e
- ]
- _ -> return ()
- mod <- getModule
- let fvExpr' = filterNameSet (nameIsLocalOrFrom mod) fvExpr
- return (HsStatic fvExpr' expr', fvExpr)
-
-{-
-************************************************************************
-* *
- Arrow notation
-* *
-************************************************************************
--}
-
-rnExpr (HsProc x pat body)
- = newArrowScope $
- rnPat ProcExpr pat $ \ pat' -> do
- { (body',fvBody) <- rnCmdTop body
- ; return (HsProc x pat' body', fvBody) }
-
-rnExpr other = pprPanic "rnExpr: unexpected expression" (ppr other)
- -- HsWrap
-
-----------------------
--- See Note [Parsing sections] in Parser.y
-rnSection :: HsExpr GhcPs -> RnM (HsExpr GhcRn, FreeVars)
-rnSection section@(SectionR x op expr)
- = do { (op', fvs_op) <- rnLExpr op
- ; (expr', fvs_expr) <- rnLExpr expr
- ; checkSectionPrec InfixR section op' expr'
- ; return (SectionR x op' expr', fvs_op `plusFV` fvs_expr) }
-
-rnSection section@(SectionL x expr op)
- = do { (expr', fvs_expr) <- rnLExpr expr
- ; (op', fvs_op) <- rnLExpr op
- ; checkSectionPrec InfixL section op' expr'
- ; return (SectionL x expr' op', fvs_op `plusFV` fvs_expr) }
-
-rnSection other = pprPanic "rnSection" (ppr other)
-
-{-
-************************************************************************
-* *
- Arrow commands
-* *
-************************************************************************
--}
-
-rnCmdArgs :: [LHsCmdTop GhcPs] -> RnM ([LHsCmdTop GhcRn], FreeVars)
-rnCmdArgs [] = return ([], emptyFVs)
-rnCmdArgs (arg:args)
- = do { (arg',fvArg) <- rnCmdTop arg
- ; (args',fvArgs) <- rnCmdArgs args
- ; return (arg':args', fvArg `plusFV` fvArgs) }
-
-rnCmdTop :: LHsCmdTop GhcPs -> RnM (LHsCmdTop GhcRn, FreeVars)
-rnCmdTop = wrapLocFstM rnCmdTop'
- where
- rnCmdTop' (HsCmdTop _ cmd)
- = do { (cmd', fvCmd) <- rnLCmd cmd
- ; let cmd_names = [arrAName, composeAName, firstAName] ++
- nameSetElemsStable (methodNamesCmd (unLoc cmd'))
- -- Generate the rebindable syntax for the monad
- ; (cmd_names', cmd_fvs) <- lookupSyntaxNames cmd_names
-
- ; return (HsCmdTop (cmd_names `zip` cmd_names') cmd',
- fvCmd `plusFV` cmd_fvs) }
- rnCmdTop' (XCmdTop nec) = noExtCon nec
-
-rnLCmd :: LHsCmd GhcPs -> RnM (LHsCmd GhcRn, FreeVars)
-rnLCmd = wrapLocFstM rnCmd
-
-rnCmd :: HsCmd GhcPs -> RnM (HsCmd GhcRn, FreeVars)
-
-rnCmd (HsCmdArrApp x arrow arg ho rtl)
- = do { (arrow',fvArrow) <- select_arrow_scope (rnLExpr arrow)
- ; (arg',fvArg) <- rnLExpr arg
- ; return (HsCmdArrApp x arrow' arg' ho rtl,
- fvArrow `plusFV` fvArg) }
- where
- select_arrow_scope tc = case ho of
- HsHigherOrderApp -> tc
- HsFirstOrderApp -> escapeArrowScope tc
- -- See Note [Escaping the arrow scope] in TcRnTypes
- -- Before renaming 'arrow', use the environment of the enclosing
- -- proc for the (-<) case.
- -- Local bindings, inside the enclosing proc, are not in scope
- -- inside 'arrow'. In the higher-order case (-<<), they are.
-
--- infix form
-rnCmd (HsCmdArrForm _ op _ (Just _) [arg1, arg2])
- = do { (op',fv_op) <- escapeArrowScope (rnLExpr op)
- ; let L _ (HsVar _ (L _ op_name)) = op'
- ; (arg1',fv_arg1) <- rnCmdTop arg1
- ; (arg2',fv_arg2) <- rnCmdTop arg2
- -- Deal with fixity
- ; fixity <- lookupFixityRn op_name
- ; final_e <- mkOpFormRn arg1' op' fixity arg2'
- ; return (final_e, fv_arg1 `plusFV` fv_op `plusFV` fv_arg2) }
-
-rnCmd (HsCmdArrForm x op f fixity cmds)
- = do { (op',fvOp) <- escapeArrowScope (rnLExpr op)
- ; (cmds',fvCmds) <- rnCmdArgs cmds
- ; return (HsCmdArrForm x op' f fixity cmds', fvOp `plusFV` fvCmds) }
-
-rnCmd (HsCmdApp x fun arg)
- = do { (fun',fvFun) <- rnLCmd fun
- ; (arg',fvArg) <- rnLExpr arg
- ; return (HsCmdApp x fun' arg', fvFun `plusFV` fvArg) }
-
-rnCmd (HsCmdLam x matches)
- = do { (matches', fvMatch) <- rnMatchGroup LambdaExpr rnLCmd matches
- ; return (HsCmdLam x matches', fvMatch) }
-
-rnCmd (HsCmdPar x e)
- = do { (e', fvs_e) <- rnLCmd e
- ; return (HsCmdPar x e', fvs_e) }
-
-rnCmd (HsCmdCase x expr matches)
- = do { (new_expr, e_fvs) <- rnLExpr expr
- ; (new_matches, ms_fvs) <- rnMatchGroup CaseAlt rnLCmd matches
- ; return (HsCmdCase x new_expr new_matches, e_fvs `plusFV` ms_fvs) }
-
-rnCmd (HsCmdIf x _ p b1 b2)
- = do { (p', fvP) <- rnLExpr p
- ; (b1', fvB1) <- rnLCmd b1
- ; (b2', fvB2) <- rnLCmd b2
- ; (mb_ite, fvITE) <- lookupIfThenElse
- ; return (HsCmdIf x mb_ite p' b1' b2', plusFVs [fvITE, fvP, fvB1, fvB2])}
-
-rnCmd (HsCmdLet x (L l binds) cmd)
- = rnLocalBindsAndThen binds $ \ binds' _ -> do
- { (cmd',fvExpr) <- rnLCmd cmd
- ; return (HsCmdLet x (L l binds') cmd', fvExpr) }
-
-rnCmd (HsCmdDo x (L l stmts))
- = do { ((stmts', _), fvs) <-
- rnStmts ArrowExpr rnLCmd stmts (\ _ -> return ((), emptyFVs))
- ; return ( HsCmdDo x (L l stmts'), fvs ) }
-
-rnCmd cmd@(HsCmdWrap {}) = pprPanic "rnCmd" (ppr cmd)
-rnCmd (XCmd nec) = noExtCon nec
-
----------------------------------------------------
-type CmdNeeds = FreeVars -- Only inhabitants are
- -- appAName, choiceAName, loopAName
-
--- find what methods the Cmd needs (loop, choice, apply)
-methodNamesLCmd :: LHsCmd GhcRn -> CmdNeeds
-methodNamesLCmd = methodNamesCmd . unLoc
-
-methodNamesCmd :: HsCmd GhcRn -> CmdNeeds
-
-methodNamesCmd (HsCmdArrApp _ _arrow _arg HsFirstOrderApp _rtl)
- = emptyFVs
-methodNamesCmd (HsCmdArrApp _ _arrow _arg HsHigherOrderApp _rtl)
- = unitFV appAName
-methodNamesCmd (HsCmdArrForm {}) = emptyFVs
-methodNamesCmd (HsCmdWrap _ _ cmd) = methodNamesCmd cmd
-
-methodNamesCmd (HsCmdPar _ c) = methodNamesLCmd c
-
-methodNamesCmd (HsCmdIf _ _ _ c1 c2)
- = methodNamesLCmd c1 `plusFV` methodNamesLCmd c2 `addOneFV` choiceAName
-
-methodNamesCmd (HsCmdLet _ _ c) = methodNamesLCmd c
-methodNamesCmd (HsCmdDo _ (L _ stmts)) = methodNamesStmts stmts
-methodNamesCmd (HsCmdApp _ c _) = methodNamesLCmd c
-methodNamesCmd (HsCmdLam _ match) = methodNamesMatch match
-
-methodNamesCmd (HsCmdCase _ _ matches)
- = methodNamesMatch matches `addOneFV` choiceAName
-
-methodNamesCmd (XCmd nec) = noExtCon nec
-
---methodNamesCmd _ = emptyFVs
- -- Other forms can't occur in commands, but it's not convenient
- -- to error here so we just do what's convenient.
- -- The type checker will complain later
-
----------------------------------------------------
-methodNamesMatch :: MatchGroup GhcRn (LHsCmd GhcRn) -> FreeVars
-methodNamesMatch (MG { mg_alts = L _ ms })
- = plusFVs (map do_one ms)
- where
- do_one (L _ (Match { m_grhss = grhss })) = methodNamesGRHSs grhss
- do_one (L _ (XMatch nec)) = noExtCon nec
-methodNamesMatch (XMatchGroup nec) = noExtCon nec
-
--------------------------------------------------
--- gaw 2004
-methodNamesGRHSs :: GRHSs GhcRn (LHsCmd GhcRn) -> FreeVars
-methodNamesGRHSs (GRHSs _ grhss _) = plusFVs (map methodNamesGRHS grhss)
-methodNamesGRHSs (XGRHSs nec) = noExtCon nec
-
--------------------------------------------------
-
-methodNamesGRHS :: Located (GRHS GhcRn (LHsCmd GhcRn)) -> CmdNeeds
-methodNamesGRHS (L _ (GRHS _ _ rhs)) = methodNamesLCmd rhs
-methodNamesGRHS (L _ (XGRHS nec)) = noExtCon nec
-
----------------------------------------------------
-methodNamesStmts :: [Located (StmtLR GhcRn GhcRn (LHsCmd GhcRn))] -> FreeVars
-methodNamesStmts stmts = plusFVs (map methodNamesLStmt stmts)
-
----------------------------------------------------
-methodNamesLStmt :: Located (StmtLR GhcRn GhcRn (LHsCmd GhcRn)) -> FreeVars
-methodNamesLStmt = methodNamesStmt . unLoc
-
-methodNamesStmt :: StmtLR GhcRn GhcRn (LHsCmd GhcRn) -> FreeVars
-methodNamesStmt (LastStmt _ cmd _ _) = methodNamesLCmd cmd
-methodNamesStmt (BodyStmt _ cmd _ _) = methodNamesLCmd cmd
-methodNamesStmt (BindStmt _ _ cmd _ _) = methodNamesLCmd cmd
-methodNamesStmt (RecStmt { recS_stmts = stmts }) =
- methodNamesStmts stmts `addOneFV` loopAName
-methodNamesStmt (LetStmt {}) = emptyFVs
-methodNamesStmt (ParStmt {}) = emptyFVs
-methodNamesStmt (TransStmt {}) = emptyFVs
-methodNamesStmt ApplicativeStmt{} = emptyFVs
- -- ParStmt and TransStmt can't occur in commands, but it's not
- -- convenient to error here so we just do what's convenient
-methodNamesStmt (XStmtLR nec) = noExtCon nec
-
-{-
-************************************************************************
-* *
- Arithmetic sequences
-* *
-************************************************************************
--}
-
-rnArithSeq :: ArithSeqInfo GhcPs -> RnM (ArithSeqInfo GhcRn, FreeVars)
-rnArithSeq (From expr)
- = do { (expr', fvExpr) <- rnLExpr expr
- ; return (From expr', fvExpr) }
-
-rnArithSeq (FromThen expr1 expr2)
- = do { (expr1', fvExpr1) <- rnLExpr expr1
- ; (expr2', fvExpr2) <- rnLExpr expr2
- ; return (FromThen expr1' expr2', fvExpr1 `plusFV` fvExpr2) }
-
-rnArithSeq (FromTo expr1 expr2)
- = do { (expr1', fvExpr1) <- rnLExpr expr1
- ; (expr2', fvExpr2) <- rnLExpr expr2
- ; return (FromTo expr1' expr2', fvExpr1 `plusFV` fvExpr2) }
-
-rnArithSeq (FromThenTo expr1 expr2 expr3)
- = do { (expr1', fvExpr1) <- rnLExpr expr1
- ; (expr2', fvExpr2) <- rnLExpr expr2
- ; (expr3', fvExpr3) <- rnLExpr expr3
- ; return (FromThenTo expr1' expr2' expr3',
- plusFVs [fvExpr1, fvExpr2, fvExpr3]) }
-
-{-
-************************************************************************
-* *
-\subsubsection{@Stmt@s: in @do@ expressions}
-* *
-************************************************************************
--}
-
-{-
-Note [Deterministic ApplicativeDo and RecursiveDo desugaring]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Both ApplicativeDo and RecursiveDo need to create tuples not
-present in the source text.
-
-For ApplicativeDo we create:
-
- (a,b,c) <- (\c b a -> (a,b,c)) <$>
-
-For RecursiveDo we create:
-
- mfix (\ ~(a,b,c) -> do ...; return (a',b',c'))
-
-The order of the components in those tuples needs to be stable
-across recompilations, otherwise they can get optimized differently
-and we end up with incompatible binaries.
-To get a stable order we use nameSetElemsStable.
-See Note [Deterministic UniqFM] to learn more about nondeterminism.
--}
-
--- | Rename some Stmts
-rnStmts :: Outputable (body GhcPs)
- => HsStmtContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -- ^ How to rename the body of each statement (e.g. rnLExpr)
- -> [LStmt GhcPs (Located (body GhcPs))]
- -- ^ Statements
- -> ([Name] -> RnM (thing, FreeVars))
- -- ^ if these statements scope over something, this renames it
- -- and returns the result.
- -> RnM (([LStmt GhcRn (Located (body GhcRn))], thing), FreeVars)
-rnStmts ctxt rnBody = rnStmtsWithPostProcessing ctxt rnBody noPostProcessStmts
-
--- | like 'rnStmts' but applies a post-processing step to the renamed Stmts
-rnStmtsWithPostProcessing
- :: Outputable (body GhcPs)
- => HsStmtContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -- ^ How to rename the body of each statement (e.g. rnLExpr)
- -> (HsStmtContext Name
- -> [(LStmt GhcRn (Located (body GhcRn)), FreeVars)]
- -> RnM ([LStmt GhcRn (Located (body GhcRn))], FreeVars))
- -- ^ postprocess the statements
- -> [LStmt GhcPs (Located (body GhcPs))]
- -- ^ Statements
- -> ([Name] -> RnM (thing, FreeVars))
- -- ^ if these statements scope over something, this renames it
- -- and returns the result.
- -> RnM (([LStmt GhcRn (Located (body GhcRn))], thing), FreeVars)
-rnStmtsWithPostProcessing ctxt rnBody ppStmts stmts thing_inside
- = do { ((stmts', thing), fvs) <-
- rnStmtsWithFreeVars ctxt rnBody stmts thing_inside
- ; (pp_stmts, fvs') <- ppStmts ctxt stmts'
- ; return ((pp_stmts, thing), fvs `plusFV` fvs')
- }
-
--- | maybe rearrange statements according to the ApplicativeDo transformation
-postProcessStmtsForApplicativeDo
- :: HsStmtContext Name
- -> [(ExprLStmt GhcRn, FreeVars)]
- -> RnM ([ExprLStmt GhcRn], FreeVars)
-postProcessStmtsForApplicativeDo ctxt stmts
- = do {
- -- rearrange the statements using ApplicativeStmt if
- -- -XApplicativeDo is on. Also strip out the FreeVars attached
- -- to each Stmt body.
- ado_is_on <- xoptM LangExt.ApplicativeDo
- ; let is_do_expr | DoExpr <- ctxt = True
- | otherwise = False
- -- don't apply the transformation inside TH brackets, because
- -- DsMeta does not handle ApplicativeDo.
- ; in_th_bracket <- isBrackStage <$> getStage
- ; if ado_is_on && is_do_expr && not in_th_bracket
- then do { traceRn "ppsfa" (ppr stmts)
- ; rearrangeForApplicativeDo ctxt stmts }
- else noPostProcessStmts ctxt stmts }
-
--- | strip the FreeVars annotations from statements
-noPostProcessStmts
- :: HsStmtContext Name
- -> [(LStmt GhcRn (Located (body GhcRn)), FreeVars)]
- -> RnM ([LStmt GhcRn (Located (body GhcRn))], FreeVars)
-noPostProcessStmts _ stmts = return (map fst stmts, emptyNameSet)
-
-
-rnStmtsWithFreeVars :: Outputable (body GhcPs)
- => HsStmtContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> [LStmt GhcPs (Located (body GhcPs))]
- -> ([Name] -> RnM (thing, FreeVars))
- -> RnM ( ([(LStmt GhcRn (Located (body GhcRn)), FreeVars)], thing)
- , FreeVars)
--- Each Stmt body is annotated with its FreeVars, so that
--- we can rearrange statements for ApplicativeDo.
---
--- Variables bound by the Stmts, and mentioned in thing_inside,
--- do not appear in the result FreeVars
-
-rnStmtsWithFreeVars ctxt _ [] thing_inside
- = do { checkEmptyStmts ctxt
- ; (thing, fvs) <- thing_inside []
- ; return (([], thing), fvs) }
-
-rnStmtsWithFreeVars MDoExpr rnBody stmts thing_inside -- Deal with mdo
- = -- Behave like do { rec { ...all but last... }; last }
- do { ((stmts1, (stmts2, thing)), fvs)
- <- rnStmt MDoExpr rnBody (noLoc $ mkRecStmt all_but_last) $ \ _ ->
- do { last_stmt' <- checkLastStmt MDoExpr last_stmt
- ; rnStmt MDoExpr rnBody last_stmt' thing_inside }
- ; return (((stmts1 ++ stmts2), thing), fvs) }
- where
- Just (all_but_last, last_stmt) = snocView stmts
-
-rnStmtsWithFreeVars ctxt rnBody (lstmt@(L loc _) : lstmts) thing_inside
- | null lstmts
- = setSrcSpan loc $
- do { lstmt' <- checkLastStmt ctxt lstmt
- ; rnStmt ctxt rnBody lstmt' thing_inside }
-
- | otherwise
- = do { ((stmts1, (stmts2, thing)), fvs)
- <- setSrcSpan loc $
- do { checkStmt ctxt lstmt
- ; rnStmt ctxt rnBody lstmt $ \ bndrs1 ->
- rnStmtsWithFreeVars ctxt rnBody lstmts $ \ bndrs2 ->
- thing_inside (bndrs1 ++ bndrs2) }
- ; return (((stmts1 ++ stmts2), thing), fvs) }
-
-----------------------
-
-{-
-Note [Failing pattern matches in Stmts]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Many things desugar to HsStmts including monadic things like `do` and `mdo`
-statements, pattern guards, and list comprehensions (see 'HsStmtContext' for an
-exhaustive list). How we deal with pattern match failure is context-dependent.
-
- * In the case of list comprehensions and pattern guards we don't need any 'fail'
- function; the desugarer ignores the fail function field of 'BindStmt' entirely.
- * In the case of monadic contexts (e.g. monad comprehensions, do, and mdo
- expressions) we want pattern match failure to be desugared to the appropriate
- 'fail' function (either that of Monad or MonadFail, depending on whether
- -XMonadFailDesugaring is enabled.)
-
-At one point we failed to make this distinction, leading to #11216.
--}
-
-rnStmt :: Outputable (body GhcPs)
- => HsStmtContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -- ^ How to rename the body of the statement
- -> LStmt GhcPs (Located (body GhcPs))
- -- ^ The statement
- -> ([Name] -> RnM (thing, FreeVars))
- -- ^ Rename the stuff that this statement scopes over
- -> RnM ( ([(LStmt GhcRn (Located (body GhcRn)), FreeVars)], thing)
- , FreeVars)
--- Variables bound by the Stmt, and mentioned in thing_inside,
--- do not appear in the result FreeVars
-
-rnStmt ctxt rnBody (L loc (LastStmt _ body noret _)) thing_inside
- = do { (body', fv_expr) <- rnBody body
- ; (ret_op, fvs1) <- if isMonadCompContext ctxt
- then lookupStmtName ctxt returnMName
- else return (noSyntaxExpr, emptyFVs)
- -- The 'return' in a LastStmt is used only
- -- for MonadComp; and we don't want to report
- -- "non in scope: return" in other cases
- -- #15607
-
- ; (thing, fvs3) <- thing_inside []
- ; return (([(L loc (LastStmt noExtField body' noret ret_op), fv_expr)]
- , thing), fv_expr `plusFV` fvs1 `plusFV` fvs3) }
-
-rnStmt ctxt rnBody (L loc (BodyStmt _ body _ _)) thing_inside
- = do { (body', fv_expr) <- rnBody body
- ; (then_op, fvs1) <- lookupStmtName ctxt thenMName
-
- ; (guard_op, fvs2) <- if isComprehensionContext ctxt
- then lookupStmtName ctxt guardMName
- else return (noSyntaxExpr, emptyFVs)
- -- Only list/monad comprehensions use 'guard'
- -- Also for sub-stmts of same eg [ e | x<-xs, gd | blah ]
- -- Here "gd" is a guard
-
- ; (thing, fvs3) <- thing_inside []
- ; return ( ([(L loc (BodyStmt noExtField body' then_op guard_op), fv_expr)]
- , thing), fv_expr `plusFV` fvs1 `plusFV` fvs2 `plusFV` fvs3) }
-
-rnStmt ctxt rnBody (L loc (BindStmt _ pat body _ _)) thing_inside
- = do { (body', fv_expr) <- rnBody body
- -- The binders do not scope over the expression
- ; (bind_op, fvs1) <- lookupStmtName ctxt bindMName
-
- ; (fail_op, fvs2) <- monadFailOp pat ctxt
-
- ; rnPat (StmtCtxt ctxt) pat $ \ pat' -> do
- { (thing, fvs3) <- thing_inside (collectPatBinders pat')
- ; return (( [( L loc (BindStmt noExtField pat' body' bind_op fail_op)
- , fv_expr )]
- , thing),
- fv_expr `plusFV` fvs1 `plusFV` fvs2 `plusFV` fvs3) }}
- -- fv_expr shouldn't really be filtered by the rnPatsAndThen
- -- but it does not matter because the names are unique
-
-rnStmt _ _ (L loc (LetStmt _ (L l binds))) thing_inside
- = do { rnLocalBindsAndThen binds $ \binds' bind_fvs -> do
- { (thing, fvs) <- thing_inside (collectLocalBinders binds')
- ; return ( ([(L loc (LetStmt noExtField (L l binds')), bind_fvs)], thing)
- , fvs) } }
-
-rnStmt ctxt rnBody (L loc (RecStmt { recS_stmts = rec_stmts })) thing_inside
- = do { (return_op, fvs1) <- lookupStmtName ctxt returnMName
- ; (mfix_op, fvs2) <- lookupStmtName ctxt mfixName
- ; (bind_op, fvs3) <- lookupStmtName ctxt bindMName
- ; let empty_rec_stmt = emptyRecStmtName { recS_ret_fn = return_op
- , recS_mfix_fn = mfix_op
- , recS_bind_fn = bind_op }
-
- -- Step1: Bring all the binders of the mdo into scope
- -- (Remember that this also removes the binders from the
- -- finally-returned free-vars.)
- -- And rename each individual stmt, making a
- -- singleton segment. At this stage the FwdRefs field
- -- isn't finished: it's empty for all except a BindStmt
- -- for which it's the fwd refs within the bind itself
- -- (This set may not be empty, because we're in a recursive
- -- context.)
- ; rnRecStmtsAndThen rnBody rec_stmts $ \ segs -> do
- { let bndrs = nameSetElemsStable $
- foldr (unionNameSet . (\(ds,_,_,_) -> ds))
- emptyNameSet
- segs
- -- See Note [Deterministic ApplicativeDo and RecursiveDo desugaring]
- ; (thing, fvs_later) <- thing_inside bndrs
- ; let (rec_stmts', fvs) = segmentRecStmts loc ctxt empty_rec_stmt segs fvs_later
- -- We aren't going to try to group RecStmts with
- -- ApplicativeDo, so attaching empty FVs is fine.
- ; return ( ((zip rec_stmts' (repeat emptyNameSet)), thing)
- , fvs `plusFV` fvs1 `plusFV` fvs2 `plusFV` fvs3) } }
-
-rnStmt ctxt _ (L loc (ParStmt _ segs _ _)) thing_inside
- = do { (mzip_op, fvs1) <- lookupStmtNamePoly ctxt mzipName
- ; (bind_op, fvs2) <- lookupStmtName ctxt bindMName
- ; (return_op, fvs3) <- lookupStmtName ctxt returnMName
- ; ((segs', thing), fvs4) <- rnParallelStmts (ParStmtCtxt ctxt) return_op segs thing_inside
- ; return (([(L loc (ParStmt noExtField segs' mzip_op bind_op), fvs4)], thing)
- , fvs1 `plusFV` fvs2 `plusFV` fvs3 `plusFV` fvs4) }
-
-rnStmt ctxt _ (L loc (TransStmt { trS_stmts = stmts, trS_by = by, trS_form = form
- , trS_using = using })) thing_inside
- = do { -- Rename the 'using' expression in the context before the transform is begun
- (using', fvs1) <- rnLExpr using
-
- -- Rename the stmts and the 'by' expression
- -- Keep track of the variables mentioned in the 'by' expression
- ; ((stmts', (by', used_bndrs, thing)), fvs2)
- <- rnStmts (TransStmtCtxt ctxt) rnLExpr stmts $ \ bndrs ->
- do { (by', fvs_by) <- mapMaybeFvRn rnLExpr by
- ; (thing, fvs_thing) <- thing_inside bndrs
- ; let fvs = fvs_by `plusFV` fvs_thing
- used_bndrs = filter (`elemNameSet` fvs) bndrs
- -- The paper (Fig 5) has a bug here; we must treat any free variable
- -- of the "thing inside", **or of the by-expression**, as used
- ; return ((by', used_bndrs, thing), fvs) }
-
- -- Lookup `return`, `(>>=)` and `liftM` for monad comprehensions
- ; (return_op, fvs3) <- lookupStmtName ctxt returnMName
- ; (bind_op, fvs4) <- lookupStmtName ctxt bindMName
- ; (fmap_op, fvs5) <- case form of
- ThenForm -> return (noExpr, emptyFVs)
- _ -> lookupStmtNamePoly ctxt fmapName
-
- ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3
- `plusFV` fvs4 `plusFV` fvs5
- bndr_map = used_bndrs `zip` used_bndrs
- -- See Note [TransStmt binder map] in GHC.Hs.Expr
-
- ; traceRn "rnStmt: implicitly rebound these used binders:" (ppr bndr_map)
- ; return (([(L loc (TransStmt { trS_ext = noExtField
- , trS_stmts = stmts', trS_bndrs = bndr_map
- , trS_by = by', trS_using = using', trS_form = form
- , trS_ret = return_op, trS_bind = bind_op
- , trS_fmap = fmap_op }), fvs2)], thing), all_fvs) }
-
-rnStmt _ _ (L _ ApplicativeStmt{}) _ =
- panic "rnStmt: ApplicativeStmt"
-
-rnStmt _ _ (L _ (XStmtLR nec)) _ =
- noExtCon nec
-
-rnParallelStmts :: forall thing. HsStmtContext Name
- -> SyntaxExpr GhcRn
- -> [ParStmtBlock GhcPs GhcPs]
- -> ([Name] -> RnM (thing, FreeVars))
- -> RnM (([ParStmtBlock GhcRn GhcRn], thing), FreeVars)
--- Note [Renaming parallel Stmts]
-rnParallelStmts ctxt return_op segs thing_inside
- = do { orig_lcl_env <- getLocalRdrEnv
- ; rn_segs orig_lcl_env [] segs }
- where
- rn_segs :: LocalRdrEnv
- -> [Name] -> [ParStmtBlock GhcPs GhcPs]
- -> RnM (([ParStmtBlock GhcRn GhcRn], thing), FreeVars)
- rn_segs _ bndrs_so_far []
- = do { let (bndrs', dups) = removeDups cmpByOcc bndrs_so_far
- ; mapM_ dupErr dups
- ; (thing, fvs) <- bindLocalNames bndrs' (thing_inside bndrs')
- ; return (([], thing), fvs) }
-
- rn_segs env bndrs_so_far (ParStmtBlock x stmts _ _ : segs)
- = do { ((stmts', (used_bndrs, segs', thing)), fvs)
- <- rnStmts ctxt rnLExpr stmts $ \ bndrs ->
- setLocalRdrEnv env $ do
- { ((segs', thing), fvs) <- rn_segs env (bndrs ++ bndrs_so_far) segs
- ; let used_bndrs = filter (`elemNameSet` fvs) bndrs
- ; return ((used_bndrs, segs', thing), fvs) }
-
- ; let seg' = ParStmtBlock x stmts' used_bndrs return_op
- ; return ((seg':segs', thing), fvs) }
- rn_segs _ _ (XParStmtBlock nec:_) = noExtCon nec
-
- cmpByOcc n1 n2 = nameOccName n1 `compare` nameOccName n2
- dupErr vs = addErr (text "Duplicate binding in parallel list comprehension for:"
- <+> quotes (ppr (NE.head vs)))
-
-lookupStmtName :: HsStmtContext Name -> Name -> RnM (SyntaxExpr GhcRn, FreeVars)
--- Like lookupSyntaxName, but respects contexts
-lookupStmtName ctxt n
- | rebindableContext ctxt
- = lookupSyntaxName n
- | otherwise
- = return (mkRnSyntaxExpr n, emptyFVs)
-
-lookupStmtNamePoly :: HsStmtContext Name -> Name -> RnM (HsExpr GhcRn, FreeVars)
-lookupStmtNamePoly ctxt name
- | rebindableContext ctxt
- = do { rebindable_on <- xoptM LangExt.RebindableSyntax
- ; if rebindable_on
- then do { fm <- lookupOccRn (nameRdrName name)
- ; return (HsVar noExtField (noLoc fm), unitFV fm) }
- else not_rebindable }
- | otherwise
- = not_rebindable
- where
- not_rebindable = return (HsVar noExtField (noLoc name), emptyFVs)
-
--- | Is this a context where we respect RebindableSyntax?
--- but ListComp are never rebindable
--- Neither is ArrowExpr, which has its own desugarer in DsArrows
-rebindableContext :: HsStmtContext Name -> Bool
-rebindableContext ctxt = case ctxt of
- ListComp -> False
- ArrowExpr -> False
- PatGuard {} -> False
-
- DoExpr -> True
- MDoExpr -> True
- MonadComp -> True
- GhciStmtCtxt -> True -- I suppose?
-
- ParStmtCtxt c -> rebindableContext c -- Look inside to
- TransStmtCtxt c -> rebindableContext c -- the parent context
-
-{-
-Note [Renaming parallel Stmts]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Renaming parallel statements is painful. Given, say
- [ a+c | a <- as, bs <- bss
- | c <- bs, a <- ds ]
-Note that
- (a) In order to report "Defined but not used" about 'bs', we must
- rename each group of Stmts with a thing_inside whose FreeVars
- include at least {a,c}
-
- (b) We want to report that 'a' is illegally bound in both branches
-
- (c) The 'bs' in the second group must obviously not be captured by
- the binding in the first group
-
-To satisfy (a) we nest the segements.
-To satisfy (b) we check for duplicates just before thing_inside.
-To satisfy (c) we reset the LocalRdrEnv each time.
-
-************************************************************************
-* *
-\subsubsection{mdo expressions}
-* *
-************************************************************************
--}
-
-type FwdRefs = NameSet
-type Segment stmts = (Defs,
- Uses, -- May include defs
- FwdRefs, -- A subset of uses that are
- -- (a) used before they are bound in this segment, or
- -- (b) used here, and bound in subsequent segments
- stmts) -- Either Stmt or [Stmt]
-
-
--- wrapper that does both the left- and right-hand sides
-rnRecStmtsAndThen :: Outputable (body GhcPs) =>
- (Located (body GhcPs)
- -> RnM (Located (body GhcRn), FreeVars))
- -> [LStmt GhcPs (Located (body GhcPs))]
- -- assumes that the FreeVars returned includes
- -- the FreeVars of the Segments
- -> ([Segment (LStmt GhcRn (Located (body GhcRn)))]
- -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
-rnRecStmtsAndThen rnBody s cont
- = do { -- (A) Make the mini fixity env for all of the stmts
- fix_env <- makeMiniFixityEnv (collectRecStmtsFixities s)
-
- -- (B) Do the LHSes
- ; new_lhs_and_fv <- rn_rec_stmts_lhs fix_env s
-
- -- ...bring them and their fixities into scope
- ; let bound_names = collectLStmtsBinders (map fst new_lhs_and_fv)
- -- Fake uses of variables introduced implicitly (warning suppression, see #4404)
- rec_uses = lStmtsImplicits (map fst new_lhs_and_fv)
- implicit_uses = mkNameSet $ concatMap snd $ rec_uses
- ; bindLocalNamesFV bound_names $
- addLocalFixities fix_env bound_names $ do
-
- -- (C) do the right-hand-sides and thing-inside
- { segs <- rn_rec_stmts rnBody bound_names new_lhs_and_fv
- ; (res, fvs) <- cont segs
- ; mapM_ (\(loc, ns) -> checkUnusedRecordWildcard loc fvs (Just ns))
- rec_uses
- ; warnUnusedLocalBinds bound_names (fvs `unionNameSet` implicit_uses)
- ; return (res, fvs) }}
-
--- get all the fixity decls in any Let stmt
-collectRecStmtsFixities :: [LStmtLR GhcPs GhcPs body] -> [LFixitySig GhcPs]
-collectRecStmtsFixities l =
- foldr (\ s -> \acc -> case s of
- (L _ (LetStmt _ (L _ (HsValBinds _ (ValBinds _ _ sigs))))) ->
- foldr (\ sig -> \ acc -> case sig of
- (L loc (FixSig _ s)) -> (L loc s) : acc
- _ -> acc) acc sigs
- _ -> acc) [] l
-
--- left-hand sides
-
-rn_rec_stmt_lhs :: Outputable body => MiniFixityEnv
- -> LStmt GhcPs body
- -- rename LHS, and return its FVs
- -- Warning: we will only need the FreeVars below in the case of a BindStmt,
- -- so we don't bother to compute it accurately in the other cases
- -> RnM [(LStmtLR GhcRn GhcPs body, FreeVars)]
-
-rn_rec_stmt_lhs _ (L loc (BodyStmt _ body a b))
- = return [(L loc (BodyStmt noExtField body a b), emptyFVs)]
-
-rn_rec_stmt_lhs _ (L loc (LastStmt _ body noret a))
- = return [(L loc (LastStmt noExtField body noret a), emptyFVs)]
-
-rn_rec_stmt_lhs fix_env (L loc (BindStmt _ pat body a b))
- = do
- -- should the ctxt be MDo instead?
- (pat', fv_pat) <- rnBindPat (localRecNameMaker fix_env) pat
- return [(L loc (BindStmt noExtField pat' body a b), fv_pat)]
-
-rn_rec_stmt_lhs _ (L _ (LetStmt _ (L _ binds@(HsIPBinds {}))))
- = failWith (badIpBinds (text "an mdo expression") binds)
-
-rn_rec_stmt_lhs fix_env (L loc (LetStmt _ (L l (HsValBinds x binds))))
- = do (_bound_names, binds') <- rnLocalValBindsLHS fix_env binds
- return [(L loc (LetStmt noExtField (L l (HsValBinds x binds'))),
- -- Warning: this is bogus; see function invariant
- emptyFVs
- )]
-
--- XXX Do we need to do something with the return and mfix names?
-rn_rec_stmt_lhs fix_env (L _ (RecStmt { recS_stmts = stmts })) -- Flatten Rec inside Rec
- = rn_rec_stmts_lhs fix_env stmts
-
-rn_rec_stmt_lhs _ stmt@(L _ (ParStmt {})) -- Syntactically illegal in mdo
- = pprPanic "rn_rec_stmt" (ppr stmt)
-
-rn_rec_stmt_lhs _ stmt@(L _ (TransStmt {})) -- Syntactically illegal in mdo
- = pprPanic "rn_rec_stmt" (ppr stmt)
-
-rn_rec_stmt_lhs _ stmt@(L _ (ApplicativeStmt {})) -- Shouldn't appear yet
- = pprPanic "rn_rec_stmt" (ppr stmt)
-
-rn_rec_stmt_lhs _ (L _ (LetStmt _ (L _ (EmptyLocalBinds _))))
- = panic "rn_rec_stmt LetStmt EmptyLocalBinds"
-rn_rec_stmt_lhs _ (L _ (LetStmt _ (L _ (XHsLocalBindsLR nec))))
- = noExtCon nec
-rn_rec_stmt_lhs _ (L _ (XStmtLR nec))
- = noExtCon nec
-
-rn_rec_stmts_lhs :: Outputable body => MiniFixityEnv
- -> [LStmt GhcPs body]
- -> RnM [(LStmtLR GhcRn GhcPs body, FreeVars)]
-rn_rec_stmts_lhs fix_env stmts
- = do { ls <- concatMapM (rn_rec_stmt_lhs fix_env) stmts
- ; let boundNames = collectLStmtsBinders (map fst ls)
- -- First do error checking: we need to check for dups here because we
- -- don't bind all of the variables from the Stmt at once
- -- with bindLocatedLocals.
- ; checkDupNames boundNames
- ; return ls }
-
-
--- right-hand-sides
-
-rn_rec_stmt :: (Outputable (body GhcPs)) =>
- (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> [Name]
- -> (LStmtLR GhcRn GhcPs (Located (body GhcPs)), FreeVars)
- -> RnM [Segment (LStmt GhcRn (Located (body GhcRn)))]
- -- Rename a Stmt that is inside a RecStmt (or mdo)
- -- Assumes all binders are already in scope
- -- Turns each stmt into a singleton Stmt
-rn_rec_stmt rnBody _ (L loc (LastStmt _ body noret _), _)
- = do { (body', fv_expr) <- rnBody body
- ; (ret_op, fvs1) <- lookupSyntaxName returnMName
- ; return [(emptyNameSet, fv_expr `plusFV` fvs1, emptyNameSet,
- L loc (LastStmt noExtField body' noret ret_op))] }
-
-rn_rec_stmt rnBody _ (L loc (BodyStmt _ body _ _), _)
- = do { (body', fvs) <- rnBody body
- ; (then_op, fvs1) <- lookupSyntaxName thenMName
- ; return [(emptyNameSet, fvs `plusFV` fvs1, emptyNameSet,
- L loc (BodyStmt noExtField body' then_op noSyntaxExpr))] }
-
-rn_rec_stmt rnBody _ (L loc (BindStmt _ pat' body _ _), fv_pat)
- = do { (body', fv_expr) <- rnBody body
- ; (bind_op, fvs1) <- lookupSyntaxName bindMName
-
- ; (fail_op, fvs2) <- getMonadFailOp
-
- ; let bndrs = mkNameSet (collectPatBinders pat')
- fvs = fv_expr `plusFV` fv_pat `plusFV` fvs1 `plusFV` fvs2
- ; return [(bndrs, fvs, bndrs `intersectNameSet` fvs,
- L loc (BindStmt noExtField pat' body' bind_op fail_op))] }
-
-rn_rec_stmt _ _ (L _ (LetStmt _ (L _ binds@(HsIPBinds {}))), _)
- = failWith (badIpBinds (text "an mdo expression") binds)
-
-rn_rec_stmt _ all_bndrs (L loc (LetStmt _ (L l (HsValBinds x binds'))), _)
- = do { (binds', du_binds) <- rnLocalValBindsRHS (mkNameSet all_bndrs) binds'
- -- fixities and unused are handled above in rnRecStmtsAndThen
- ; let fvs = allUses du_binds
- ; return [(duDefs du_binds, fvs, emptyNameSet,
- L loc (LetStmt noExtField (L l (HsValBinds x binds'))))] }
-
--- no RecStmt case because they get flattened above when doing the LHSes
-rn_rec_stmt _ _ stmt@(L _ (RecStmt {}), _)
- = pprPanic "rn_rec_stmt: RecStmt" (ppr stmt)
-
-rn_rec_stmt _ _ stmt@(L _ (ParStmt {}), _) -- Syntactically illegal in mdo
- = pprPanic "rn_rec_stmt: ParStmt" (ppr stmt)
-
-rn_rec_stmt _ _ stmt@(L _ (TransStmt {}), _) -- Syntactically illegal in mdo
- = pprPanic "rn_rec_stmt: TransStmt" (ppr stmt)
-
-rn_rec_stmt _ _ (L _ (LetStmt _ (L _ (XHsLocalBindsLR nec))), _)
- = noExtCon nec
-
-rn_rec_stmt _ _ (L _ (LetStmt _ (L _ (EmptyLocalBinds _))), _)
- = panic "rn_rec_stmt: LetStmt EmptyLocalBinds"
-
-rn_rec_stmt _ _ stmt@(L _ (ApplicativeStmt {}), _)
- = pprPanic "rn_rec_stmt: ApplicativeStmt" (ppr stmt)
-
-rn_rec_stmt _ _ (L _ (XStmtLR nec), _)
- = noExtCon nec
-
-rn_rec_stmts :: Outputable (body GhcPs) =>
- (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> [Name]
- -> [(LStmtLR GhcRn GhcPs (Located (body GhcPs)), FreeVars)]
- -> RnM [Segment (LStmt GhcRn (Located (body GhcRn)))]
-rn_rec_stmts rnBody bndrs stmts
- = do { segs_s <- mapM (rn_rec_stmt rnBody bndrs) stmts
- ; return (concat segs_s) }
-
----------------------------------------------
-segmentRecStmts :: SrcSpan -> HsStmtContext Name
- -> Stmt GhcRn body
- -> [Segment (LStmt GhcRn body)] -> FreeVars
- -> ([LStmt GhcRn body], FreeVars)
-
-segmentRecStmts loc ctxt empty_rec_stmt segs fvs_later
- | null segs
- = ([], fvs_later)
-
- | MDoExpr <- ctxt
- = segsToStmts empty_rec_stmt grouped_segs fvs_later
- -- Step 4: Turn the segments into Stmts
- -- Use RecStmt when and only when there are fwd refs
- -- Also gather up the uses from the end towards the
- -- start, so we can tell the RecStmt which things are
- -- used 'after' the RecStmt
-
- | otherwise
- = ([ L loc $
- empty_rec_stmt { recS_stmts = ss
- , recS_later_ids = nameSetElemsStable
- (defs `intersectNameSet` fvs_later)
- , recS_rec_ids = nameSetElemsStable
- (defs `intersectNameSet` uses) }]
- -- See Note [Deterministic ApplicativeDo and RecursiveDo desugaring]
- , uses `plusFV` fvs_later)
-
- where
- (defs_s, uses_s, _, ss) = unzip4 segs
- defs = plusFVs defs_s
- uses = plusFVs uses_s
-
- -- Step 2: Fill in the fwd refs.
- -- The segments are all singletons, but their fwd-ref
- -- field mentions all the things used by the segment
- -- that are bound after their use
- segs_w_fwd_refs = addFwdRefs segs
-
- -- Step 3: Group together the segments to make bigger segments
- -- Invariant: in the result, no segment uses a variable
- -- bound in a later segment
- grouped_segs = glomSegments ctxt segs_w_fwd_refs
-
-----------------------------
-addFwdRefs :: [Segment a] -> [Segment a]
--- So far the segments only have forward refs *within* the Stmt
--- (which happens for bind: x <- ...x...)
--- This function adds the cross-seg fwd ref info
-
-addFwdRefs segs
- = fst (foldr mk_seg ([], emptyNameSet) segs)
- where
- mk_seg (defs, uses, fwds, stmts) (segs, later_defs)
- = (new_seg : segs, all_defs)
- where
- new_seg = (defs, uses, new_fwds, stmts)
- all_defs = later_defs `unionNameSet` defs
- new_fwds = fwds `unionNameSet` (uses `intersectNameSet` later_defs)
- -- Add the downstream fwd refs here
-
-{-
-Note [Segmenting mdo]
-~~~~~~~~~~~~~~~~~~~~~
-NB. June 7 2012: We only glom segments that appear in an explicit mdo;
-and leave those found in "do rec"'s intact. See
-https://gitlab.haskell.org/ghc/ghc/issues/4148 for the discussion
-leading to this design choice. Hence the test in segmentRecStmts.
-
-Note [Glomming segments]
-~~~~~~~~~~~~~~~~~~~~~~~~
-Glomming the singleton segments of an mdo into minimal recursive groups.
-
-At first I thought this was just strongly connected components, but
-there's an important constraint: the order of the stmts must not change.
-
-Consider
- mdo { x <- ...y...
- p <- z
- y <- ...x...
- q <- x
- z <- y
- r <- x }
-
-Here, the first stmt mention 'y', which is bound in the third.
-But that means that the innocent second stmt (p <- z) gets caught
-up in the recursion. And that in turn means that the binding for
-'z' has to be included... and so on.
-
-Start at the tail { r <- x }
-Now add the next one { z <- y ; r <- x }
-Now add one more { q <- x ; z <- y ; r <- x }
-Now one more... but this time we have to group a bunch into rec
- { rec { y <- ...x... ; q <- x ; z <- y } ; r <- x }
-Now one more, which we can add on without a rec
- { p <- z ;
- rec { y <- ...x... ; q <- x ; z <- y } ;
- r <- x }
-Finally we add the last one; since it mentions y we have to
-glom it together with the first two groups
- { rec { x <- ...y...; p <- z ; y <- ...x... ;
- q <- x ; z <- y } ;
- r <- x }
--}
-
-glomSegments :: HsStmtContext Name
- -> [Segment (LStmt GhcRn body)]
- -> [Segment [LStmt GhcRn body]]
- -- Each segment has a non-empty list of Stmts
--- See Note [Glomming segments]
-
-glomSegments _ [] = []
-glomSegments ctxt ((defs,uses,fwds,stmt) : segs)
- -- Actually stmts will always be a singleton
- = (seg_defs, seg_uses, seg_fwds, seg_stmts) : others
- where
- segs' = glomSegments ctxt segs
- (extras, others) = grab uses segs'
- (ds, us, fs, ss) = unzip4 extras
-
- seg_defs = plusFVs ds `plusFV` defs
- seg_uses = plusFVs us `plusFV` uses
- seg_fwds = plusFVs fs `plusFV` fwds
- seg_stmts = stmt : concat ss
-
- grab :: NameSet -- The client
- -> [Segment a]
- -> ([Segment a], -- Needed by the 'client'
- [Segment a]) -- Not needed by the client
- -- The result is simply a split of the input
- grab uses dus
- = (reverse yeses, reverse noes)
- where
- (noes, yeses) = span not_needed (reverse dus)
- not_needed (defs,_,_,_) = not (intersectsNameSet defs uses)
-
-----------------------------------------------------
-segsToStmts :: Stmt GhcRn body
- -- A RecStmt with the SyntaxOps filled in
- -> [Segment [LStmt GhcRn body]]
- -- Each Segment has a non-empty list of Stmts
- -> FreeVars -- Free vars used 'later'
- -> ([LStmt GhcRn body], FreeVars)
-
-segsToStmts _ [] fvs_later = ([], fvs_later)
-segsToStmts empty_rec_stmt ((defs, uses, fwds, ss) : segs) fvs_later
- = ASSERT( not (null ss) )
- (new_stmt : later_stmts, later_uses `plusFV` uses)
- where
- (later_stmts, later_uses) = segsToStmts empty_rec_stmt segs fvs_later
- new_stmt | non_rec = head ss
- | otherwise = L (getLoc (head ss)) rec_stmt
- rec_stmt = empty_rec_stmt { recS_stmts = ss
- , recS_later_ids = nameSetElemsStable used_later
- , recS_rec_ids = nameSetElemsStable fwds }
- -- See Note [Deterministic ApplicativeDo and RecursiveDo desugaring]
- non_rec = isSingleton ss && isEmptyNameSet fwds
- used_later = defs `intersectNameSet` later_uses
- -- The ones needed after the RecStmt
-
-{-
-************************************************************************
-* *
-ApplicativeDo
-* *
-************************************************************************
-
-Note [ApplicativeDo]
-
-= Example =
-
-For a sequence of statements
-
- do
- x <- A
- y <- B x
- z <- C
- return (f x y z)
-
-We want to transform this to
-
- (\(x,y) z -> f x y z) <$> (do x <- A; y <- B x; return (x,y)) <*> C
-
-It would be easy to notice that "y <- B x" and "z <- C" are
-independent and do something like this:
-
- do
- x <- A
- (y,z) <- (,) <$> B x <*> C
- return (f x y z)
-
-But this isn't enough! A and C were also independent, and this
-transformation loses the ability to do A and C in parallel.
-
-The algorithm works by first splitting the sequence of statements into
-independent "segments", and a separate "tail" (the final statement). In
-our example above, the segements would be
-
- [ x <- A
- , y <- B x ]
-
- [ z <- C ]
-
-and the tail is:
-
- return (f x y z)
-
-Then we take these segments and make an Applicative expression from them:
-
- (\(x,y) z -> return (f x y z))
- <$> do { x <- A; y <- B x; return (x,y) }
- <*> C
-
-Finally, we recursively apply the transformation to each segment, to
-discover any nested parallelism.
-
-= Syntax & spec =
-
- expr ::= ... | do {stmt_1; ..; stmt_n} expr | ...
-
- stmt ::= pat <- expr
- | (arg_1 | ... | arg_n) -- applicative composition, n>=1
- | ... -- other kinds of statement (e.g. let)
-
- arg ::= pat <- expr
- | {stmt_1; ..; stmt_n} {var_1..var_n}
-
-(note that in the actual implementation,the expr in a do statement is
-represented by a LastStmt as the final stmt, this is just a
-representational issue and may change later.)
-
-== Transformation to introduce applicative stmts ==
-
-ado {} tail = tail
-ado {pat <- expr} {return expr'} = (mkArg(pat <- expr)); return expr'
-ado {one} tail = one : tail
-ado stmts tail
- | n == 1 = ado before (ado after tail)
- where (before,after) = split(stmts_1)
- | n > 1 = (mkArg(stmts_1) | ... | mkArg(stmts_n)); tail
- where
- {stmts_1 .. stmts_n} = segments(stmts)
-
-segments(stmts) =
- -- divide stmts into segments with no interdependencies
-
-mkArg({pat <- expr}) = (pat <- expr)
-mkArg({stmt_1; ...; stmt_n}) =
- {stmt_1; ...; stmt_n} {vars(stmt_1) u .. u vars(stmt_n)}
-
-split({stmt_1; ..; stmt_n) =
- ({stmt_1; ..; stmt_i}, {stmt_i+1; ..; stmt_n})
- -- 1 <= i <= n
- -- i is a good place to insert a bind
-
-== Desugaring for do ==
-
-dsDo {} expr = expr
-
-dsDo {pat <- rhs; stmts} expr =
- rhs >>= \pat -> dsDo stmts expr
-
-dsDo {(arg_1 | ... | arg_n)} (return expr) =
- (\argpat (arg_1) .. argpat(arg_n) -> expr)
- <$> argexpr(arg_1)
- <*> ...
- <*> argexpr(arg_n)
-
-dsDo {(arg_1 | ... | arg_n); stmts} expr =
- join (\argpat (arg_1) .. argpat(arg_n) -> dsDo stmts expr)
- <$> argexpr(arg_1)
- <*> ...
- <*> argexpr(arg_n)
-
-= Relevant modules in the rest of the compiler =
-
-ApplicativeDo touches a few phases in the compiler:
-
-* Renamer: The journey begins here in the renamer, where do-blocks are
- scheduled as outlined above and transformed into applicative
- combinators. However, the code is still represented as a do-block
- with special forms of applicative statements. This allows us to
- recover the original do-block when e.g. printing type errors, where
- we don't want to show any of the applicative combinators since they
- don't exist in the source code.
- See ApplicativeStmt and ApplicativeArg in HsExpr.
-
-* Typechecker: ApplicativeDo passes through the typechecker much like any
- other form of expression. The only crux is that the typechecker has to
- be aware of the special ApplicativeDo statements in the do-notation, and
- typecheck them appropriately.
- Relevant module: TcMatches
-
-* Desugarer: Any do-block which contains applicative statements is desugared
- as outlined above, to use the Applicative combinators.
- Relevant module: DsExpr
-
--}
-
--- | The 'Name's of @return@ and @pure@. These may not be 'returnName' and
--- 'pureName' due to @RebindableSyntax@.
-data MonadNames = MonadNames { return_name, pure_name :: Name }
-
-instance Outputable MonadNames where
- ppr (MonadNames {return_name=return_name,pure_name=pure_name}) =
- hcat
- [text "MonadNames { return_name = "
- ,ppr return_name
- ,text ", pure_name = "
- ,ppr pure_name
- ,text "}"
- ]
-
--- | rearrange a list of statements using ApplicativeDoStmt. See
--- Note [ApplicativeDo].
-rearrangeForApplicativeDo
- :: HsStmtContext Name
- -> [(ExprLStmt GhcRn, FreeVars)]
- -> RnM ([ExprLStmt GhcRn], FreeVars)
-
-rearrangeForApplicativeDo _ [] = return ([], emptyNameSet)
-rearrangeForApplicativeDo _ [(one,_)] = return ([one], emptyNameSet)
-rearrangeForApplicativeDo ctxt stmts0 = do
- optimal_ado <- goptM Opt_OptimalApplicativeDo
- let stmt_tree | optimal_ado = mkStmtTreeOptimal stmts
- | otherwise = mkStmtTreeHeuristic stmts
- traceRn "rearrangeForADo" (ppr stmt_tree)
- return_name <- lookupSyntaxName' returnMName
- pure_name <- lookupSyntaxName' pureAName
- let monad_names = MonadNames { return_name = return_name
- , pure_name = pure_name }
- stmtTreeToStmts monad_names ctxt stmt_tree [last] last_fvs
- where
- (stmts,(last,last_fvs)) = findLast stmts0
- findLast [] = error "findLast"
- findLast [last] = ([],last)
- findLast (x:xs) = (x:rest,last) where (rest,last) = findLast xs
-
--- | A tree of statements using a mixture of applicative and bind constructs.
-data StmtTree a
- = StmtTreeOne a
- | StmtTreeBind (StmtTree a) (StmtTree a)
- | StmtTreeApplicative [StmtTree a]
-
-instance Outputable a => Outputable (StmtTree a) where
- ppr (StmtTreeOne x) = parens (text "StmtTreeOne" <+> ppr x)
- ppr (StmtTreeBind x y) = parens (hang (text "StmtTreeBind")
- 2 (sep [ppr x, ppr y]))
- ppr (StmtTreeApplicative xs) = parens (hang (text "StmtTreeApplicative")
- 2 (vcat (map ppr xs)))
-
-flattenStmtTree :: StmtTree a -> [a]
-flattenStmtTree t = go t []
- where
- go (StmtTreeOne a) as = a : as
- go (StmtTreeBind l r) as = go l (go r as)
- go (StmtTreeApplicative ts) as = foldr go as ts
-
-type ExprStmtTree = StmtTree (ExprLStmt GhcRn, FreeVars)
-type Cost = Int
-
--- | Turn a sequence of statements into an ExprStmtTree using a
--- heuristic algorithm. /O(n^2)/
-mkStmtTreeHeuristic :: [(ExprLStmt GhcRn, FreeVars)] -> ExprStmtTree
-mkStmtTreeHeuristic [one] = StmtTreeOne one
-mkStmtTreeHeuristic stmts =
- case segments stmts of
- [one] -> split one
- segs -> StmtTreeApplicative (map split segs)
- where
- split [one] = StmtTreeOne one
- split stmts =
- StmtTreeBind (mkStmtTreeHeuristic before) (mkStmtTreeHeuristic after)
- where (before, after) = splitSegment stmts
-
--- | Turn a sequence of statements into an ExprStmtTree optimally,
--- using dynamic programming. /O(n^3)/
-mkStmtTreeOptimal :: [(ExprLStmt GhcRn, FreeVars)] -> ExprStmtTree
-mkStmtTreeOptimal stmts =
- ASSERT(not (null stmts)) -- the empty case is handled by the caller;
- -- we don't support empty StmtTrees.
- fst (arr ! (0,n))
- where
- n = length stmts - 1
- stmt_arr = listArray (0,n) stmts
-
- -- lazy cache of optimal trees for subsequences of the input
- arr :: Array (Int,Int) (ExprStmtTree, Cost)
- arr = array ((0,0),(n,n))
- [ ((lo,hi), tree lo hi)
- | lo <- [0..n]
- , hi <- [lo..n] ]
-
- -- compute the optimal tree for the sequence [lo..hi]
- tree lo hi
- | hi == lo = (StmtTreeOne (stmt_arr ! lo), 1)
- | otherwise =
- case segments [ stmt_arr ! i | i <- [lo..hi] ] of
- [] -> panic "mkStmtTree"
- [_one] -> split lo hi
- segs -> (StmtTreeApplicative trees, maximum costs)
- where
- bounds = scanl (\(_,hi) a -> (hi+1, hi + length a)) (0,lo-1) segs
- (trees,costs) = unzip (map (uncurry split) (tail bounds))
-
- -- find the best place to split the segment [lo..hi]
- split :: Int -> Int -> (ExprStmtTree, Cost)
- split lo hi
- | hi == lo = (StmtTreeOne (stmt_arr ! lo), 1)
- | otherwise = (StmtTreeBind before after, c1+c2)
- where
- -- As per the paper, for a sequence s1...sn, we want to find
- -- the split with the minimum cost, where the cost is the
- -- sum of the cost of the left and right subsequences.
- --
- -- As an optimisation (also in the paper) if the cost of
- -- s1..s(n-1) is different from the cost of s2..sn, we know
- -- that the optimal solution is the lower of the two. Only
- -- in the case that these two have the same cost do we need
- -- to do the exhaustive search.
- --
- ((before,c1),(after,c2))
- | hi - lo == 1
- = ((StmtTreeOne (stmt_arr ! lo), 1),
- (StmtTreeOne (stmt_arr ! hi), 1))
- | left_cost < right_cost
- = ((left,left_cost), (StmtTreeOne (stmt_arr ! hi), 1))
- | left_cost > right_cost
- = ((StmtTreeOne (stmt_arr ! lo), 1), (right,right_cost))
- | otherwise = minimumBy (comparing cost) alternatives
- where
- (left, left_cost) = arr ! (lo,hi-1)
- (right, right_cost) = arr ! (lo+1,hi)
- cost ((_,c1),(_,c2)) = c1 + c2
- alternatives = [ (arr ! (lo,k), arr ! (k+1,hi))
- | k <- [lo .. hi-1] ]
-
-
--- | Turn the ExprStmtTree back into a sequence of statements, using
--- ApplicativeStmt where necessary.
-stmtTreeToStmts
- :: MonadNames
- -> HsStmtContext Name
- -> ExprStmtTree
- -> [ExprLStmt GhcRn] -- ^ the "tail"
- -> FreeVars -- ^ free variables of the tail
- -> RnM ( [ExprLStmt GhcRn] -- ( output statements,
- , FreeVars ) -- , things we needed
-
--- If we have a single bind, and we can do it without a join, transform
--- to an ApplicativeStmt. This corresponds to the rule
--- dsBlock [pat <- rhs] (return expr) = expr <$> rhs
--- In the spec, but we do it here rather than in the desugarer,
--- because we need the typechecker to typecheck the <$> form rather than
--- the bind form, which would give rise to a Monad constraint.
-stmtTreeToStmts monad_names ctxt (StmtTreeOne (L _ (BindStmt _ pat rhs _ fail_op), _))
- tail _tail_fvs
- | not (isStrictPattern pat), (False,tail') <- needJoin monad_names tail
- -- See Note [ApplicativeDo and strict patterns]
- = mkApplicativeStmt ctxt [ApplicativeArgOne
- { xarg_app_arg_one = noExtField
- , app_arg_pattern = pat
- , arg_expr = rhs
- , is_body_stmt = False
- , fail_operator = fail_op}]
- False tail'
-stmtTreeToStmts monad_names ctxt (StmtTreeOne (L _ (BodyStmt _ rhs _ fail_op),_))
- tail _tail_fvs
- | (False,tail') <- needJoin monad_names tail
- = mkApplicativeStmt ctxt
- [ApplicativeArgOne
- { xarg_app_arg_one = noExtField
- , app_arg_pattern = nlWildPatName
- , arg_expr = rhs
- , is_body_stmt = True
- , fail_operator = fail_op}] False tail'
-
-stmtTreeToStmts _monad_names _ctxt (StmtTreeOne (s,_)) tail _tail_fvs =
- return (s : tail, emptyNameSet)
-
-stmtTreeToStmts monad_names ctxt (StmtTreeBind before after) tail tail_fvs = do
- (stmts1, fvs1) <- stmtTreeToStmts monad_names ctxt after tail tail_fvs
- let tail1_fvs = unionNameSets (tail_fvs : map snd (flattenStmtTree after))
- (stmts2, fvs2) <- stmtTreeToStmts monad_names ctxt before stmts1 tail1_fvs
- return (stmts2, fvs1 `plusFV` fvs2)
-
-stmtTreeToStmts monad_names ctxt (StmtTreeApplicative trees) tail tail_fvs = do
- pairs <- mapM (stmtTreeArg ctxt tail_fvs) trees
- let (stmts', fvss) = unzip pairs
- let (need_join, tail') =
- if any hasStrictPattern trees
- then (True, tail)
- else needJoin monad_names tail
-
- (stmts, fvs) <- mkApplicativeStmt ctxt stmts' need_join tail'
- return (stmts, unionNameSets (fvs:fvss))
- where
- stmtTreeArg _ctxt _tail_fvs (StmtTreeOne (L _ (BindStmt _ pat exp _ fail_op), _))
- = return (ApplicativeArgOne
- { xarg_app_arg_one = noExtField
- , app_arg_pattern = pat
- , arg_expr = exp
- , is_body_stmt = False
- , fail_operator = fail_op
- }, emptyFVs)
- stmtTreeArg _ctxt _tail_fvs (StmtTreeOne (L _ (BodyStmt _ exp _ fail_op), _)) =
- return (ApplicativeArgOne
- { xarg_app_arg_one = noExtField
- , app_arg_pattern = nlWildPatName
- , arg_expr = exp
- , is_body_stmt = True
- , fail_operator = fail_op
- }, emptyFVs)
- stmtTreeArg ctxt tail_fvs tree = do
- let stmts = flattenStmtTree tree
- pvarset = mkNameSet (concatMap (collectStmtBinders.unLoc.fst) stmts)
- `intersectNameSet` tail_fvs
- pvars = nameSetElemsStable pvarset
- -- See Note [Deterministic ApplicativeDo and RecursiveDo desugaring]
- pat = mkBigLHsVarPatTup pvars
- tup = mkBigLHsVarTup pvars
- (stmts',fvs2) <- stmtTreeToStmts monad_names ctxt tree [] pvarset
- (mb_ret, fvs1) <-
- if | L _ ApplicativeStmt{} <- last stmts' ->
- return (unLoc tup, emptyNameSet)
- | otherwise -> do
- ret <- lookupSyntaxName' returnMName
- let expr = HsApp noExtField (noLoc (HsVar noExtField (noLoc ret))) tup
- return (expr, emptyFVs)
- return ( ApplicativeArgMany
- { xarg_app_arg_many = noExtField
- , app_stmts = stmts'
- , final_expr = mb_ret
- , bv_pattern = pat
- }
- , fvs1 `plusFV` fvs2)
-
-
--- | Divide a sequence of statements into segments, where no segment
--- depends on any variables defined by a statement in another segment.
-segments
- :: [(ExprLStmt GhcRn, FreeVars)]
- -> [[(ExprLStmt GhcRn, FreeVars)]]
-segments stmts = map fst $ merge $ reverse $ map reverse $ walk (reverse stmts)
- where
- allvars = mkNameSet (concatMap (collectStmtBinders.unLoc.fst) stmts)
-
- -- We would rather not have a segment that just has LetStmts in
- -- it, so combine those with an adjacent segment where possible.
- merge [] = []
- merge (seg : segs)
- = case rest of
- [] -> [(seg,all_lets)]
- ((s,s_lets):ss) | all_lets || s_lets
- -> (seg ++ s, all_lets && s_lets) : ss
- _otherwise -> (seg,all_lets) : rest
- where
- rest = merge segs
- all_lets = all (isLetStmt . fst) seg
-
- -- walk splits the statement sequence into segments, traversing
- -- the sequence from the back to the front, and keeping track of
- -- the set of free variables of the current segment. Whenever
- -- this set of free variables is empty, we have a complete segment.
- walk :: [(ExprLStmt GhcRn, FreeVars)] -> [[(ExprLStmt GhcRn, FreeVars)]]
- walk [] = []
- walk ((stmt,fvs) : stmts) = ((stmt,fvs) : seg) : walk rest
- where (seg,rest) = chunter fvs' stmts
- (_, fvs') = stmtRefs stmt fvs
-
- chunter _ [] = ([], [])
- chunter vars ((stmt,fvs) : rest)
- | not (isEmptyNameSet vars)
- || isStrictPatternBind stmt
- -- See Note [ApplicativeDo and strict patterns]
- = ((stmt,fvs) : chunk, rest')
- where (chunk,rest') = chunter vars' rest
- (pvars, evars) = stmtRefs stmt fvs
- vars' = (vars `minusNameSet` pvars) `unionNameSet` evars
- chunter _ rest = ([], rest)
-
- stmtRefs stmt fvs
- | isLetStmt stmt = (pvars, fvs' `minusNameSet` pvars)
- | otherwise = (pvars, fvs')
- where fvs' = fvs `intersectNameSet` allvars
- pvars = mkNameSet (collectStmtBinders (unLoc stmt))
-
- isStrictPatternBind :: ExprLStmt GhcRn -> Bool
- isStrictPatternBind (L _ (BindStmt _ pat _ _ _)) = isStrictPattern pat
- isStrictPatternBind _ = False
-
-{-
-Note [ApplicativeDo and strict patterns]
-
-A strict pattern match is really a dependency. For example,
-
-do
- (x,y) <- A
- z <- B
- return C
-
-The pattern (_,_) must be matched strictly before we do B. If we
-allowed this to be transformed into
-
- (\(x,y) -> \z -> C) <$> A <*> B
-
-then it could be lazier than the standard desuraging using >>=. See #13875
-for more examples.
-
-Thus, whenever we have a strict pattern match, we treat it as a
-dependency between that statement and the following one. The
-dependency prevents those two statements from being performed "in
-parallel" in an ApplicativeStmt, but doesn't otherwise affect what we
-can do with the rest of the statements in the same "do" expression.
--}
-
-isStrictPattern :: LPat (GhcPass p) -> Bool
-isStrictPattern lpat =
- case unLoc lpat of
- WildPat{} -> False
- VarPat{} -> False
- LazyPat{} -> False
- AsPat _ _ p -> isStrictPattern p
- ParPat _ p -> isStrictPattern p
- ViewPat _ _ p -> isStrictPattern p
- SigPat _ p _ -> isStrictPattern p
- BangPat{} -> True
- ListPat{} -> True
- TuplePat{} -> True
- SumPat{} -> True
- ConPatIn{} -> True
- ConPatOut{} -> True
- LitPat{} -> True
- NPat{} -> True
- NPlusKPat{} -> True
- SplicePat{} -> True
- _otherwise -> panic "isStrictPattern"
-
-hasStrictPattern :: ExprStmtTree -> Bool
-hasStrictPattern (StmtTreeOne (L _ (BindStmt _ pat _ _ _), _)) = isStrictPattern pat
-hasStrictPattern (StmtTreeOne _) = False
-hasStrictPattern (StmtTreeBind a b) = hasStrictPattern a || hasStrictPattern b
-hasStrictPattern (StmtTreeApplicative trees) = any hasStrictPattern trees
-
-
-isLetStmt :: LStmt a b -> Bool
-isLetStmt (L _ LetStmt{}) = True
-isLetStmt _ = False
-
--- | Find a "good" place to insert a bind in an indivisible segment.
--- This is the only place where we use heuristics. The current
--- heuristic is to peel off the first group of independent statements
--- and put the bind after those.
-splitSegment
- :: [(ExprLStmt GhcRn, FreeVars)]
- -> ( [(ExprLStmt GhcRn, FreeVars)]
- , [(ExprLStmt GhcRn, FreeVars)] )
-splitSegment [one,two] = ([one],[two])
- -- there is no choice when there are only two statements; this just saves
- -- some work in a common case.
-splitSegment stmts
- | Just (lets,binds,rest) <- slurpIndependentStmts stmts
- = if not (null lets)
- then (lets, binds++rest)
- else (lets++binds, rest)
- | otherwise
- = case stmts of
- (x:xs) -> ([x],xs)
- _other -> (stmts,[])
-
-slurpIndependentStmts
- :: [(LStmt GhcRn (Located (body GhcRn)), FreeVars)]
- -> Maybe ( [(LStmt GhcRn (Located (body GhcRn)), FreeVars)] -- LetStmts
- , [(LStmt GhcRn (Located (body GhcRn)), FreeVars)] -- BindStmts
- , [(LStmt GhcRn (Located (body GhcRn)), FreeVars)] )
-slurpIndependentStmts stmts = go [] [] emptyNameSet stmts
- where
- -- If we encounter a BindStmt that doesn't depend on a previous BindStmt
- -- in this group, then add it to the group. We have to be careful about
- -- strict patterns though; splitSegments expects that if we return Just
- -- then we have actually done some splitting. Otherwise it will go into
- -- an infinite loop (#14163).
- go lets indep bndrs ((L loc (BindStmt _ pat body bind_op fail_op), fvs): rest)
- | isEmptyNameSet (bndrs `intersectNameSet` fvs) && not (isStrictPattern pat)
- = go lets ((L loc (BindStmt noExtField pat body bind_op fail_op), fvs) : indep)
- bndrs' rest
- where bndrs' = bndrs `unionNameSet` mkNameSet (collectPatBinders pat)
- -- If we encounter a LetStmt that doesn't depend on a BindStmt in this
- -- group, then move it to the beginning, so that it doesn't interfere with
- -- grouping more BindStmts.
- -- TODO: perhaps we shouldn't do this if there are any strict bindings,
- -- because we might be moving evaluation earlier.
- go lets indep bndrs ((L loc (LetStmt noExtField binds), fvs) : rest)
- | isEmptyNameSet (bndrs `intersectNameSet` fvs)
- = go ((L loc (LetStmt noExtField binds), fvs) : lets) indep bndrs rest
- go _ [] _ _ = Nothing
- go _ [_] _ _ = Nothing
- go lets indep _ stmts = Just (reverse lets, reverse indep, stmts)
-
--- | Build an ApplicativeStmt, and strip the "return" from the tail
--- if necessary.
---
--- For example, if we start with
--- do x <- E1; y <- E2; return (f x y)
--- then we get
--- do (E1[x] | E2[y]); f x y
---
--- the LastStmt in this case has the return removed, but we set the
--- flag on the LastStmt to indicate this, so that we can print out the
--- original statement correctly in error messages. It is easier to do
--- it this way rather than try to ignore the return later in both the
--- typechecker and the desugarer (I tried it that way first!).
-mkApplicativeStmt
- :: HsStmtContext Name
- -> [ApplicativeArg GhcRn] -- ^ The args
- -> Bool -- ^ True <=> need a join
- -> [ExprLStmt GhcRn] -- ^ The body statements
- -> RnM ([ExprLStmt GhcRn], FreeVars)
-mkApplicativeStmt ctxt args need_join body_stmts
- = do { (fmap_op, fvs1) <- lookupStmtName ctxt fmapName
- ; (ap_op, fvs2) <- lookupStmtName ctxt apAName
- ; (mb_join, fvs3) <-
- if need_join then
- do { (join_op, fvs) <- lookupStmtName ctxt joinMName
- ; return (Just join_op, fvs) }
- else
- return (Nothing, emptyNameSet)
- ; let applicative_stmt = noLoc $ ApplicativeStmt noExtField
- (zip (fmap_op : repeat ap_op) args)
- mb_join
- ; return ( applicative_stmt : body_stmts
- , fvs1 `plusFV` fvs2 `plusFV` fvs3) }
-
--- | Given the statements following an ApplicativeStmt, determine whether
--- we need a @join@ or not, and remove the @return@ if necessary.
-needJoin :: MonadNames
- -> [ExprLStmt GhcRn]
- -> (Bool, [ExprLStmt GhcRn])
-needJoin _monad_names [] = (False, []) -- we're in an ApplicativeArg
-needJoin monad_names [L loc (LastStmt _ e _ t)]
- | Just arg <- isReturnApp monad_names e =
- (False, [L loc (LastStmt noExtField arg True t)])
-needJoin _monad_names stmts = (True, stmts)
-
--- | @Just e@, if the expression is @return e@ or @return $ e@,
--- otherwise @Nothing@
-isReturnApp :: MonadNames
- -> LHsExpr GhcRn
- -> Maybe (LHsExpr GhcRn)
-isReturnApp monad_names (L _ (HsPar _ expr)) = isReturnApp monad_names expr
-isReturnApp monad_names (L _ e) = case e of
- OpApp _ l op r | is_return l, is_dollar op -> Just r
- HsApp _ f arg | is_return f -> Just arg
- _otherwise -> Nothing
- where
- is_var f (L _ (HsPar _ e)) = is_var f e
- is_var f (L _ (HsAppType _ e _)) = is_var f e
- is_var f (L _ (HsVar _ (L _ r))) = f r
- -- TODO: I don't know how to get this right for rebindable syntax
- is_var _ _ = False
-
- is_return = is_var (\n -> n == return_name monad_names
- || n == pure_name monad_names)
- is_dollar = is_var (`hasKey` dollarIdKey)
-
-{-
-************************************************************************
-* *
-\subsubsection{Errors}
-* *
-************************************************************************
--}
-
-checkEmptyStmts :: HsStmtContext Name -> RnM ()
--- We've seen an empty sequence of Stmts... is that ok?
-checkEmptyStmts ctxt
- = unless (okEmpty ctxt) (addErr (emptyErr ctxt))
-
-okEmpty :: HsStmtContext a -> Bool
-okEmpty (PatGuard {}) = True
-okEmpty _ = False
-
-emptyErr :: HsStmtContext Name -> SDoc
-emptyErr (ParStmtCtxt {}) = text "Empty statement group in parallel comprehension"
-emptyErr (TransStmtCtxt {}) = text "Empty statement group preceding 'group' or 'then'"
-emptyErr ctxt = text "Empty" <+> pprStmtContext ctxt
-
-----------------------
-checkLastStmt :: Outputable (body GhcPs) => HsStmtContext Name
- -> LStmt GhcPs (Located (body GhcPs))
- -> RnM (LStmt GhcPs (Located (body GhcPs)))
-checkLastStmt ctxt lstmt@(L loc stmt)
- = case ctxt of
- ListComp -> check_comp
- MonadComp -> check_comp
- ArrowExpr -> check_do
- DoExpr -> check_do
- MDoExpr -> check_do
- _ -> check_other
- where
- check_do -- Expect BodyStmt, and change it to LastStmt
- = case stmt of
- BodyStmt _ e _ _ -> return (L loc (mkLastStmt e))
- LastStmt {} -> return lstmt -- "Deriving" clauses may generate a
- -- LastStmt directly (unlike the parser)
- _ -> do { addErr (hang last_error 2 (ppr stmt)); return lstmt }
- last_error = (text "The last statement in" <+> pprAStmtContext ctxt
- <+> text "must be an expression")
-
- check_comp -- Expect LastStmt; this should be enforced by the parser!
- = case stmt of
- LastStmt {} -> return lstmt
- _ -> pprPanic "checkLastStmt" (ppr lstmt)
-
- check_other -- Behave just as if this wasn't the last stmt
- = do { checkStmt ctxt lstmt; return lstmt }
-
--- Checking when a particular Stmt is ok
-checkStmt :: HsStmtContext Name
- -> LStmt GhcPs (Located (body GhcPs))
- -> RnM ()
-checkStmt ctxt (L _ stmt)
- = do { dflags <- getDynFlags
- ; case okStmt dflags ctxt stmt of
- IsValid -> return ()
- NotValid extra -> addErr (msg $$ extra) }
- where
- msg = sep [ text "Unexpected" <+> pprStmtCat stmt <+> ptext (sLit "statement")
- , text "in" <+> pprAStmtContext ctxt ]
-
-pprStmtCat :: Stmt (GhcPass a) body -> SDoc
-pprStmtCat (TransStmt {}) = text "transform"
-pprStmtCat (LastStmt {}) = text "return expression"
-pprStmtCat (BodyStmt {}) = text "body"
-pprStmtCat (BindStmt {}) = text "binding"
-pprStmtCat (LetStmt {}) = text "let"
-pprStmtCat (RecStmt {}) = text "rec"
-pprStmtCat (ParStmt {}) = text "parallel"
-pprStmtCat (ApplicativeStmt {}) = panic "pprStmtCat: ApplicativeStmt"
-pprStmtCat (XStmtLR nec) = noExtCon nec
-
-------------
-emptyInvalid :: Validity -- Payload is the empty document
-emptyInvalid = NotValid Outputable.empty
-
-okStmt, okDoStmt, okCompStmt, okParStmt
- :: DynFlags -> HsStmtContext Name
- -> Stmt GhcPs (Located (body GhcPs)) -> Validity
--- Return Nothing if OK, (Just extra) if not ok
--- The "extra" is an SDoc that is appended to a generic error message
-
-okStmt dflags ctxt stmt
- = case ctxt of
- PatGuard {} -> okPatGuardStmt stmt
- ParStmtCtxt ctxt -> okParStmt dflags ctxt stmt
- DoExpr -> okDoStmt dflags ctxt stmt
- MDoExpr -> okDoStmt dflags ctxt stmt
- ArrowExpr -> okDoStmt dflags ctxt stmt
- GhciStmtCtxt -> okDoStmt dflags ctxt stmt
- ListComp -> okCompStmt dflags ctxt stmt
- MonadComp -> okCompStmt dflags ctxt stmt
- TransStmtCtxt ctxt -> okStmt dflags ctxt stmt
-
--------------
-okPatGuardStmt :: Stmt GhcPs (Located (body GhcPs)) -> Validity
-okPatGuardStmt stmt
- = case stmt of
- BodyStmt {} -> IsValid
- BindStmt {} -> IsValid
- LetStmt {} -> IsValid
- _ -> emptyInvalid
-
--------------
-okParStmt dflags ctxt stmt
- = case stmt of
- LetStmt _ (L _ (HsIPBinds {})) -> emptyInvalid
- _ -> okStmt dflags ctxt stmt
-
-----------------
-okDoStmt dflags ctxt stmt
- = case stmt of
- RecStmt {}
- | LangExt.RecursiveDo `xopt` dflags -> IsValid
- | ArrowExpr <- ctxt -> IsValid -- Arrows allows 'rec'
- | otherwise -> NotValid (text "Use RecursiveDo")
- BindStmt {} -> IsValid
- LetStmt {} -> IsValid
- BodyStmt {} -> IsValid
- _ -> emptyInvalid
-
-----------------
-okCompStmt dflags _ stmt
- = case stmt of
- BindStmt {} -> IsValid
- LetStmt {} -> IsValid
- BodyStmt {} -> IsValid
- ParStmt {}
- | LangExt.ParallelListComp `xopt` dflags -> IsValid
- | otherwise -> NotValid (text "Use ParallelListComp")
- TransStmt {}
- | LangExt.TransformListComp `xopt` dflags -> IsValid
- | otherwise -> NotValid (text "Use TransformListComp")
- RecStmt {} -> emptyInvalid
- LastStmt {} -> emptyInvalid -- Should not happen (dealt with by checkLastStmt)
- ApplicativeStmt {} -> emptyInvalid
- XStmtLR nec -> noExtCon nec
-
----------
-checkTupleSection :: [LHsTupArg GhcPs] -> RnM ()
-checkTupleSection args
- = do { tuple_section <- xoptM LangExt.TupleSections
- ; checkErr (all tupArgPresent args || tuple_section) msg }
- where
- msg = text "Illegal tuple section: use TupleSections"
-
----------
-sectionErr :: HsExpr GhcPs -> SDoc
-sectionErr expr
- = hang (text "A section must be enclosed in parentheses")
- 2 (text "thus:" <+> (parens (ppr expr)))
-
-badIpBinds :: Outputable a => SDoc -> a -> SDoc
-badIpBinds what binds
- = hang (text "Implicit-parameter bindings illegal in" <+> what)
- 2 (ppr binds)
-
----------
-
-monadFailOp :: LPat GhcPs
- -> HsStmtContext Name
- -> RnM (SyntaxExpr GhcRn, FreeVars)
-monadFailOp pat ctxt
- -- If the pattern is irrefutable (e.g.: wildcard, tuple, ~pat, etc.)
- -- we should not need to fail.
- | isIrrefutableHsPat pat = return (noSyntaxExpr, emptyFVs)
-
- -- For non-monadic contexts (e.g. guard patterns, list
- -- comprehensions, etc.) we should not need to fail. See Note
- -- [Failing pattern matches in Stmts]
- | not (isMonadFailStmtContext ctxt) = return (noSyntaxExpr, emptyFVs)
-
- | otherwise = getMonadFailOp
-
-{-
-Note [Monad fail : Rebindable syntax, overloaded strings]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Given the code
- foo x = do { Just y <- x; return y }
-
-we expect it to desugar as
- foo x = x >>= \r -> case r of
- Just y -> return y
- Nothing -> fail "Pattern match error"
-
-But with RebindableSyntax and OverloadedStrings, we really want
-it to desugar thus:
- foo x = x >>= \r -> case r of
- Just y -> return y
- Nothing -> fail (fromString "Patterm match error")
-
-So, in this case, we synthesize the function
- \x -> fail (fromString x)
-
-(rather than plain 'fail') for the 'fail' operation. This is done in
-'getMonadFailOp'.
--}
-getMonadFailOp :: RnM (SyntaxExpr GhcRn, FreeVars) -- Syntax expr fail op
-getMonadFailOp
- = do { xOverloadedStrings <- fmap (xopt LangExt.OverloadedStrings) getDynFlags
- ; xRebindableSyntax <- fmap (xopt LangExt.RebindableSyntax) getDynFlags
- ; reallyGetMonadFailOp xRebindableSyntax xOverloadedStrings
- }
- where
- reallyGetMonadFailOp rebindableSyntax overloadedStrings
- | rebindableSyntax && overloadedStrings = do
- (failExpr, failFvs) <- lookupSyntaxName failMName
- (fromStringExpr, fromStringFvs) <- lookupSyntaxName fromStringName
- let arg_lit = fsLit "arg"
- arg_name = mkSystemVarName (mkVarOccUnique arg_lit) arg_lit
- arg_syn_expr = mkRnSyntaxExpr arg_name
- let body :: LHsExpr GhcRn =
- nlHsApp (noLoc $ syn_expr failExpr)
- (nlHsApp (noLoc $ syn_expr fromStringExpr)
- (noLoc $ syn_expr arg_syn_expr))
- let failAfterFromStringExpr :: HsExpr GhcRn =
- unLoc $ mkHsLam [noLoc $ VarPat noExtField $ noLoc arg_name] body
- let failAfterFromStringSynExpr :: SyntaxExpr GhcRn =
- mkSyntaxExpr failAfterFromStringExpr
- return (failAfterFromStringSynExpr, failFvs `plusFV` fromStringFvs)
- | otherwise = lookupSyntaxName failMName
diff --git a/compiler/rename/RnExpr.hs-boot b/compiler/rename/RnExpr.hs-boot
deleted file mode 100644
index 8a9c7818a1..0000000000
--- a/compiler/rename/RnExpr.hs-boot
+++ /dev/null
@@ -1,17 +0,0 @@
-module RnExpr where
-import Name
-import GHC.Hs
-import NameSet ( FreeVars )
-import TcRnTypes
-import SrcLoc ( Located )
-import Outputable ( Outputable )
-
-rnLExpr :: LHsExpr GhcPs
- -> RnM (LHsExpr GhcRn, FreeVars)
-
-rnStmts :: --forall thing body.
- Outputable (body GhcPs) => HsStmtContext Name
- -> (Located (body GhcPs) -> RnM (Located (body GhcRn), FreeVars))
- -> [LStmt GhcPs (Located (body GhcPs))]
- -> ([Name] -> RnM (thing, FreeVars))
- -> RnM (([LStmt GhcRn (Located (body GhcRn))], thing), FreeVars)
diff --git a/compiler/rename/RnFixity.hs b/compiler/rename/RnFixity.hs
deleted file mode 100644
index aeff25094f..0000000000
--- a/compiler/rename/RnFixity.hs
+++ /dev/null
@@ -1,214 +0,0 @@
-{-# LANGUAGE ViewPatterns #-}
-
-{-
-
-This module contains code which maintains and manipulates the
-fixity environment during renaming.
-
--}
-module RnFixity ( MiniFixityEnv,
- addLocalFixities,
- lookupFixityRn, lookupFixityRn_help,
- lookupFieldFixityRn, lookupTyFixityRn ) where
-
-import GhcPrelude
-
-import GHC.Iface.Load
-import GHC.Hs
-import RdrName
-import HscTypes
-import TcRnMonad
-import Name
-import NameEnv
-import Module
-import BasicTypes ( Fixity(..), FixityDirection(..), minPrecedence,
- defaultFixity, SourceText(..) )
-import SrcLoc
-import Outputable
-import Maybes
-import Data.List
-import Data.Function ( on )
-import RnUnbound
-
-{-
-*********************************************************
-* *
- Fixities
-* *
-*********************************************************
-
-Note [Fixity signature lookup]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A fixity declaration like
-
- infixr 2 ?
-
-can refer to a value-level operator, e.g.:
-
- (?) :: String -> String -> String
-
-or a type-level operator, like:
-
- data (?) a b = A a | B b
-
-so we extend the lookup of the reader name '?' to the TcClsName namespace, as
-well as the original namespace.
-
-The extended lookup is also used in other places, like resolution of
-deprecation declarations, and lookup of names in GHCi.
--}
-
---------------------------------
-type MiniFixityEnv = FastStringEnv (Located Fixity)
- -- Mini fixity env for the names we're about
- -- to bind, in a single binding group
- --
- -- It is keyed by the *FastString*, not the *OccName*, because
- -- the single fixity decl infix 3 T
- -- affects both the data constructor T and the type constrctor T
- --
- -- We keep the location so that if we find
- -- a duplicate, we can report it sensibly
-
---------------------------------
--- Used for nested fixity decls to bind names along with their fixities.
--- the fixities are given as a UFM from an OccName's FastString to a fixity decl
-
-addLocalFixities :: MiniFixityEnv -> [Name] -> RnM a -> RnM a
-addLocalFixities mini_fix_env names thing_inside
- = extendFixityEnv (mapMaybe find_fixity names) thing_inside
- where
- find_fixity name
- = case lookupFsEnv mini_fix_env (occNameFS occ) of
- Just lfix -> Just (name, FixItem occ (unLoc lfix))
- Nothing -> Nothing
- where
- occ = nameOccName name
-
-{-
---------------------------------
-lookupFixity is a bit strange.
-
-* Nested local fixity decls are put in the local fixity env, which we
- find with getFixtyEnv
-
-* Imported fixities are found in the PIT
-
-* Top-level fixity decls in this module may be for Names that are
- either Global (constructors, class operations)
- or Local/Exported (everything else)
- (See notes with RnNames.getLocalDeclBinders for why we have this split.)
- We put them all in the local fixity environment
--}
-
-lookupFixityRn :: Name -> RnM Fixity
-lookupFixityRn name = lookupFixityRn' name (nameOccName name)
-
-lookupFixityRn' :: Name -> OccName -> RnM Fixity
-lookupFixityRn' name = fmap snd . lookupFixityRn_help' name
-
--- | 'lookupFixityRn_help' returns @(True, fixity)@ if it finds a 'Fixity'
--- in a local environment or from an interface file. Otherwise, it returns
--- @(False, fixity)@ (e.g., for unbound 'Name's or 'Name's without
--- user-supplied fixity declarations).
-lookupFixityRn_help :: Name
- -> RnM (Bool, Fixity)
-lookupFixityRn_help name =
- lookupFixityRn_help' name (nameOccName name)
-
-lookupFixityRn_help' :: Name
- -> OccName
- -> RnM (Bool, Fixity)
-lookupFixityRn_help' name occ
- | isUnboundName name
- = return (False, Fixity NoSourceText minPrecedence InfixL)
- -- Minimise errors from ubound names; eg
- -- a>0 `foo` b>0
- -- where 'foo' is not in scope, should not give an error (#7937)
-
- | otherwise
- = do { local_fix_env <- getFixityEnv
- ; case lookupNameEnv local_fix_env name of {
- Just (FixItem _ fix) -> return (True, fix) ;
- Nothing ->
-
- do { this_mod <- getModule
- ; if nameIsLocalOrFrom this_mod name
- -- Local (and interactive) names are all in the
- -- fixity env, and don't have entries in the HPT
- then return (False, defaultFixity)
- else lookup_imported } } }
- where
- lookup_imported
- -- For imported names, we have to get their fixities by doing a
- -- loadInterfaceForName, and consulting the Ifaces that comes back
- -- from that, because the interface file for the Name might not
- -- have been loaded yet. Why not? Suppose you import module A,
- -- which exports a function 'f', thus;
- -- module CurrentModule where
- -- import A( f )
- -- module A( f ) where
- -- import B( f )
- -- Then B isn't loaded right away (after all, it's possible that
- -- nothing from B will be used). When we come across a use of
- -- 'f', we need to know its fixity, and it's then, and only
- -- then, that we load B.hi. That is what's happening here.
- --
- -- loadInterfaceForName will find B.hi even if B is a hidden module,
- -- and that's what we want.
- = do { iface <- loadInterfaceForName doc name
- ; let mb_fix = mi_fix_fn (mi_final_exts iface) occ
- ; let msg = case mb_fix of
- Nothing ->
- text "looking up name" <+> ppr name
- <+> text "in iface, but found no fixity for it."
- <+> text "Using default fixity instead."
- Just f ->
- text "looking up name in iface and found:"
- <+> vcat [ppr name, ppr f]
- ; traceRn "lookupFixityRn_either:" msg
- ; return (maybe (False, defaultFixity) (\f -> (True, f)) mb_fix) }
-
- doc = text "Checking fixity for" <+> ppr name
-
----------------
-lookupTyFixityRn :: Located Name -> RnM Fixity
-lookupTyFixityRn = lookupFixityRn . unLoc
-
--- | Look up the fixity of a (possibly ambiguous) occurrence of a record field
--- selector. We use 'lookupFixityRn'' so that we can specifiy the 'OccName' as
--- the field label, which might be different to the 'OccName' of the selector
--- 'Name' if @DuplicateRecordFields@ is in use (#1173). If there are
--- multiple possible selectors with different fixities, generate an error.
-lookupFieldFixityRn :: AmbiguousFieldOcc GhcRn -> RnM Fixity
-lookupFieldFixityRn (Unambiguous n lrdr)
- = lookupFixityRn' n (rdrNameOcc (unLoc lrdr))
-lookupFieldFixityRn (Ambiguous _ lrdr) = get_ambiguous_fixity (unLoc lrdr)
- where
- get_ambiguous_fixity :: RdrName -> RnM Fixity
- get_ambiguous_fixity rdr_name = do
- traceRn "get_ambiguous_fixity" (ppr rdr_name)
- rdr_env <- getGlobalRdrEnv
- let elts = lookupGRE_RdrName rdr_name rdr_env
-
- fixities <- groupBy ((==) `on` snd) . zip elts
- <$> mapM lookup_gre_fixity elts
-
- case fixities of
- -- There should always be at least one fixity.
- -- Something's very wrong if there are no fixity candidates, so panic
- [] -> panic "get_ambiguous_fixity: no candidates for a given RdrName"
- [ (_, fix):_ ] -> return fix
- ambigs -> addErr (ambiguous_fixity_err rdr_name ambigs)
- >> return (Fixity NoSourceText minPrecedence InfixL)
-
- lookup_gre_fixity gre = lookupFixityRn' (gre_name gre) (greOccName gre)
-
- ambiguous_fixity_err rn ambigs
- = vcat [ text "Ambiguous fixity for record field" <+> quotes (ppr rn)
- , hang (text "Conflicts: ") 2 . vcat .
- map format_ambig $ concat ambigs ]
-
- format_ambig (elt, fix) = hang (ppr fix)
- 2 (pprNameProvenance elt)
-lookupFieldFixityRn (XAmbiguousFieldOcc nec) = noExtCon nec
diff --git a/compiler/rename/RnHsDoc.hs b/compiler/rename/RnHsDoc.hs
deleted file mode 100644
index 6af59a0210..0000000000
--- a/compiler/rename/RnHsDoc.hs
+++ /dev/null
@@ -1,25 +0,0 @@
-{-# LANGUAGE ViewPatterns #-}
-
-module RnHsDoc ( rnHsDoc, rnLHsDoc, rnMbLHsDoc ) where
-
-import GhcPrelude
-
-import TcRnTypes
-import GHC.Hs
-import SrcLoc
-
-
-rnMbLHsDoc :: Maybe LHsDocString -> RnM (Maybe LHsDocString)
-rnMbLHsDoc mb_doc = case mb_doc of
- Just doc -> do
- doc' <- rnLHsDoc doc
- return (Just doc')
- Nothing -> return Nothing
-
-rnLHsDoc :: LHsDocString -> RnM LHsDocString
-rnLHsDoc (L pos doc) = do
- doc' <- rnHsDoc doc
- return (L pos doc')
-
-rnHsDoc :: HsDocString -> RnM HsDocString
-rnHsDoc = pure
diff --git a/compiler/rename/RnNames.hs b/compiler/rename/RnNames.hs
deleted file mode 100644
index 7cb2aeafbb..0000000000
--- a/compiler/rename/RnNames.hs
+++ /dev/null
@@ -1,1783 +0,0 @@
-{-
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-\section[RnNames]{Extracting imported and top-level names in scope}
--}
-
-{-# LANGUAGE CPP, NondecreasingIndentation, MultiWayIf, NamedFieldPuns #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeFamilies #-}
-
-module RnNames (
- rnImports, getLocalNonValBinders, newRecordSelector,
- extendGlobalRdrEnvRn,
- gresFromAvails,
- calculateAvails,
- reportUnusedNames,
- checkConName,
- mkChildEnv,
- findChildren,
- dodgyMsg,
- dodgyMsgInsert,
- findImportUsage,
- getMinimalImports,
- printMinimalImports,
- ImportDeclUsage
- ) where
-
-#include "HsVersions.h"
-
-import GhcPrelude
-
-import DynFlags
-import TyCoPpr
-import GHC.Hs
-import TcEnv
-import RnEnv
-import RnFixity
-import RnUtils ( warnUnusedTopBinds, mkFieldEnv )
-import GHC.Iface.Load ( loadSrcInterface )
-import TcRnMonad
-import PrelNames
-import Module
-import Name
-import NameEnv
-import NameSet
-import Avail
-import FieldLabel
-import HscTypes
-import RdrName
-import RdrHsSyn ( setRdrNameSpace )
-import Outputable
-import Maybes
-import SrcLoc
-import BasicTypes ( TopLevelFlag(..), StringLiteral(..) )
-import Util
-import FastString
-import FastStringEnv
-import Id
-import Type
-import PatSyn
-import qualified GHC.LanguageExtensions as LangExt
-
-import Control.Monad
-import Data.Either ( partitionEithers, isRight, rights )
-import Data.Map ( Map )
-import qualified Data.Map as Map
-import Data.Ord ( comparing )
-import Data.List ( partition, (\\), find, sortBy )
-import qualified Data.Set as S
-import System.FilePath ((</>))
-
-import System.IO
-
-{-
-************************************************************************
-* *
-\subsection{rnImports}
-* *
-************************************************************************
-
-Note [Tracking Trust Transitively]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When we import a package as well as checking that the direct imports are safe
-according to the rules outlined in the Note [HscMain . Safe Haskell Trust Check]
-we must also check that these rules hold transitively for all dependent modules
-and packages. Doing this without caching any trust information would be very
-slow as we would need to touch all packages and interface files a module depends
-on. To avoid this we make use of the property that if a modules Safe Haskell
-mode changes, this triggers a recompilation from that module in the dependcy
-graph. So we can just worry mostly about direct imports.
-
-There is one trust property that can change for a package though without
-recompilation being triggered: package trust. So we must check that all
-packages a module tranitively depends on to be trusted are still trusted when
-we are compiling this module (as due to recompilation avoidance some modules
-below may not be considered trusted any more without recompilation being
-triggered).
-
-We handle this by augmenting the existing transitive list of packages a module M
-depends on with a bool for each package that says if it must be trusted when the
-module M is being checked for trust. This list of trust required packages for a
-single import is gathered in the rnImportDecl function and stored in an
-ImportAvails data structure. The union of these trust required packages for all
-imports is done by the rnImports function using the combine function which calls
-the plusImportAvails function that is a union operation for the ImportAvails
-type. This gives us in an ImportAvails structure all packages required to be
-trusted for the module we are currently compiling. Checking that these packages
-are still trusted (and that direct imports are trusted) is done in
-HscMain.checkSafeImports.
-
-See the note below, [Trust Own Package] for a corner case in this method and
-how its handled.
-
-
-Note [Trust Own Package]
-~~~~~~~~~~~~~~~~~~~~~~~~
-There is a corner case of package trust checking that the usual transitive check
-doesn't cover. (For how the usual check operates see the Note [Tracking Trust
-Transitively] below). The case is when you import a -XSafe module M and M
-imports a -XTrustworthy module N. If N resides in a different package than M,
-then the usual check works as M will record a package dependency on N's package
-and mark it as required to be trusted. If N resides in the same package as M
-though, then importing M should require its own package be trusted due to N
-(since M is -XSafe so doesn't create this requirement by itself). The usual
-check fails as a module doesn't record a package dependency of its own package.
-So instead we now have a bool field in a modules interface file that simply
-states if the module requires its own package to be trusted. This field avoids
-us having to load all interface files that the module depends on to see if one
-is trustworthy.
-
-
-Note [Trust Transitive Property]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-So there is an interesting design question in regards to transitive trust
-checking. Say I have a module B compiled with -XSafe. B is dependent on a bunch
-of modules and packages, some packages it requires to be trusted as its using
--XTrustworthy modules from them. Now if I have a module A that doesn't use safe
-haskell at all and simply imports B, should A inherit all the trust
-requirements from B? Should A now also require that a package p is trusted since
-B required it?
-
-We currently say no but saying yes also makes sense. The difference is, if a
-module M that doesn't use Safe Haskell imports a module N that does, should all
-the trusted package requirements be dropped since M didn't declare that it cares
-about Safe Haskell (so -XSafe is more strongly associated with the module doing
-the importing) or should it be done still since the author of the module N that
-uses Safe Haskell said they cared (so -XSafe is more strongly associated with
-the module that was compiled that used it).
-
-Going with yes is a simpler semantics we think and harder for the user to stuff
-up but it does mean that Safe Haskell will affect users who don't care about
-Safe Haskell as they might grab a package from Cabal which uses safe haskell (say
-network) and that packages imports -XTrustworthy modules from another package
-(say bytestring), so requires that package is trusted. The user may now get
-compilation errors in code that doesn't do anything with Safe Haskell simply
-because they are using the network package. They will have to call 'ghc-pkg
-trust network' to get everything working. Due to this invasive nature of going
-with yes we have gone with no for now.
--}
-
--- | Process Import Decls. See 'rnImportDecl' for a description of what
--- the return types represent.
--- Note: Do the non SOURCE ones first, so that we get a helpful warning
--- for SOURCE ones that are unnecessary
-rnImports :: [LImportDecl GhcPs]
- -> RnM ([LImportDecl GhcRn], GlobalRdrEnv, ImportAvails, AnyHpcUsage)
-rnImports imports = do
- tcg_env <- getGblEnv
- -- NB: want an identity module here, because it's OK for a signature
- -- module to import from its implementor
- let this_mod = tcg_mod tcg_env
- let (source, ordinary) = partition is_source_import imports
- is_source_import d = ideclSource (unLoc d)
- stuff1 <- mapAndReportM (rnImportDecl this_mod) ordinary
- stuff2 <- mapAndReportM (rnImportDecl this_mod) source
- -- Safe Haskell: See Note [Tracking Trust Transitively]
- let (decls, rdr_env, imp_avails, hpc_usage) = combine (stuff1 ++ stuff2)
- return (decls, rdr_env, imp_avails, hpc_usage)
-
- where
- -- See Note [Combining ImportAvails]
- combine :: [(LImportDecl GhcRn, GlobalRdrEnv, ImportAvails, AnyHpcUsage)]
- -> ([LImportDecl GhcRn], GlobalRdrEnv, ImportAvails, AnyHpcUsage)
- combine ss =
- let (decls, rdr_env, imp_avails, hpc_usage, finsts) = foldr
- plus
- ([], emptyGlobalRdrEnv, emptyImportAvails, False, emptyModuleSet)
- ss
- in (decls, rdr_env, imp_avails { imp_finsts = moduleSetElts finsts },
- hpc_usage)
-
- plus (decl, gbl_env1, imp_avails1, hpc_usage1)
- (decls, gbl_env2, imp_avails2, hpc_usage2, finsts_set)
- = ( decl:decls,
- gbl_env1 `plusGlobalRdrEnv` gbl_env2,
- imp_avails1' `plusImportAvails` imp_avails2,
- hpc_usage1 || hpc_usage2,
- extendModuleSetList finsts_set new_finsts )
- where
- imp_avails1' = imp_avails1 { imp_finsts = [] }
- new_finsts = imp_finsts imp_avails1
-
-{-
-Note [Combining ImportAvails]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-imp_finsts in ImportAvails is a list of family instance modules
-transitively depended on by an import. imp_finsts for a currently
-compiled module is a union of all the imp_finsts of imports.
-Computing the union of two lists of size N is O(N^2) and if we
-do it to M imports we end up with O(M*N^2). That can get very
-expensive for bigger module hierarchies.
-
-Union can be optimized to O(N log N) if we use a Set.
-imp_finsts is converted back and forth between dep_finsts, so
-changing a type of imp_finsts means either paying for the conversions
-or changing the type of dep_finsts as well.
-
-I've measured that the conversions would cost 20% of allocations on my
-test case, so that can be ruled out.
-
-Changing the type of dep_finsts forces checkFamInsts to
-get the module lists in non-deterministic order. If we wanted to restore
-the deterministic order, we'd have to sort there, which is an additional
-cost. As far as I can tell, using a non-deterministic order is fine there,
-but that's a brittle nonlocal property which I'd like to avoid.
-
-Additionally, dep_finsts is read from an interface file, so its "natural"
-type is a list. Which makes it a natural type for imp_finsts.
-
-Since rnImports.combine is really the only place that would benefit from
-it being a Set, it makes sense to optimize the hot loop in rnImports.combine
-without changing the representation.
-
-So here's what we do: instead of naively merging ImportAvails with
-plusImportAvails in a loop, we make plusImportAvails merge empty imp_finsts
-and compute the union on the side using Sets. When we're done, we can
-convert it back to a list. One nice side effect of this approach is that
-if there's a lot of overlap in the imp_finsts of imports, the
-Set doesn't really need to grow and we don't need to allocate.
-
-Running generateModules from #14693 with DEPTH=16, WIDTH=30 finishes in
-23s before, and 11s after.
--}
-
-
-
--- | Given a located import declaration @decl@ from @this_mod@,
--- calculate the following pieces of information:
---
--- 1. An updated 'LImportDecl', where all unresolved 'RdrName' in
--- the entity lists have been resolved into 'Name's,
---
--- 2. A 'GlobalRdrEnv' representing the new identifiers that were
--- brought into scope (taking into account module qualification
--- and hiding),
---
--- 3. 'ImportAvails' summarizing the identifiers that were imported
--- by this declaration, and
---
--- 4. A boolean 'AnyHpcUsage' which is true if the imported module
--- used HPC.
-rnImportDecl :: Module -> LImportDecl GhcPs
- -> RnM (LImportDecl GhcRn, GlobalRdrEnv, ImportAvails, AnyHpcUsage)
-rnImportDecl this_mod
- (L loc decl@(ImportDecl { ideclExt = noExtField
- , ideclName = loc_imp_mod_name
- , ideclPkgQual = mb_pkg
- , ideclSource = want_boot, ideclSafe = mod_safe
- , ideclQualified = qual_style, ideclImplicit = implicit
- , ideclAs = as_mod, ideclHiding = imp_details }))
- = setSrcSpan loc $ do
-
- when (isJust mb_pkg) $ do
- pkg_imports <- xoptM LangExt.PackageImports
- when (not pkg_imports) $ addErr packageImportErr
-
- let qual_only = isImportDeclQualified qual_style
-
- -- If there's an error in loadInterface, (e.g. interface
- -- file not found) we get lots of spurious errors from 'filterImports'
- let imp_mod_name = unLoc loc_imp_mod_name
- doc = ppr imp_mod_name <+> text "is directly imported"
-
- -- Check for self-import, which confuses the typechecker (#9032)
- -- ghc --make rejects self-import cycles already, but batch-mode may not
- -- at least not until GHC.IfaceToCore.tcHiBootIface, which is too late to avoid
- -- typechecker crashes. (Indirect self imports are not caught until
- -- GHC.IfaceToCore, see #10337 tracking how to make this error better.)
- --
- -- Originally, we also allowed 'import {-# SOURCE #-} M', but this
- -- caused bug #10182: in one-shot mode, we should never load an hs-boot
- -- file for the module we are compiling into the EPS. In principle,
- -- it should be possible to support this mode of use, but we would have to
- -- extend Provenance to support a local definition in a qualified location.
- -- For now, we don't support it, but see #10336
- when (imp_mod_name == moduleName this_mod &&
- (case mb_pkg of -- If we have import "<pkg>" M, then we should
- -- check that "<pkg>" is "this" (which is magic)
- -- or the name of this_mod's package. Yurgh!
- -- c.f. GHC.findModule, and #9997
- Nothing -> True
- Just (StringLiteral _ pkg_fs) -> pkg_fs == fsLit "this" ||
- fsToUnitId pkg_fs == moduleUnitId this_mod))
- (addErr (text "A module cannot import itself:" <+> ppr imp_mod_name))
-
- -- Check for a missing import list (Opt_WarnMissingImportList also
- -- checks for T(..) items but that is done in checkDodgyImport below)
- case imp_details of
- Just (False, _) -> return () -- Explicit import list
- _ | implicit -> return () -- Do not bleat for implicit imports
- | qual_only -> return ()
- | otherwise -> whenWOptM Opt_WarnMissingImportList $
- addWarn (Reason Opt_WarnMissingImportList)
- (missingImportListWarn imp_mod_name)
-
- iface <- loadSrcInterface doc imp_mod_name want_boot (fmap sl_fs mb_pkg)
-
- -- Compiler sanity check: if the import didn't say
- -- {-# SOURCE #-} we should not get a hi-boot file
- WARN( not want_boot && mi_boot iface, ppr imp_mod_name ) do
-
- -- Issue a user warning for a redundant {- SOURCE -} import
- -- NB that we arrange to read all the ordinary imports before
- -- any of the {- SOURCE -} imports.
- --
- -- in --make and GHCi, the compilation manager checks for this,
- -- and indeed we shouldn't do it here because the existence of
- -- the non-boot module depends on the compilation order, which
- -- is not deterministic. The hs-boot test can show this up.
- dflags <- getDynFlags
- warnIf (want_boot && not (mi_boot iface) && isOneShot (ghcMode dflags))
- (warnRedundantSourceImport imp_mod_name)
- when (mod_safe && not (safeImportsOn dflags)) $
- addErr (text "safe import can't be used as Safe Haskell isn't on!"
- $+$ ptext (sLit $ "please enable Safe Haskell through either "
- ++ "Safe, Trustworthy or Unsafe"))
-
- let
- qual_mod_name = fmap unLoc as_mod `orElse` imp_mod_name
- imp_spec = ImpDeclSpec { is_mod = imp_mod_name, is_qual = qual_only,
- is_dloc = loc, is_as = qual_mod_name }
-
- -- filter the imports according to the import declaration
- (new_imp_details, gres) <- filterImports iface imp_spec imp_details
-
- -- for certain error messages, we’d like to know what could be imported
- -- here, if everything were imported
- potential_gres <- mkGlobalRdrEnv . snd <$> filterImports iface imp_spec Nothing
-
- let gbl_env = mkGlobalRdrEnv gres
-
- is_hiding | Just (True,_) <- imp_details = True
- | otherwise = False
-
- -- should the import be safe?
- mod_safe' = mod_safe
- || (not implicit && safeDirectImpsReq dflags)
- || (implicit && safeImplicitImpsReq dflags)
-
- let imv = ImportedModsVal
- { imv_name = qual_mod_name
- , imv_span = loc
- , imv_is_safe = mod_safe'
- , imv_is_hiding = is_hiding
- , imv_all_exports = potential_gres
- , imv_qualified = qual_only
- }
- imports = calculateAvails dflags iface mod_safe' want_boot (ImportedByUser imv)
-
- -- Complain if we import a deprecated module
- whenWOptM Opt_WarnWarningsDeprecations (
- case (mi_warns iface) of
- WarnAll txt -> addWarn (Reason Opt_WarnWarningsDeprecations)
- (moduleWarn imp_mod_name txt)
- _ -> return ()
- )
-
- let new_imp_decl = L loc (decl { ideclExt = noExtField, ideclSafe = mod_safe'
- , ideclHiding = new_imp_details })
-
- return (new_imp_decl, gbl_env, imports, mi_hpc iface)
-rnImportDecl _ (L _ (XImportDecl nec)) = noExtCon nec
-
--- | Calculate the 'ImportAvails' induced by an import of a particular
--- interface, but without 'imp_mods'.
-calculateAvails :: DynFlags
- -> ModIface
- -> IsSafeImport
- -> IsBootInterface
- -> ImportedBy
- -> ImportAvails
-calculateAvails dflags iface mod_safe' want_boot imported_by =
- let imp_mod = mi_module iface
- imp_sem_mod= mi_semantic_module iface
- orph_iface = mi_orphan (mi_final_exts iface)
- has_finsts = mi_finsts (mi_final_exts iface)
- deps = mi_deps iface
- trust = getSafeMode $ mi_trust iface
- trust_pkg = mi_trust_pkg iface
-
- -- If the module exports anything defined in this module, just
- -- ignore it. Reason: otherwise it looks as if there are two
- -- local definition sites for the thing, and an error gets
- -- reported. Easiest thing is just to filter them out up
- -- front. This situation only arises if a module imports
- -- itself, or another module that imported it. (Necessarily,
- -- this invoves a loop.)
- --
- -- We do this *after* filterImports, so that if you say
- -- module A where
- -- import B( AType )
- -- type AType = ...
- --
- -- module B( AType ) where
- -- import {-# SOURCE #-} A( AType )
- --
- -- then you won't get a 'B does not export AType' message.
-
-
- -- Compute new transitive dependencies
- --
- -- 'dep_orphs' and 'dep_finsts' do NOT include the imported module
- -- itself, but we DO need to include this module in 'imp_orphs' and
- -- 'imp_finsts' if it defines an orphan or instance family; thus the
- -- orph_iface/has_iface tests.
-
- orphans | orph_iface = ASSERT2( not (imp_sem_mod `elem` dep_orphs deps), ppr imp_sem_mod <+> ppr (dep_orphs deps) )
- imp_sem_mod : dep_orphs deps
- | otherwise = dep_orphs deps
-
- finsts | has_finsts = ASSERT2( not (imp_sem_mod `elem` dep_finsts deps), ppr imp_sem_mod <+> ppr (dep_orphs deps) )
- imp_sem_mod : dep_finsts deps
- | otherwise = dep_finsts deps
-
- pkg = moduleUnitId (mi_module iface)
- ipkg = toInstalledUnitId pkg
-
- -- Does this import mean we now require our own pkg
- -- to be trusted? See Note [Trust Own Package]
- ptrust = trust == Sf_Trustworthy || trust_pkg
-
- (dependent_mods, dependent_pkgs, pkg_trust_req)
- | pkg == thisPackage dflags =
- -- Imported module is from the home package
- -- Take its dependent modules and add imp_mod itself
- -- Take its dependent packages unchanged
- --
- -- NB: (dep_mods deps) might include a hi-boot file
- -- for the module being compiled, CM. Do *not* filter
- -- this out (as we used to), because when we've
- -- finished dealing with the direct imports we want to
- -- know if any of them depended on CM.hi-boot, in
- -- which case we should do the hi-boot consistency
- -- check. See GHC.Iface.Load.loadHiBootInterface
- ((moduleName imp_mod,want_boot):dep_mods deps,dep_pkgs deps,ptrust)
-
- | otherwise =
- -- Imported module is from another package
- -- Dump the dependent modules
- -- Add the package imp_mod comes from to the dependent packages
- ASSERT2( not (ipkg `elem` (map fst $ dep_pkgs deps))
- , ppr ipkg <+> ppr (dep_pkgs deps) )
- ([], (ipkg, False) : dep_pkgs deps, False)
-
- in ImportAvails {
- imp_mods = unitModuleEnv (mi_module iface) [imported_by],
- imp_orphs = orphans,
- imp_finsts = finsts,
- imp_dep_mods = mkModDeps dependent_mods,
- imp_dep_pkgs = S.fromList . map fst $ dependent_pkgs,
- -- Add in the imported modules trusted package
- -- requirements. ONLY do this though if we import the
- -- module as a safe import.
- -- See Note [Tracking Trust Transitively]
- -- and Note [Trust Transitive Property]
- imp_trust_pkgs = if mod_safe'
- then S.fromList . map fst $ filter snd dependent_pkgs
- else S.empty,
- -- Do we require our own pkg to be trusted?
- -- See Note [Trust Own Package]
- imp_trust_own_pkg = pkg_trust_req
- }
-
-
-warnRedundantSourceImport :: ModuleName -> SDoc
-warnRedundantSourceImport mod_name
- = text "Unnecessary {-# SOURCE #-} in the import of module"
- <+> quotes (ppr mod_name)
-
-{-
-************************************************************************
-* *
-\subsection{importsFromLocalDecls}
-* *
-************************************************************************
-
-From the top-level declarations of this module produce
- * the lexical environment
- * the ImportAvails
-created by its bindings.
-
-Note [Top-level Names in Template Haskell decl quotes]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-See also: Note [Interactively-bound Ids in GHCi] in HscTypes
- Note [Looking up Exact RdrNames] in RnEnv
-
-Consider a Template Haskell declaration quotation like this:
- module M where
- f x = h [d| f = 3 |]
-When renaming the declarations inside [d| ...|], we treat the
-top level binders specially in two ways
-
-1. We give them an Internal Name, not (as usual) an External one.
- This is done by RnEnv.newTopSrcBinder.
-
-2. We make them *shadow* the outer bindings.
- See Note [GlobalRdrEnv shadowing]
-
-3. We find out whether we are inside a [d| ... |] by testing the TH
- stage. This is a slight hack, because the stage field was really
- meant for the type checker, and here we are not interested in the
- fields of Brack, hence the error thunks in thRnBrack.
--}
-
-extendGlobalRdrEnvRn :: [AvailInfo]
- -> MiniFixityEnv
- -> RnM (TcGblEnv, TcLclEnv)
--- Updates both the GlobalRdrEnv and the FixityEnv
--- We return a new TcLclEnv only because we might have to
--- delete some bindings from it;
--- see Note [Top-level Names in Template Haskell decl quotes]
-
-extendGlobalRdrEnvRn avails new_fixities
- = do { (gbl_env, lcl_env) <- getEnvs
- ; stage <- getStage
- ; isGHCi <- getIsGHCi
- ; let rdr_env = tcg_rdr_env gbl_env
- fix_env = tcg_fix_env gbl_env
- th_bndrs = tcl_th_bndrs lcl_env
- th_lvl = thLevel stage
-
- -- Delete new_occs from global and local envs
- -- If we are in a TemplateHaskell decl bracket,
- -- we are going to shadow them
- -- See Note [GlobalRdrEnv shadowing]
- inBracket = isBrackStage stage
-
- lcl_env_TH = lcl_env { tcl_rdr = delLocalRdrEnvList (tcl_rdr lcl_env) new_occs }
- -- See Note [GlobalRdrEnv shadowing]
-
- lcl_env2 | inBracket = lcl_env_TH
- | otherwise = lcl_env
-
- -- Deal with shadowing: see Note [GlobalRdrEnv shadowing]
- want_shadowing = isGHCi || inBracket
- rdr_env1 | want_shadowing = shadowNames rdr_env new_names
- | otherwise = rdr_env
-
- lcl_env3 = lcl_env2 { tcl_th_bndrs = extendNameEnvList th_bndrs
- [ (n, (TopLevel, th_lvl))
- | n <- new_names ] }
-
- ; rdr_env2 <- foldlM add_gre rdr_env1 new_gres
-
- ; let fix_env' = foldl' extend_fix_env fix_env new_gres
- gbl_env' = gbl_env { tcg_rdr_env = rdr_env2, tcg_fix_env = fix_env' }
-
- ; traceRn "extendGlobalRdrEnvRn 2" (pprGlobalRdrEnv True rdr_env2)
- ; return (gbl_env', lcl_env3) }
- where
- new_names = concatMap availNames avails
- new_occs = map nameOccName new_names
-
- -- If there is a fixity decl for the gre, add it to the fixity env
- extend_fix_env fix_env gre
- | Just (L _ fi) <- lookupFsEnv new_fixities (occNameFS occ)
- = extendNameEnv fix_env name (FixItem occ fi)
- | otherwise
- = fix_env
- where
- name = gre_name gre
- occ = greOccName gre
-
- new_gres :: [GlobalRdrElt] -- New LocalDef GREs, derived from avails
- new_gres = concatMap localGREsFromAvail avails
-
- add_gre :: GlobalRdrEnv -> GlobalRdrElt -> RnM GlobalRdrEnv
- -- Extend the GlobalRdrEnv with a LocalDef GRE
- -- If there is already a LocalDef GRE with the same OccName,
- -- report an error and discard the new GRE
- -- This establishes INVARIANT 1 of GlobalRdrEnvs
- add_gre env gre
- | not (null dups) -- Same OccName defined twice
- = do { addDupDeclErr (gre : dups); return env }
-
- | otherwise
- = return (extendGlobalRdrEnv env gre)
- where
- name = gre_name gre
- occ = nameOccName name
- dups = filter isLocalGRE (lookupGlobalRdrEnv env occ)
-
-
-{- *********************************************************************
-* *
- getLocalDeclBindersd@ returns the names for an HsDecl
- It's used for source code.
-
- *** See Note [The Naming story] in GHC.Hs.Decls ****
-* *
-********************************************************************* -}
-
-getLocalNonValBinders :: MiniFixityEnv -> HsGroup GhcPs
- -> RnM ((TcGblEnv, TcLclEnv), NameSet)
--- Get all the top-level binders bound the group *except*
--- for value bindings, which are treated separately
--- Specifically we return AvailInfo for
--- * type decls (incl constructors and record selectors)
--- * class decls (including class ops)
--- * associated types
--- * foreign imports
--- * value signatures (in hs-boot files only)
-
-getLocalNonValBinders fixity_env
- (HsGroup { hs_valds = binds,
- hs_tyclds = tycl_decls,
- hs_fords = foreign_decls })
- = do { -- Process all type/class decls *except* family instances
- ; let inst_decls = tycl_decls >>= group_instds
- ; overload_ok <- xoptM LangExt.DuplicateRecordFields
- ; (tc_avails, tc_fldss)
- <- fmap unzip $ mapM (new_tc overload_ok)
- (tyClGroupTyClDecls tycl_decls)
- ; traceRn "getLocalNonValBinders 1" (ppr tc_avails)
- ; envs <- extendGlobalRdrEnvRn tc_avails fixity_env
- ; setEnvs envs $ do {
- -- Bring these things into scope first
- -- See Note [Looking up family names in family instances]
-
- -- Process all family instances
- -- to bring new data constructors into scope
- ; (nti_availss, nti_fldss) <- mapAndUnzipM (new_assoc overload_ok)
- inst_decls
-
- -- Finish off with value binders:
- -- foreign decls and pattern synonyms for an ordinary module
- -- type sigs in case of a hs-boot file only
- ; is_boot <- tcIsHsBootOrSig
- ; let val_bndrs | is_boot = hs_boot_sig_bndrs
- | otherwise = for_hs_bndrs
- ; val_avails <- mapM new_simple val_bndrs
-
- ; let avails = concat nti_availss ++ val_avails
- new_bndrs = availsToNameSetWithSelectors avails `unionNameSet`
- availsToNameSetWithSelectors tc_avails
- flds = concat nti_fldss ++ concat tc_fldss
- ; traceRn "getLocalNonValBinders 2" (ppr avails)
- ; (tcg_env, tcl_env) <- extendGlobalRdrEnvRn avails fixity_env
-
- -- Extend tcg_field_env with new fields (this used to be the
- -- work of extendRecordFieldEnv)
- ; let field_env = extendNameEnvList (tcg_field_env tcg_env) flds
- envs = (tcg_env { tcg_field_env = field_env }, tcl_env)
-
- ; traceRn "getLocalNonValBinders 3" (vcat [ppr flds, ppr field_env])
- ; return (envs, new_bndrs) } }
- where
- ValBinds _ _val_binds val_sigs = binds
-
- for_hs_bndrs :: [Located RdrName]
- for_hs_bndrs = hsForeignDeclsBinders foreign_decls
-
- -- In a hs-boot file, the value binders come from the
- -- *signatures*, and there should be no foreign binders
- hs_boot_sig_bndrs = [ L decl_loc (unLoc n)
- | L decl_loc (TypeSig _ ns _) <- val_sigs, n <- ns]
-
- -- the SrcSpan attached to the input should be the span of the
- -- declaration, not just the name
- new_simple :: Located RdrName -> RnM AvailInfo
- new_simple rdr_name = do{ nm <- newTopSrcBinder rdr_name
- ; return (avail nm) }
-
- new_tc :: Bool -> LTyClDecl GhcPs
- -> RnM (AvailInfo, [(Name, [FieldLabel])])
- new_tc overload_ok tc_decl -- NOT for type/data instances
- = do { let (bndrs, flds) = hsLTyClDeclBinders tc_decl
- ; names@(main_name : sub_names) <- mapM newTopSrcBinder bndrs
- ; flds' <- mapM (newRecordSelector overload_ok sub_names) flds
- ; let fld_env = case unLoc tc_decl of
- DataDecl { tcdDataDefn = d } -> mk_fld_env d names flds'
- _ -> []
- ; return (AvailTC main_name names flds', fld_env) }
-
-
- -- Calculate the mapping from constructor names to fields, which
- -- will go in tcg_field_env. It's convenient to do this here where
- -- we are working with a single datatype definition.
- mk_fld_env :: HsDataDefn GhcPs -> [Name] -> [FieldLabel]
- -> [(Name, [FieldLabel])]
- mk_fld_env d names flds = concatMap find_con_flds (dd_cons d)
- where
- find_con_flds (L _ (ConDeclH98 { con_name = L _ rdr
- , con_args = RecCon cdflds }))
- = [( find_con_name rdr
- , concatMap find_con_decl_flds (unLoc cdflds) )]
- find_con_flds (L _ (ConDeclGADT { con_names = rdrs
- , con_args = RecCon flds }))
- = [ ( find_con_name rdr
- , concatMap find_con_decl_flds (unLoc flds))
- | L _ rdr <- rdrs ]
-
- find_con_flds _ = []
-
- find_con_name rdr
- = expectJust "getLocalNonValBinders/find_con_name" $
- find (\ n -> nameOccName n == rdrNameOcc rdr) names
- find_con_decl_flds (L _ x)
- = map find_con_decl_fld (cd_fld_names x)
-
- find_con_decl_fld (L _ (FieldOcc _ (L _ rdr)))
- = expectJust "getLocalNonValBinders/find_con_decl_fld" $
- find (\ fl -> flLabel fl == lbl) flds
- where lbl = occNameFS (rdrNameOcc rdr)
- find_con_decl_fld (L _ (XFieldOcc nec)) = noExtCon nec
-
- new_assoc :: Bool -> LInstDecl GhcPs
- -> RnM ([AvailInfo], [(Name, [FieldLabel])])
- new_assoc _ (L _ (TyFamInstD {})) = return ([], [])
- -- type instances don't bind new names
-
- new_assoc overload_ok (L _ (DataFamInstD _ d))
- = do { (avail, flds) <- new_di overload_ok Nothing d
- ; return ([avail], flds) }
- new_assoc overload_ok (L _ (ClsInstD _ (ClsInstDecl { cid_poly_ty = inst_ty
- , cid_datafam_insts = adts })))
- = do -- First, attempt to grab the name of the class from the instance.
- -- This step could fail if the instance is not headed by a class,
- -- such as in the following examples:
- --
- -- (1) The class is headed by a bang pattern, such as in
- -- `instance !Show Int` (#3811c)
- -- (2) The class is headed by a type variable, such as in
- -- `instance c` (#16385)
- --
- -- If looking up the class name fails, then mb_cls_nm will
- -- be Nothing.
- mb_cls_nm <- runMaybeT $ do
- -- See (1) above
- L loc cls_rdr <- MaybeT $ pure $ getLHsInstDeclClass_maybe inst_ty
- -- See (2) above
- MaybeT $ setSrcSpan loc $ lookupGlobalOccRn_maybe cls_rdr
- -- Assuming the previous step succeeded, process any associated data
- -- family instances. If the previous step failed, bail out.
- case mb_cls_nm of
- Nothing -> pure ([], [])
- Just cls_nm -> do
- (avails, fldss)
- <- mapAndUnzipM (new_loc_di overload_ok (Just cls_nm)) adts
- pure (avails, concat fldss)
- new_assoc _ (L _ (ClsInstD _ (XClsInstDecl nec))) = noExtCon nec
- new_assoc _ (L _ (XInstDecl nec)) = noExtCon nec
-
- new_di :: Bool -> Maybe Name -> DataFamInstDecl GhcPs
- -> RnM (AvailInfo, [(Name, [FieldLabel])])
- new_di overload_ok mb_cls dfid@(DataFamInstDecl { dfid_eqn =
- HsIB { hsib_body = ti_decl }})
- = do { main_name <- lookupFamInstName mb_cls (feqn_tycon ti_decl)
- ; let (bndrs, flds) = hsDataFamInstBinders dfid
- ; sub_names <- mapM newTopSrcBinder bndrs
- ; flds' <- mapM (newRecordSelector overload_ok sub_names) flds
- ; let avail = AvailTC (unLoc main_name) sub_names flds'
- -- main_name is not bound here!
- fld_env = mk_fld_env (feqn_rhs ti_decl) sub_names flds'
- ; return (avail, fld_env) }
- new_di _ _ (DataFamInstDecl (XHsImplicitBndrs nec)) = noExtCon nec
-
- new_loc_di :: Bool -> Maybe Name -> LDataFamInstDecl GhcPs
- -> RnM (AvailInfo, [(Name, [FieldLabel])])
- new_loc_di overload_ok mb_cls (L _ d) = new_di overload_ok mb_cls d
-getLocalNonValBinders _ (XHsGroup nec) = noExtCon nec
-
-newRecordSelector :: Bool -> [Name] -> LFieldOcc GhcPs -> RnM FieldLabel
-newRecordSelector _ [] _ = error "newRecordSelector: datatype has no constructors!"
-newRecordSelector _ _ (L _ (XFieldOcc nec)) = noExtCon nec
-newRecordSelector overload_ok (dc:_) (L loc (FieldOcc _ (L _ fld)))
- = do { selName <- newTopSrcBinder $ L loc $ field
- ; return $ qualFieldLbl { flSelector = selName } }
- where
- fieldOccName = occNameFS $ rdrNameOcc fld
- qualFieldLbl = mkFieldLabelOccs fieldOccName (nameOccName dc) overload_ok
- field | isExact fld = fld
- -- use an Exact RdrName as is to preserve the bindings
- -- of an already renamer-resolved field and its use
- -- sites. This is needed to correctly support record
- -- selectors in Template Haskell. See Note [Binders in
- -- Template Haskell] in Convert.hs and Note [Looking up
- -- Exact RdrNames] in RnEnv.hs.
- | otherwise = mkRdrUnqual (flSelector qualFieldLbl)
-
-{-
-Note [Looking up family names in family instances]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
-
- module M where
- type family T a :: *
- type instance M.T Int = Bool
-
-We might think that we can simply use 'lookupOccRn' when processing the type
-instance to look up 'M.T'. Alas, we can't! The type family declaration is in
-the *same* HsGroup as the type instance declaration. Hence, as we are
-currently collecting the binders declared in that HsGroup, these binders will
-not have been added to the global environment yet.
-
-Solution is simple: process the type family declarations first, extend
-the environment, and then process the type instances.
-
-
-************************************************************************
-* *
-\subsection{Filtering imports}
-* *
-************************************************************************
-
-@filterImports@ takes the @ExportEnv@ telling what the imported module makes
-available, and filters it through the import spec (if any).
-
-Note [Dealing with imports]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-For import M( ies ), we take the mi_exports of M, and make
- imp_occ_env :: OccEnv (Name, AvailInfo, Maybe Name)
-One entry for each Name that M exports; the AvailInfo is the
-AvailInfo exported from M that exports that Name.
-
-The situation is made more complicated by associated types. E.g.
- module M where
- class C a where { data T a }
- instance C Int where { data T Int = T1 | T2 }
- instance C Bool where { data T Int = T3 }
-Then M's export_avails are (recall the AvailTC invariant from Avails.hs)
- C(C,T), T(T,T1,T2,T3)
-Notice that T appears *twice*, once as a child and once as a parent. From
-this list we construct a raw list including
- T -> (T, T( T1, T2, T3 ), Nothing)
- T -> (C, C( C, T ), Nothing)
-and we combine these (in function 'combine' in 'imp_occ_env' in
-'filterImports') to get
- T -> (T, T(T,T1,T2,T3), Just C)
-
-So the overall imp_occ_env is
- C -> (C, C(C,T), Nothing)
- T -> (T, T(T,T1,T2,T3), Just C)
- T1 -> (T1, T(T,T1,T2,T3), Nothing) -- similarly T2,T3
-
-If we say
- import M( T(T1,T2) )
-then we get *two* Avails: C(T), T(T1,T2)
-
-Note that the imp_occ_env will have entries for data constructors too,
-although we never look up data constructors.
--}
-
-filterImports
- :: ModIface
- -> ImpDeclSpec -- The span for the entire import decl
- -> Maybe (Bool, Located [LIE GhcPs]) -- Import spec; True => hiding
- -> RnM (Maybe (Bool, Located [LIE GhcRn]), -- Import spec w/ Names
- [GlobalRdrElt]) -- Same again, but in GRE form
-filterImports iface decl_spec Nothing
- = return (Nothing, gresFromAvails (Just imp_spec) (mi_exports iface))
- where
- imp_spec = ImpSpec { is_decl = decl_spec, is_item = ImpAll }
-
-
-filterImports iface decl_spec (Just (want_hiding, L l import_items))
- = do -- check for errors, convert RdrNames to Names
- items1 <- mapM lookup_lie import_items
-
- let items2 :: [(LIE GhcRn, AvailInfo)]
- items2 = concat items1
- -- NB the AvailInfo may have duplicates, and several items
- -- for the same parent; e.g N(x) and N(y)
-
- names = availsToNameSetWithSelectors (map snd items2)
- keep n = not (n `elemNameSet` names)
- pruned_avails = filterAvails keep all_avails
- hiding_spec = ImpSpec { is_decl = decl_spec, is_item = ImpAll }
-
- gres | want_hiding = gresFromAvails (Just hiding_spec) pruned_avails
- | otherwise = concatMap (gresFromIE decl_spec) items2
-
- return (Just (want_hiding, L l (map fst items2)), gres)
- where
- all_avails = mi_exports iface
-
- -- See Note [Dealing with imports]
- imp_occ_env :: OccEnv (Name, -- the name
- AvailInfo, -- the export item providing the name
- Maybe Name) -- the parent of associated types
- imp_occ_env = mkOccEnv_C combine [ (occ, (n, a, Nothing))
- | a <- all_avails
- , (n, occ) <- availNamesWithOccs a]
- where
- -- See Note [Dealing with imports]
- -- 'combine' is only called for associated data types which appear
- -- twice in the all_avails. In the example, we combine
- -- T(T,T1,T2,T3) and C(C,T) to give (T, T(T,T1,T2,T3), Just C)
- -- NB: the AvailTC can have fields as well as data constructors (#12127)
- combine (name1, a1@(AvailTC p1 _ _), mp1)
- (name2, a2@(AvailTC p2 _ _), mp2)
- = ASSERT2( name1 == name2 && isNothing mp1 && isNothing mp2
- , ppr name1 <+> ppr name2 <+> ppr mp1 <+> ppr mp2 )
- if p1 == name1 then (name1, a1, Just p2)
- else (name1, a2, Just p1)
- combine x y = pprPanic "filterImports/combine" (ppr x $$ ppr y)
-
- lookup_name :: IE GhcPs -> RdrName -> IELookupM (Name, AvailInfo, Maybe Name)
- lookup_name ie rdr
- | isQual rdr = failLookupWith (QualImportError rdr)
- | Just succ <- mb_success = return succ
- | otherwise = failLookupWith (BadImport ie)
- where
- mb_success = lookupOccEnv imp_occ_env (rdrNameOcc rdr)
-
- lookup_lie :: LIE GhcPs -> TcRn [(LIE GhcRn, AvailInfo)]
- lookup_lie (L loc ieRdr)
- = do (stuff, warns) <- setSrcSpan loc $
- liftM (fromMaybe ([],[])) $
- run_lookup (lookup_ie ieRdr)
- mapM_ emit_warning warns
- return [ (L loc ie, avail) | (ie,avail) <- stuff ]
- where
- -- Warn when importing T(..) if T was exported abstractly
- emit_warning (DodgyImport n) = whenWOptM Opt_WarnDodgyImports $
- addWarn (Reason Opt_WarnDodgyImports) (dodgyImportWarn n)
- emit_warning MissingImportList = whenWOptM Opt_WarnMissingImportList $
- addWarn (Reason Opt_WarnMissingImportList) (missingImportListItem ieRdr)
- emit_warning (BadImportW ie) = whenWOptM Opt_WarnDodgyImports $
- addWarn (Reason Opt_WarnDodgyImports) (lookup_err_msg (BadImport ie))
-
- run_lookup :: IELookupM a -> TcRn (Maybe a)
- run_lookup m = case m of
- Failed err -> addErr (lookup_err_msg err) >> return Nothing
- Succeeded a -> return (Just a)
-
- lookup_err_msg err = case err of
- BadImport ie -> badImportItemErr iface decl_spec ie all_avails
- IllegalImport -> illegalImportItemErr
- QualImportError rdr -> qualImportItemErr rdr
-
- -- For each import item, we convert its RdrNames to Names,
- -- and at the same time construct an AvailInfo corresponding
- -- to what is actually imported by this item.
- -- Returns Nothing on error.
- -- We return a list here, because in the case of an import
- -- item like C, if we are hiding, then C refers to *both* a
- -- type/class and a data constructor. Moreover, when we import
- -- data constructors of an associated family, we need separate
- -- AvailInfos for the data constructors and the family (as they have
- -- different parents). See Note [Dealing with imports]
- lookup_ie :: IE GhcPs
- -> IELookupM ([(IE GhcRn, AvailInfo)], [IELookupWarning])
- lookup_ie ie = handle_bad_import $ do
- case ie of
- IEVar _ (L l n) -> do
- (name, avail, _) <- lookup_name ie $ ieWrappedName n
- return ([(IEVar noExtField (L l (replaceWrappedName n name)),
- trimAvail avail name)], [])
-
- IEThingAll _ (L l tc) -> do
- (name, avail, mb_parent) <- lookup_name ie $ ieWrappedName tc
- let warns = case avail of
- Avail {} -- e.g. f(..)
- -> [DodgyImport $ ieWrappedName tc]
-
- AvailTC _ subs fs
- | null (drop 1 subs) && null fs -- e.g. T(..) where T is a synonym
- -> [DodgyImport $ ieWrappedName tc]
-
- | not (is_qual decl_spec) -- e.g. import M( T(..) )
- -> [MissingImportList]
-
- | otherwise
- -> []
-
- renamed_ie = IEThingAll noExtField (L l (replaceWrappedName tc name))
- sub_avails = case avail of
- Avail {} -> []
- AvailTC name2 subs fs -> [(renamed_ie, AvailTC name2 (subs \\ [name]) fs)]
- case mb_parent of
- Nothing -> return ([(renamed_ie, avail)], warns)
- -- non-associated ty/cls
- Just parent -> return ((renamed_ie, AvailTC parent [name] []) : sub_avails, warns)
- -- associated type
-
- IEThingAbs _ (L l tc')
- | want_hiding -- hiding ( C )
- -- Here the 'C' can be a data constructor
- -- *or* a type/class, or even both
- -> let tc = ieWrappedName tc'
- tc_name = lookup_name ie tc
- dc_name = lookup_name ie (setRdrNameSpace tc srcDataName)
- in
- case catIELookupM [ tc_name, dc_name ] of
- [] -> failLookupWith (BadImport ie)
- names -> return ([mkIEThingAbs tc' l name | name <- names], [])
- | otherwise
- -> do nameAvail <- lookup_name ie (ieWrappedName tc')
- return ([mkIEThingAbs tc' l nameAvail]
- , [])
-
- IEThingWith xt ltc@(L l rdr_tc) wc rdr_ns rdr_fs ->
- ASSERT2(null rdr_fs, ppr rdr_fs) do
- (name, avail, mb_parent)
- <- lookup_name (IEThingAbs noExtField ltc) (ieWrappedName rdr_tc)
-
- let (ns,subflds) = case avail of
- AvailTC _ ns' subflds' -> (ns',subflds')
- Avail _ -> panic "filterImports"
-
- -- Look up the children in the sub-names of the parent
- let subnames = case ns of -- The tc is first in ns,
- [] -> [] -- if it is there at all
- -- See the AvailTC Invariant in Avail.hs
- (n1:ns1) | n1 == name -> ns1
- | otherwise -> ns
- case lookupChildren (map Left subnames ++ map Right subflds) rdr_ns of
-
- Failed rdrs -> failLookupWith (BadImport (IEThingWith xt ltc wc rdrs []))
- -- We are trying to import T( a,b,c,d ), and failed
- -- to find 'b' and 'd'. So we make up an import item
- -- to report as failing, namely T( b, d ).
- -- c.f. #15412
-
- Succeeded (childnames, childflds) ->
- case mb_parent of
- -- non-associated ty/cls
- Nothing
- -> return ([(IEThingWith noExtField (L l name') wc childnames'
- childflds,
- AvailTC name (name:map unLoc childnames) (map unLoc childflds))],
- [])
- where name' = replaceWrappedName rdr_tc name
- childnames' = map to_ie_post_rn childnames
- -- childnames' = postrn_ies childnames
- -- associated ty
- Just parent
- -> return ([(IEThingWith noExtField (L l name') wc childnames'
- childflds,
- AvailTC name (map unLoc childnames) (map unLoc childflds)),
- (IEThingWith noExtField (L l name') wc childnames'
- childflds,
- AvailTC parent [name] [])],
- [])
- where name' = replaceWrappedName rdr_tc name
- childnames' = map to_ie_post_rn childnames
-
- _other -> failLookupWith IllegalImport
- -- could be IEModuleContents, IEGroup, IEDoc, IEDocNamed
- -- all errors.
-
- where
- mkIEThingAbs tc l (n, av, Nothing )
- = (IEThingAbs noExtField (L l (replaceWrappedName tc n)), trimAvail av n)
- mkIEThingAbs tc l (n, _, Just parent)
- = (IEThingAbs noExtField (L l (replaceWrappedName tc n))
- , AvailTC parent [n] [])
-
- handle_bad_import m = catchIELookup m $ \err -> case err of
- BadImport ie | want_hiding -> return ([], [BadImportW ie])
- _ -> failLookupWith err
-
-type IELookupM = MaybeErr IELookupError
-
-data IELookupWarning
- = BadImportW (IE GhcPs)
- | MissingImportList
- | DodgyImport RdrName
- -- NB. use the RdrName for reporting a "dodgy" import
-
-data IELookupError
- = QualImportError RdrName
- | BadImport (IE GhcPs)
- | IllegalImport
-
-failLookupWith :: IELookupError -> IELookupM a
-failLookupWith err = Failed err
-
-catchIELookup :: IELookupM a -> (IELookupError -> IELookupM a) -> IELookupM a
-catchIELookup m h = case m of
- Succeeded r -> return r
- Failed err -> h err
-
-catIELookupM :: [IELookupM a] -> [a]
-catIELookupM ms = [ a | Succeeded a <- ms ]
-
-{-
-************************************************************************
-* *
-\subsection{Import/Export Utils}
-* *
-************************************************************************
--}
-
--- | Given an import\/export spec, construct the appropriate 'GlobalRdrElt's.
-gresFromIE :: ImpDeclSpec -> (LIE GhcRn, AvailInfo) -> [GlobalRdrElt]
-gresFromIE decl_spec (L loc ie, avail)
- = gresFromAvail prov_fn avail
- where
- is_explicit = case ie of
- IEThingAll _ name -> \n -> n == lieWrappedName name
- _ -> \_ -> True
- prov_fn name
- = Just (ImpSpec { is_decl = decl_spec, is_item = item_spec })
- where
- item_spec = ImpSome { is_explicit = is_explicit name, is_iloc = loc }
-
-
-{-
-Note [Children for duplicate record fields]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider the module
-
- {-# LANGUAGE DuplicateRecordFields #-}
- module M (F(foo, MkFInt, MkFBool)) where
- data family F a
- data instance F Int = MkFInt { foo :: Int }
- data instance F Bool = MkFBool { foo :: Bool }
-
-The `foo` in the export list refers to *both* selectors! For this
-reason, lookupChildren builds an environment that maps the FastString
-to a list of items, rather than a single item.
--}
-
-mkChildEnv :: [GlobalRdrElt] -> NameEnv [GlobalRdrElt]
-mkChildEnv gres = foldr add emptyNameEnv gres
- where
- add gre env = case gre_par gre of
- FldParent p _ -> extendNameEnv_Acc (:) singleton env p gre
- ParentIs p -> extendNameEnv_Acc (:) singleton env p gre
- NoParent -> env
-
-findChildren :: NameEnv [a] -> Name -> [a]
-findChildren env n = lookupNameEnv env n `orElse` []
-
-lookupChildren :: [Either Name FieldLabel] -> [LIEWrappedName RdrName]
- -> MaybeErr [LIEWrappedName RdrName] -- The ones for which the lookup failed
- ([Located Name], [Located FieldLabel])
--- (lookupChildren all_kids rdr_items) maps each rdr_item to its
--- corresponding Name all_kids, if the former exists
--- The matching is done by FastString, not OccName, so that
--- Cls( meth, AssocTy )
--- will correctly find AssocTy among the all_kids of Cls, even though
--- the RdrName for AssocTy may have a (bogus) DataName namespace
--- (Really the rdr_items should be FastStrings in the first place.)
-lookupChildren all_kids rdr_items
- | null fails
- = Succeeded (fmap concat (partitionEithers oks))
- -- This 'fmap concat' trickily applies concat to the /second/ component
- -- of the pair, whose type is ([Located Name], [[Located FieldLabel]])
- | otherwise
- = Failed fails
- where
- mb_xs = map doOne rdr_items
- fails = [ bad_rdr | Failed bad_rdr <- mb_xs ]
- oks = [ ok | Succeeded ok <- mb_xs ]
- oks :: [Either (Located Name) [Located FieldLabel]]
-
- doOne item@(L l r)
- = case (lookupFsEnv kid_env . occNameFS . rdrNameOcc . ieWrappedName) r of
- Just [Left n] -> Succeeded (Left (L l n))
- Just rs | all isRight rs -> Succeeded (Right (map (L l) (rights rs)))
- _ -> Failed item
-
- -- See Note [Children for duplicate record fields]
- kid_env = extendFsEnvList_C (++) emptyFsEnv
- [(either (occNameFS . nameOccName) flLabel x, [x]) | x <- all_kids]
-
-
-
--------------------------------
-
-{-
-*********************************************************
-* *
-\subsection{Unused names}
-* *
-*********************************************************
--}
-
-reportUnusedNames :: TcGblEnv -> RnM ()
-reportUnusedNames gbl_env
- = do { keep <- readTcRef (tcg_keep gbl_env)
- ; traceRn "RUN" (ppr (tcg_dus gbl_env))
- ; warnUnusedImportDecls gbl_env
- ; warnUnusedTopBinds $ unused_locals keep
- ; warnMissingSignatures gbl_env }
- where
- used_names :: NameSet -> NameSet
- used_names keep = findUses (tcg_dus gbl_env) emptyNameSet `unionNameSet` keep
- -- NB: currently, if f x = g, we only treat 'g' as used if 'f' is used
- -- Hence findUses
-
- -- Collect the defined names from the in-scope environment
- defined_names :: [GlobalRdrElt]
- defined_names = globalRdrEnvElts (tcg_rdr_env gbl_env)
-
- kids_env = mkChildEnv defined_names
- -- This is done in mkExports too; duplicated work
-
- gre_is_used :: NameSet -> GlobalRdrElt -> Bool
- gre_is_used used_names (GRE {gre_name = name})
- = name `elemNameSet` used_names
- || any (\ gre -> gre_name gre `elemNameSet` used_names) (findChildren kids_env name)
- -- A use of C implies a use of T,
- -- if C was brought into scope by T(..) or T(C)
-
- -- Filter out the ones that are
- -- (a) defined in this module, and
- -- (b) not defined by a 'deriving' clause
- -- The latter have an Internal Name, so we can filter them out easily
- unused_locals :: NameSet -> [GlobalRdrElt]
- unused_locals keep =
- let -- Note that defined_and_used, defined_but_not_used
- -- are both [GRE]; that's why we need defined_and_used
- -- rather than just used_names
- _defined_and_used, defined_but_not_used :: [GlobalRdrElt]
- (_defined_and_used, defined_but_not_used)
- = partition (gre_is_used (used_names keep)) defined_names
-
- in filter is_unused_local defined_but_not_used
- is_unused_local :: GlobalRdrElt -> Bool
- is_unused_local gre = isLocalGRE gre && isExternalName (gre_name gre)
-
-{- *********************************************************************
-* *
- Missing signatures
-* *
-********************************************************************* -}
-
--- | Warn the user about top level binders that lack type signatures.
--- Called /after/ type inference, so that we can report the
--- inferred type of the function
-warnMissingSignatures :: TcGblEnv -> RnM ()
-warnMissingSignatures gbl_env
- = do { let exports = availsToNameSet (tcg_exports gbl_env)
- sig_ns = tcg_sigs gbl_env
- -- We use sig_ns to exclude top-level bindings that are generated by GHC
- binds = collectHsBindsBinders $ tcg_binds gbl_env
- pat_syns = tcg_patsyns gbl_env
-
- -- Warn about missing signatures
- -- Do this only when we have a type to offer
- ; warn_missing_sigs <- woptM Opt_WarnMissingSignatures
- ; warn_only_exported <- woptM Opt_WarnMissingExportedSignatures
- ; warn_pat_syns <- woptM Opt_WarnMissingPatternSynonymSignatures
-
- ; let add_sig_warns
- | warn_only_exported = add_warns Opt_WarnMissingExportedSignatures
- | warn_missing_sigs = add_warns Opt_WarnMissingSignatures
- | warn_pat_syns = add_warns Opt_WarnMissingPatternSynonymSignatures
- | otherwise = return ()
-
- add_warns flag
- = when warn_pat_syns
- (mapM_ add_pat_syn_warn pat_syns) >>
- when (warn_missing_sigs || warn_only_exported)
- (mapM_ add_bind_warn binds)
- where
- add_pat_syn_warn p
- = add_warn name $
- hang (text "Pattern synonym with no type signature:")
- 2 (text "pattern" <+> pprPrefixName name <+> dcolon <+> pp_ty)
- where
- name = patSynName p
- pp_ty = pprPatSynType p
-
- add_bind_warn :: Id -> IOEnv (Env TcGblEnv TcLclEnv) ()
- add_bind_warn id
- = do { env <- tcInitTidyEnv -- Why not use emptyTidyEnv?
- ; let name = idName id
- (_, ty) = tidyOpenType env (idType id)
- ty_msg = pprSigmaType ty
- ; add_warn name $
- hang (text "Top-level binding with no type signature:")
- 2 (pprPrefixName name <+> dcolon <+> ty_msg) }
-
- add_warn name msg
- = when (name `elemNameSet` sig_ns && export_check name)
- (addWarnAt (Reason flag) (getSrcSpan name) msg)
-
- export_check name
- = not warn_only_exported || name `elemNameSet` exports
-
- ; add_sig_warns }
-
-
-{-
-*********************************************************
-* *
-\subsection{Unused imports}
-* *
-*********************************************************
-
-This code finds which import declarations are unused. The
-specification and implementation notes are here:
- https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/unused-imports
-
-See also Note [Choosing the best import declaration] in RdrName
--}
-
-type ImportDeclUsage
- = ( LImportDecl GhcRn -- The import declaration
- , [GlobalRdrElt] -- What *is* used (normalised)
- , [Name] ) -- What is imported but *not* used
-
-warnUnusedImportDecls :: TcGblEnv -> RnM ()
-warnUnusedImportDecls gbl_env
- = do { uses <- readMutVar (tcg_used_gres gbl_env)
- ; let user_imports = filterOut
- (ideclImplicit . unLoc)
- (tcg_rn_imports gbl_env)
- -- This whole function deals only with *user* imports
- -- both for warning about unnecessary ones, and for
- -- deciding the minimal ones
- rdr_env = tcg_rdr_env gbl_env
- fld_env = mkFieldEnv rdr_env
-
- ; let usage :: [ImportDeclUsage]
- usage = findImportUsage user_imports uses
-
- ; traceRn "warnUnusedImportDecls" $
- (vcat [ text "Uses:" <+> ppr uses
- , text "Import usage" <+> ppr usage])
-
- ; whenWOptM Opt_WarnUnusedImports $
- mapM_ (warnUnusedImport Opt_WarnUnusedImports fld_env) usage
-
- ; whenGOptM Opt_D_dump_minimal_imports $
- printMinimalImports usage }
-
-findImportUsage :: [LImportDecl GhcRn]
- -> [GlobalRdrElt]
- -> [ImportDeclUsage]
-
-findImportUsage imports used_gres
- = map unused_decl imports
- where
- import_usage :: ImportMap
- import_usage = mkImportMap used_gres
-
- unused_decl decl@(L loc (ImportDecl { ideclHiding = imps }))
- = (decl, used_gres, nameSetElemsStable unused_imps)
- where
- used_gres = Map.lookup (srcSpanEnd loc) import_usage
- -- srcSpanEnd: see Note [The ImportMap]
- `orElse` []
-
- used_names = mkNameSet (map gre_name used_gres)
- used_parents = mkNameSet (mapMaybe greParent_maybe used_gres)
-
- unused_imps -- Not trivial; see eg #7454
- = case imps of
- Just (False, L _ imp_ies) ->
- foldr (add_unused . unLoc) emptyNameSet imp_ies
- _other -> emptyNameSet -- No explicit import list => no unused-name list
-
- add_unused :: IE GhcRn -> NameSet -> NameSet
- add_unused (IEVar _ n) acc = add_unused_name (lieWrappedName n) acc
- add_unused (IEThingAbs _ n) acc = add_unused_name (lieWrappedName n) acc
- add_unused (IEThingAll _ n) acc = add_unused_all (lieWrappedName n) acc
- add_unused (IEThingWith _ p wc ns fs) acc =
- add_wc_all (add_unused_with pn xs acc)
- where pn = lieWrappedName p
- xs = map lieWrappedName ns ++ map (flSelector . unLoc) fs
- add_wc_all = case wc of
- NoIEWildcard -> id
- IEWildcard _ -> add_unused_all pn
- add_unused _ acc = acc
-
- add_unused_name n acc
- | n `elemNameSet` used_names = acc
- | otherwise = acc `extendNameSet` n
- add_unused_all n acc
- | n `elemNameSet` used_names = acc
- | n `elemNameSet` used_parents = acc
- | otherwise = acc `extendNameSet` n
- add_unused_with p ns acc
- | all (`elemNameSet` acc1) ns = add_unused_name p acc1
- | otherwise = acc1
- where
- acc1 = foldr add_unused_name acc ns
- -- If you use 'signum' from Num, then the user may well have
- -- imported Num(signum). We don't want to complain that
- -- Num is not itself mentioned. Hence the two cases in add_unused_with.
- unused_decl (L _ (XImportDecl nec)) = noExtCon nec
-
-
-{- Note [The ImportMap]
-~~~~~~~~~~~~~~~~~~~~~~~
-The ImportMap is a short-lived intermediate data structure records, for
-each import declaration, what stuff brought into scope by that
-declaration is actually used in the module.
-
-The SrcLoc is the location of the END of a particular 'import'
-declaration. Why *END*? Because we don't want to get confused
-by the implicit Prelude import. Consider (#7476) the module
- import Foo( foo )
- main = print foo
-There is an implicit 'import Prelude(print)', and it gets a SrcSpan
-of line 1:1 (just the point, not a span). If we use the *START* of
-the SrcSpan to identify the import decl, we'll confuse the implicit
-import Prelude with the explicit 'import Foo'. So we use the END.
-It's just a cheap hack; we could equally well use the Span too.
-
-The [GlobalRdrElt] are the things imported from that decl.
--}
-
-type ImportMap = Map SrcLoc [GlobalRdrElt] -- See [The ImportMap]
- -- If loc :-> gres, then
- -- 'loc' = the end loc of the bestImport of each GRE in 'gres'
-
-mkImportMap :: [GlobalRdrElt] -> ImportMap
--- For each of a list of used GREs, find all the import decls that brought
--- it into scope; choose one of them (bestImport), and record
--- the RdrName in that import decl's entry in the ImportMap
-mkImportMap gres
- = foldr add_one Map.empty gres
- where
- add_one gre@(GRE { gre_imp = imp_specs }) imp_map
- = Map.insertWith add decl_loc [gre] imp_map
- where
- best_imp_spec = bestImport imp_specs
- decl_loc = srcSpanEnd (is_dloc (is_decl best_imp_spec))
- -- For srcSpanEnd see Note [The ImportMap]
- add _ gres = gre : gres
-
-warnUnusedImport :: WarningFlag -> NameEnv (FieldLabelString, Name)
- -> ImportDeclUsage -> RnM ()
-warnUnusedImport flag fld_env (L loc decl, used, unused)
-
- -- Do not warn for 'import M()'
- | Just (False,L _ []) <- ideclHiding decl
- = return ()
-
- -- Note [Do not warn about Prelude hiding]
- | Just (True, L _ hides) <- ideclHiding decl
- , not (null hides)
- , pRELUDE_NAME == unLoc (ideclName decl)
- = return ()
-
- -- Nothing used; drop entire declaration
- | null used
- = addWarnAt (Reason flag) loc msg1
-
- -- Everything imported is used; nop
- | null unused
- = return ()
-
- -- Some imports are unused
- | otherwise
- = addWarnAt (Reason flag) loc msg2
-
- where
- msg1 = vcat [ pp_herald <+> quotes pp_mod <+> is_redundant
- , nest 2 (text "except perhaps to import instances from"
- <+> quotes pp_mod)
- , text "To import instances alone, use:"
- <+> text "import" <+> pp_mod <> parens Outputable.empty ]
- msg2 = sep [ pp_herald <+> quotes sort_unused
- , text "from module" <+> quotes pp_mod <+> is_redundant]
- pp_herald = text "The" <+> pp_qual <+> text "import of"
- pp_qual
- | isImportDeclQualified (ideclQualified decl)= text "qualified"
- | otherwise = Outputable.empty
- pp_mod = ppr (unLoc (ideclName decl))
- is_redundant = text "is redundant"
-
- -- In warning message, pretty-print identifiers unqualified unconditionally
- -- to improve the consistent for ambiguous/unambiguous identifiers.
- -- See trac#14881.
- ppr_possible_field n = case lookupNameEnv fld_env n of
- Just (fld, p) -> pprNameUnqualified p <> parens (ppr fld)
- Nothing -> pprNameUnqualified n
-
- -- Print unused names in a deterministic (lexicographic) order
- sort_unused :: SDoc
- sort_unused = pprWithCommas ppr_possible_field $
- sortBy (comparing nameOccName) unused
-
-{-
-Note [Do not warn about Prelude hiding]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We do not warn about
- import Prelude hiding( x, y )
-because even if nothing else from Prelude is used, it may be essential to hide
-x,y to avoid name-shadowing warnings. Example (#9061)
- import Prelude hiding( log )
- f x = log where log = ()
-
-
-
-Note [Printing minimal imports]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-To print the minimal imports we walk over the user-supplied import
-decls, and simply trim their import lists. NB that
-
- * We do *not* change the 'qualified' or 'as' parts!
-
- * We do not disard a decl altogether; we might need instances
- from it. Instead we just trim to an empty import list
--}
-
-getMinimalImports :: [ImportDeclUsage] -> RnM [LImportDecl GhcRn]
-getMinimalImports = mapM mk_minimal
- where
- mk_minimal (L l decl, used_gres, unused)
- | null unused
- , Just (False, _) <- ideclHiding decl
- = return (L l decl)
- | otherwise
- = do { let ImportDecl { ideclName = L _ mod_name
- , ideclSource = is_boot
- , ideclPkgQual = mb_pkg } = decl
- ; iface <- loadSrcInterface doc mod_name is_boot (fmap sl_fs mb_pkg)
- ; let used_avails = gresToAvailInfo used_gres
- lies = map (L l) (concatMap (to_ie iface) used_avails)
- ; return (L l (decl { ideclHiding = Just (False, L l lies) })) }
- where
- doc = text "Compute minimal imports for" <+> ppr decl
-
- to_ie :: ModIface -> AvailInfo -> [IE GhcRn]
- -- The main trick here is that if we're importing all the constructors
- -- we want to say "T(..)", but if we're importing only a subset we want
- -- to say "T(A,B,C)". So we have to find out what the module exports.
- to_ie _ (Avail n)
- = [IEVar noExtField (to_ie_post_rn $ noLoc n)]
- to_ie _ (AvailTC n [m] [])
- | n==m = [IEThingAbs noExtField (to_ie_post_rn $ noLoc n)]
- to_ie iface (AvailTC n ns fs)
- = case [(xs,gs) | AvailTC x xs gs <- mi_exports iface
- , x == n
- , x `elem` xs -- Note [Partial export]
- ] of
- [xs] | all_used xs -> [IEThingAll noExtField (to_ie_post_rn $ noLoc n)]
- | otherwise ->
- [IEThingWith noExtField (to_ie_post_rn $ noLoc n) NoIEWildcard
- (map (to_ie_post_rn . noLoc) (filter (/= n) ns))
- (map noLoc fs)]
- -- Note [Overloaded field import]
- _other | all_non_overloaded fs
- -> map (IEVar noExtField . to_ie_post_rn_var . noLoc) $ ns
- ++ map flSelector fs
- | otherwise ->
- [IEThingWith noExtField (to_ie_post_rn $ noLoc n) NoIEWildcard
- (map (to_ie_post_rn . noLoc) (filter (/= n) ns))
- (map noLoc fs)]
- where
-
- fld_lbls = map flLabel fs
-
- all_used (avail_occs, avail_flds)
- = all (`elem` ns) avail_occs
- && all (`elem` fld_lbls) (map flLabel avail_flds)
-
- all_non_overloaded = all (not . flIsOverloaded)
-
-printMinimalImports :: [ImportDeclUsage] -> RnM ()
--- See Note [Printing minimal imports]
-printMinimalImports imports_w_usage
- = do { imports' <- getMinimalImports imports_w_usage
- ; this_mod <- getModule
- ; dflags <- getDynFlags
- ; liftIO $
- do { h <- openFile (mkFilename dflags this_mod) WriteMode
- ; printForUser dflags h neverQualify (vcat (map ppr imports')) }
- -- The neverQualify is important. We are printing Names
- -- but they are in the context of an 'import' decl, and
- -- we never qualify things inside there
- -- E.g. import Blag( f, b )
- -- not import Blag( Blag.f, Blag.g )!
- }
- where
- mkFilename dflags this_mod
- | Just d <- dumpDir dflags = d </> basefn
- | otherwise = basefn
- where
- basefn = moduleNameString (moduleName this_mod) ++ ".imports"
-
-
-to_ie_post_rn_var :: (HasOccName name) => Located name -> LIEWrappedName name
-to_ie_post_rn_var (L l n)
- | isDataOcc $ occName n = L l (IEPattern (L l n))
- | otherwise = L l (IEName (L l n))
-
-
-to_ie_post_rn :: (HasOccName name) => Located name -> LIEWrappedName name
-to_ie_post_rn (L l n)
- | isTcOcc occ && isSymOcc occ = L l (IEType (L l n))
- | otherwise = L l (IEName (L l n))
- where occ = occName n
-
-{-
-Note [Partial export]
-~~~~~~~~~~~~~~~~~~~~~
-Suppose we have
-
- module A( op ) where
- class C a where
- op :: a -> a
-
- module B where
- import A
- f = ..op...
-
-Then the minimal import for module B is
- import A( op )
-not
- import A( C( op ) )
-which we would usually generate if C was exported from B. Hence
-the (x `elem` xs) test when deciding what to generate.
-
-
-Note [Overloaded field import]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-On the other hand, if we have
-
- {-# LANGUAGE DuplicateRecordFields #-}
- module A where
- data T = MkT { foo :: Int }
-
- module B where
- import A
- f = ...foo...
-
-then the minimal import for module B must be
- import A ( T(foo) )
-because when DuplicateRecordFields is enabled, field selectors are
-not in scope without their enclosing datatype.
-
-
-************************************************************************
-* *
-\subsection{Errors}
-* *
-************************************************************************
--}
-
-qualImportItemErr :: RdrName -> SDoc
-qualImportItemErr rdr
- = hang (text "Illegal qualified name in import item:")
- 2 (ppr rdr)
-
-badImportItemErrStd :: ModIface -> ImpDeclSpec -> IE GhcPs -> SDoc
-badImportItemErrStd iface decl_spec ie
- = sep [text "Module", quotes (ppr (is_mod decl_spec)), source_import,
- text "does not export", quotes (ppr ie)]
- where
- source_import | mi_boot iface = text "(hi-boot interface)"
- | otherwise = Outputable.empty
-
-badImportItemErrDataCon :: OccName -> ModIface -> ImpDeclSpec -> IE GhcPs
- -> SDoc
-badImportItemErrDataCon dataType_occ iface decl_spec ie
- = vcat [ text "In module"
- <+> quotes (ppr (is_mod decl_spec))
- <+> source_import <> colon
- , nest 2 $ quotes datacon
- <+> text "is a data constructor of"
- <+> quotes dataType
- , text "To import it use"
- , nest 2 $ text "import"
- <+> ppr (is_mod decl_spec)
- <> parens_sp (dataType <> parens_sp datacon)
- , text "or"
- , nest 2 $ text "import"
- <+> ppr (is_mod decl_spec)
- <> parens_sp (dataType <> text "(..)")
- ]
- where
- datacon_occ = rdrNameOcc $ ieName ie
- datacon = parenSymOcc datacon_occ (ppr datacon_occ)
- dataType = parenSymOcc dataType_occ (ppr dataType_occ)
- source_import | mi_boot iface = text "(hi-boot interface)"
- | otherwise = Outputable.empty
- parens_sp d = parens (space <> d <> space) -- T( f,g )
-
-badImportItemErr :: ModIface -> ImpDeclSpec -> IE GhcPs -> [AvailInfo] -> SDoc
-badImportItemErr iface decl_spec ie avails
- = case find checkIfDataCon avails of
- Just con -> badImportItemErrDataCon (availOccName con) iface decl_spec ie
- Nothing -> badImportItemErrStd iface decl_spec ie
- where
- checkIfDataCon (AvailTC _ ns _) =
- case find (\n -> importedFS == nameOccNameFS n) ns of
- Just n -> isDataConName n
- Nothing -> False
- checkIfDataCon _ = False
- availOccName = nameOccName . availName
- nameOccNameFS = occNameFS . nameOccName
- importedFS = occNameFS . rdrNameOcc $ ieName ie
-
-illegalImportItemErr :: SDoc
-illegalImportItemErr = text "Illegal import item"
-
-dodgyImportWarn :: RdrName -> SDoc
-dodgyImportWarn item
- = dodgyMsg (text "import") item (dodgyMsgInsert item :: IE GhcPs)
-
-dodgyMsg :: (Outputable a, Outputable b) => SDoc -> a -> b -> SDoc
-dodgyMsg kind tc ie
- = sep [ text "The" <+> kind <+> ptext (sLit "item")
- -- <+> quotes (ppr (IEThingAll (noLoc (IEName $ noLoc tc))))
- <+> quotes (ppr ie)
- <+> text "suggests that",
- quotes (ppr tc) <+> text "has (in-scope) constructors or class methods,",
- text "but it has none" ]
-
-dodgyMsgInsert :: forall p . IdP (GhcPass p) -> IE (GhcPass p)
-dodgyMsgInsert tc = IEThingAll noExtField ii
- where
- ii :: LIEWrappedName (IdP (GhcPass p))
- ii = noLoc (IEName $ noLoc tc)
-
-
-addDupDeclErr :: [GlobalRdrElt] -> TcRn ()
-addDupDeclErr [] = panic "addDupDeclErr: empty list"
-addDupDeclErr gres@(gre : _)
- = addErrAt (getSrcSpan (last sorted_names)) $
- -- Report the error at the later location
- vcat [text "Multiple declarations of" <+>
- quotes (ppr (nameOccName name)),
- -- NB. print the OccName, not the Name, because the
- -- latter might not be in scope in the RdrEnv and so will
- -- be printed qualified.
- text "Declared at:" <+>
- vcat (map (ppr . nameSrcLoc) sorted_names)]
- where
- name = gre_name gre
- sorted_names = sortWith nameSrcLoc (map gre_name gres)
-
-
-
-missingImportListWarn :: ModuleName -> SDoc
-missingImportListWarn mod
- = text "The module" <+> quotes (ppr mod) <+> ptext (sLit "does not have an explicit import list")
-
-missingImportListItem :: IE GhcPs -> SDoc
-missingImportListItem ie
- = text "The import item" <+> quotes (ppr ie) <+> ptext (sLit "does not have an explicit import list")
-
-moduleWarn :: ModuleName -> WarningTxt -> SDoc
-moduleWarn mod (WarningTxt _ txt)
- = sep [ text "Module" <+> quotes (ppr mod) <> ptext (sLit ":"),
- nest 2 (vcat (map (ppr . sl_fs . unLoc) txt)) ]
-moduleWarn mod (DeprecatedTxt _ txt)
- = sep [ text "Module" <+> quotes (ppr mod)
- <+> text "is deprecated:",
- nest 2 (vcat (map (ppr . sl_fs . unLoc) txt)) ]
-
-packageImportErr :: SDoc
-packageImportErr
- = text "Package-qualified imports are not enabled; use PackageImports"
-
--- This data decl will parse OK
--- data T = a Int
--- treating "a" as the constructor.
--- It is really hard to make the parser spot this malformation.
--- So the renamer has to check that the constructor is legal
---
--- We can get an operator as the constructor, even in the prefix form:
--- data T = :% Int Int
--- from interface files, which always print in prefix form
-
-checkConName :: RdrName -> TcRn ()
-checkConName name = checkErr (isRdrDataCon name) (badDataCon name)
-
-badDataCon :: RdrName -> SDoc
-badDataCon name
- = hsep [text "Illegal data constructor name", quotes (ppr name)]
diff --git a/compiler/rename/RnPat.hs b/compiler/rename/RnPat.hs
deleted file mode 100644
index 59ab5446cd..0000000000
--- a/compiler/rename/RnPat.hs
+++ /dev/null
@@ -1,897 +0,0 @@
-{-
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-\section[RnPat]{Renaming of patterns}
-
-Basically dependency analysis.
-
-Handles @Match@, @GRHSs@, @HsExpr@, and @Qualifier@ datatypes. In
-general, all of these functions return a renamed thing, and a set of
-free variables.
--}
-
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE ViewPatterns #-}
-{-# LANGUAGE DeriveFunctor #-}
-
-module RnPat (-- main entry points
- rnPat, rnPats, rnBindPat, rnPatAndThen,
-
- NameMaker, applyNameMaker, -- a utility for making names:
- localRecNameMaker, topRecNameMaker, -- sometimes we want to make local names,
- -- sometimes we want to make top (qualified) names.
- isTopRecNameMaker,
-
- rnHsRecFields, HsRecFieldContext(..),
- rnHsRecUpdFields,
-
- -- CpsRn monad
- CpsRn, liftCps,
-
- -- Literals
- rnLit, rnOverLit,
-
- -- Pattern Error messages that are also used elsewhere
- checkTupSize, patSigErr
- ) where
-
--- ENH: thin imports to only what is necessary for patterns
-
-import GhcPrelude
-
-import {-# SOURCE #-} RnExpr ( rnLExpr )
-import {-# SOURCE #-} RnSplice ( rnSplicePat )
-
-#include "HsVersions.h"
-
-import GHC.Hs
-import TcRnMonad
-import TcHsSyn ( hsOverLitName )
-import RnEnv
-import RnFixity
-import RnUtils ( HsDocContext(..), newLocalBndrRn, bindLocalNames
- , warnUnusedMatches, newLocalBndrRn
- , checkUnusedRecordWildcard
- , checkDupNames, checkDupAndShadowedNames
- , checkTupSize , unknownSubordinateErr )
-import RnTypes
-import PrelNames
-import Name
-import NameSet
-import RdrName
-import BasicTypes
-import Util
-import ListSetOps ( removeDups )
-import Outputable
-import SrcLoc
-import Literal ( inCharRange )
-import TysWiredIn ( nilDataCon )
-import DataCon
-import qualified GHC.LanguageExtensions as LangExt
-
-import Control.Monad ( when, ap, guard )
-import qualified Data.List.NonEmpty as NE
-import Data.Ratio
-
-{-
-*********************************************************
-* *
- The CpsRn Monad
-* *
-*********************************************************
-
-Note [CpsRn monad]
-~~~~~~~~~~~~~~~~~~
-The CpsRn monad uses continuation-passing style to support this
-style of programming:
-
- do { ...
- ; ns <- bindNames rs
- ; ...blah... }
-
- where rs::[RdrName], ns::[Name]
-
-The idea is that '...blah...'
- a) sees the bindings of ns
- b) returns the free variables it mentions
- so that bindNames can report unused ones
-
-In particular,
- mapM rnPatAndThen [p1, p2, p3]
-has a *left-to-right* scoping: it makes the binders in
-p1 scope over p2,p3.
--}
-
-newtype CpsRn b = CpsRn { unCpsRn :: forall r. (b -> RnM (r, FreeVars))
- -> RnM (r, FreeVars) }
- deriving (Functor)
- -- See Note [CpsRn monad]
-
-instance Applicative CpsRn where
- pure x = CpsRn (\k -> k x)
- (<*>) = ap
-
-instance Monad CpsRn where
- (CpsRn m) >>= mk = CpsRn (\k -> m (\v -> unCpsRn (mk v) k))
-
-runCps :: CpsRn a -> RnM (a, FreeVars)
-runCps (CpsRn m) = m (\r -> return (r, emptyFVs))
-
-liftCps :: RnM a -> CpsRn a
-liftCps rn_thing = CpsRn (\k -> rn_thing >>= k)
-
-liftCpsFV :: RnM (a, FreeVars) -> CpsRn a
-liftCpsFV rn_thing = CpsRn (\k -> do { (v,fvs1) <- rn_thing
- ; (r,fvs2) <- k v
- ; return (r, fvs1 `plusFV` fvs2) })
-
-wrapSrcSpanCps :: (a -> CpsRn b) -> Located a -> CpsRn (Located b)
--- Set the location, and also wrap it around the value returned
-wrapSrcSpanCps fn (L loc a)
- = CpsRn (\k -> setSrcSpan loc $
- unCpsRn (fn a) $ \v ->
- k (L loc v))
-
-lookupConCps :: Located RdrName -> CpsRn (Located Name)
-lookupConCps con_rdr
- = CpsRn (\k -> do { con_name <- lookupLocatedOccRn con_rdr
- ; (r, fvs) <- k con_name
- ; return (r, addOneFV fvs (unLoc con_name)) })
- -- We add the constructor name to the free vars
- -- See Note [Patterns are uses]
-
-{-
-Note [Patterns are uses]
-~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
- module Foo( f, g ) where
- data T = T1 | T2
-
- f T1 = True
- f T2 = False
-
- g _ = T1
-
-Arguably we should report T2 as unused, even though it appears in a
-pattern, because it never occurs in a constructed position. See
-#7336.
-However, implementing this in the face of pattern synonyms would be
-less straightforward, since given two pattern synonyms
-
- pattern P1 <- P2
- pattern P2 <- ()
-
-we need to observe the dependency between P1 and P2 so that type
-checking can be done in the correct order (just like for value
-bindings). Dependencies between bindings is analyzed in the renamer,
-where we don't know yet whether P2 is a constructor or a pattern
-synonym. So for now, we do report conid occurrences in patterns as
-uses.
-
-*********************************************************
-* *
- Name makers
-* *
-*********************************************************
-
-Externally abstract type of name makers,
-which is how you go from a RdrName to a Name
--}
-
-data NameMaker
- = LamMk -- Lambdas
- Bool -- True <=> report unused bindings
- -- (even if True, the warning only comes out
- -- if -Wunused-matches is on)
-
- | LetMk -- Let bindings, incl top level
- -- Do *not* check for unused bindings
- TopLevelFlag
- MiniFixityEnv
-
-topRecNameMaker :: MiniFixityEnv -> NameMaker
-topRecNameMaker fix_env = LetMk TopLevel fix_env
-
-isTopRecNameMaker :: NameMaker -> Bool
-isTopRecNameMaker (LetMk TopLevel _) = True
-isTopRecNameMaker _ = False
-
-localRecNameMaker :: MiniFixityEnv -> NameMaker
-localRecNameMaker fix_env = LetMk NotTopLevel fix_env
-
-matchNameMaker :: HsMatchContext a -> NameMaker
-matchNameMaker ctxt = LamMk report_unused
- where
- -- Do not report unused names in interactive contexts
- -- i.e. when you type 'x <- e' at the GHCi prompt
- report_unused = case ctxt of
- StmtCtxt GhciStmtCtxt -> False
- -- also, don't warn in pattern quotes, as there
- -- is no RHS where the variables can be used!
- ThPatQuote -> False
- _ -> True
-
-rnHsSigCps :: LHsSigWcType GhcPs -> CpsRn (LHsSigWcType GhcRn)
-rnHsSigCps sig = CpsRn (rnHsSigWcTypeScoped AlwaysBind PatCtx sig)
-
-newPatLName :: NameMaker -> Located RdrName -> CpsRn (Located Name)
-newPatLName name_maker rdr_name@(L loc _)
- = do { name <- newPatName name_maker rdr_name
- ; return (L loc name) }
-
-newPatName :: NameMaker -> Located RdrName -> CpsRn Name
-newPatName (LamMk report_unused) rdr_name
- = CpsRn (\ thing_inside ->
- do { name <- newLocalBndrRn rdr_name
- ; (res, fvs) <- bindLocalNames [name] (thing_inside name)
- ; when report_unused $ warnUnusedMatches [name] fvs
- ; return (res, name `delFV` fvs) })
-
-newPatName (LetMk is_top fix_env) rdr_name
- = CpsRn (\ thing_inside ->
- do { name <- case is_top of
- NotTopLevel -> newLocalBndrRn rdr_name
- TopLevel -> newTopSrcBinder rdr_name
- ; bindLocalNames [name] $ -- Do *not* use bindLocalNameFV here
- -- See Note [View pattern usage]
- addLocalFixities fix_env [name] $
- thing_inside name })
-
- -- Note: the bindLocalNames is somewhat suspicious
- -- because it binds a top-level name as a local name.
- -- however, this binding seems to work, and it only exists for
- -- the duration of the patterns and the continuation;
- -- then the top-level name is added to the global env
- -- before going on to the RHSes (see RnSource.hs).
-
-{-
-Note [View pattern usage]
-~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
- let (r, (r -> x)) = x in ...
-Here the pattern binds 'r', and then uses it *only* in the view pattern.
-We want to "see" this use, and in let-bindings we collect all uses and
-report unused variables at the binding level. So we must use bindLocalNames
-here, *not* bindLocalNameFV. #3943.
-
-
-Note [Don't report shadowing for pattern synonyms]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-There is one special context where a pattern doesn't introduce any new binders -
-pattern synonym declarations. Therefore we don't check to see if pattern
-variables shadow existing identifiers as they are never bound to anything
-and have no scope.
-
-Without this check, there would be quite a cryptic warning that the `x`
-in the RHS of the pattern synonym declaration shadowed the top level `x`.
-
-```
-x :: ()
-x = ()
-
-pattern P x = Just x
-```
-
-See #12615 for some more examples.
-
-*********************************************************
-* *
- External entry points
-* *
-*********************************************************
-
-There are various entry points to renaming patterns, depending on
- (1) whether the names created should be top-level names or local names
- (2) whether the scope of the names is entirely given in a continuation
- (e.g., in a case or lambda, but not in a let or at the top-level,
- because of the way mutually recursive bindings are handled)
- (3) whether the a type signature in the pattern can bind
- lexically-scoped type variables (for unpacking existential
- type vars in data constructors)
- (4) whether we do duplicate and unused variable checking
- (5) whether there are fixity declarations associated with the names
- bound by the patterns that need to be brought into scope with them.
-
- Rather than burdening the clients of this module with all of these choices,
- we export the three points in this design space that we actually need:
--}
-
--- ----------- Entry point 1: rnPats -------------------
--- Binds local names; the scope of the bindings is entirely in the thing_inside
--- * allows type sigs to bind type vars
--- * local namemaker
--- * unused and duplicate checking
--- * no fixities
-rnPats :: HsMatchContext Name -- for error messages
- -> [LPat GhcPs]
- -> ([LPat GhcRn] -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
-rnPats ctxt pats thing_inside
- = do { envs_before <- getRdrEnvs
-
- -- (1) rename the patterns, bringing into scope all of the term variables
- -- (2) then do the thing inside.
- ; unCpsRn (rnLPatsAndThen (matchNameMaker ctxt) pats) $ \ pats' -> do
- { -- Check for duplicated and shadowed names
- -- Must do this *after* renaming the patterns
- -- See Note [Collect binders only after renaming] in GHC.Hs.Utils
- -- Because we don't bind the vars all at once, we can't
- -- check incrementally for duplicates;
- -- Nor can we check incrementally for shadowing, else we'll
- -- complain *twice* about duplicates e.g. f (x,x) = ...
- --
- -- See note [Don't report shadowing for pattern synonyms]
- ; let bndrs = collectPatsBinders pats'
- ; addErrCtxt doc_pat $
- if isPatSynCtxt ctxt
- then checkDupNames bndrs
- else checkDupAndShadowedNames envs_before bndrs
- ; thing_inside pats' } }
- where
- doc_pat = text "In" <+> pprMatchContext ctxt
-
-rnPat :: HsMatchContext Name -- for error messages
- -> LPat GhcPs
- -> (LPat GhcRn -> RnM (a, FreeVars))
- -> RnM (a, FreeVars) -- Variables bound by pattern do not
- -- appear in the result FreeVars
-rnPat ctxt pat thing_inside
- = rnPats ctxt [pat] (\pats' -> let [pat'] = pats' in thing_inside pat')
-
-applyNameMaker :: NameMaker -> Located RdrName -> RnM (Located Name)
-applyNameMaker mk rdr = do { (n, _fvs) <- runCps (newPatLName mk rdr)
- ; return n }
-
--- ----------- Entry point 2: rnBindPat -------------------
--- Binds local names; in a recursive scope that involves other bound vars
--- e.g let { (x, Just y) = e1; ... } in ...
--- * does NOT allows type sig to bind type vars
--- * local namemaker
--- * no unused and duplicate checking
--- * fixities might be coming in
-rnBindPat :: NameMaker
- -> LPat GhcPs
- -> RnM (LPat GhcRn, FreeVars)
- -- Returned FreeVars are the free variables of the pattern,
- -- of course excluding variables bound by this pattern
-
-rnBindPat name_maker pat = runCps (rnLPatAndThen name_maker pat)
-
-{-
-*********************************************************
-* *
- The main event
-* *
-*********************************************************
--}
-
--- ----------- Entry point 3: rnLPatAndThen -------------------
--- General version: parametrized by how you make new names
-
-rnLPatsAndThen :: NameMaker -> [LPat GhcPs] -> CpsRn [LPat GhcRn]
-rnLPatsAndThen mk = mapM (rnLPatAndThen mk)
- -- Despite the map, the monad ensures that each pattern binds
- -- variables that may be mentioned in subsequent patterns in the list
-
---------------------
--- The workhorse
-rnLPatAndThen :: NameMaker -> LPat GhcPs -> CpsRn (LPat GhcRn)
-rnLPatAndThen nm lpat = wrapSrcSpanCps (rnPatAndThen nm) lpat
-
-rnPatAndThen :: NameMaker -> Pat GhcPs -> CpsRn (Pat GhcRn)
-rnPatAndThen _ (WildPat _) = return (WildPat noExtField)
-rnPatAndThen mk (ParPat x pat) = do { pat' <- rnLPatAndThen mk pat
- ; return (ParPat x pat') }
-rnPatAndThen mk (LazyPat x pat) = do { pat' <- rnLPatAndThen mk pat
- ; return (LazyPat x pat') }
-rnPatAndThen mk (BangPat x pat) = do { pat' <- rnLPatAndThen mk pat
- ; return (BangPat x pat') }
-rnPatAndThen mk (VarPat x (L l rdr))
- = do { loc <- liftCps getSrcSpanM
- ; name <- newPatName mk (L loc rdr)
- ; return (VarPat x (L l name)) }
- -- we need to bind pattern variables for view pattern expressions
- -- (e.g. in the pattern (x, x -> y) x needs to be bound in the rhs of the tuple)
-
-rnPatAndThen mk (SigPat x pat sig)
- -- When renaming a pattern type signature (e.g. f (a :: T) = ...), it is
- -- important to rename its type signature _before_ renaming the rest of the
- -- pattern, so that type variables are first bound by the _outermost_ pattern
- -- type signature they occur in. This keeps the type checker happy when
- -- pattern type signatures happen to be nested (#7827)
- --
- -- f ((Just (x :: a) :: Maybe a)
- -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~^ `a' is first bound here
- -- ~~~~~~~~~~~~~~~^ the same `a' then used here
- = do { sig' <- rnHsSigCps sig
- ; pat' <- rnLPatAndThen mk pat
- ; return (SigPat x pat' sig' ) }
-
-rnPatAndThen mk (LitPat x lit)
- | HsString src s <- lit
- = do { ovlStr <- liftCps (xoptM LangExt.OverloadedStrings)
- ; if ovlStr
- then rnPatAndThen mk
- (mkNPat (noLoc (mkHsIsString src s))
- Nothing)
- else normal_lit }
- | otherwise = normal_lit
- where
- normal_lit = do { liftCps (rnLit lit); return (LitPat x (convertLit lit)) }
-
-rnPatAndThen _ (NPat x (L l lit) mb_neg _eq)
- = do { (lit', mb_neg') <- liftCpsFV $ rnOverLit lit
- ; mb_neg' -- See Note [Negative zero]
- <- let negative = do { (neg, fvs) <- lookupSyntaxName negateName
- ; return (Just neg, fvs) }
- positive = return (Nothing, emptyFVs)
- in liftCpsFV $ case (mb_neg , mb_neg') of
- (Nothing, Just _ ) -> negative
- (Just _ , Nothing) -> negative
- (Nothing, Nothing) -> positive
- (Just _ , Just _ ) -> positive
- ; eq' <- liftCpsFV $ lookupSyntaxName eqName
- ; return (NPat x (L l lit') mb_neg' eq') }
-
-rnPatAndThen mk (NPlusKPat x rdr (L l lit) _ _ _ )
- = do { new_name <- newPatName mk rdr
- ; (lit', _) <- liftCpsFV $ rnOverLit lit -- See Note [Negative zero]
- -- We skip negateName as
- -- negative zero doesn't make
- -- sense in n + k patterns
- ; minus <- liftCpsFV $ lookupSyntaxName minusName
- ; ge <- liftCpsFV $ lookupSyntaxName geName
- ; return (NPlusKPat x (L (nameSrcSpan new_name) new_name)
- (L l lit') lit' ge minus) }
- -- The Report says that n+k patterns must be in Integral
-
-rnPatAndThen mk (AsPat x rdr pat)
- = do { new_name <- newPatLName mk rdr
- ; pat' <- rnLPatAndThen mk pat
- ; return (AsPat x new_name pat') }
-
-rnPatAndThen mk p@(ViewPat x expr pat)
- = do { liftCps $ do { vp_flag <- xoptM LangExt.ViewPatterns
- ; checkErr vp_flag (badViewPat p) }
- -- Because of the way we're arranging the recursive calls,
- -- this will be in the right context
- ; expr' <- liftCpsFV $ rnLExpr expr
- ; pat' <- rnLPatAndThen mk pat
- -- Note: at this point the PreTcType in ty can only be a placeHolder
- -- ; return (ViewPat expr' pat' ty) }
- ; return (ViewPat x expr' pat') }
-
-rnPatAndThen mk (ConPatIn con stuff)
- -- rnConPatAndThen takes care of reconstructing the pattern
- -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on.
- = case unLoc con == nameRdrName (dataConName nilDataCon) of
- True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists
- ; if ol_flag then rnPatAndThen mk (ListPat noExtField [])
- else rnConPatAndThen mk con stuff}
- False -> rnConPatAndThen mk con stuff
-
-rnPatAndThen mk (ListPat _ pats)
- = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists
- ; pats' <- rnLPatsAndThen mk pats
- ; case opt_OverloadedLists of
- True -> do { (to_list_name,_) <- liftCps $ lookupSyntaxName toListName
- ; return (ListPat (Just to_list_name) pats')}
- False -> return (ListPat Nothing pats') }
-
-rnPatAndThen mk (TuplePat x pats boxed)
- = do { liftCps $ checkTupSize (length pats)
- ; pats' <- rnLPatsAndThen mk pats
- ; return (TuplePat x pats' boxed) }
-
-rnPatAndThen mk (SumPat x pat alt arity)
- = do { pat <- rnLPatAndThen mk pat
- ; return (SumPat x pat alt arity)
- }
-
--- If a splice has been run already, just rename the result.
-rnPatAndThen mk (SplicePat x (HsSpliced x2 mfs (HsSplicedPat pat)))
- = SplicePat x . HsSpliced x2 mfs . HsSplicedPat <$> rnPatAndThen mk pat
-
-rnPatAndThen mk (SplicePat _ splice)
- = do { eith <- liftCpsFV $ rnSplicePat splice
- ; case eith of -- See Note [rnSplicePat] in RnSplice
- Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed
- Right already_renamed -> return already_renamed }
-
-rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat)
-
-
---------------------
-rnConPatAndThen :: NameMaker
- -> Located RdrName -- the constructor
- -> HsConPatDetails GhcPs
- -> CpsRn (Pat GhcRn)
-
-rnConPatAndThen mk con (PrefixCon pats)
- = do { con' <- lookupConCps con
- ; pats' <- rnLPatsAndThen mk pats
- ; return (ConPatIn con' (PrefixCon pats')) }
-
-rnConPatAndThen mk con (InfixCon pat1 pat2)
- = do { con' <- lookupConCps con
- ; pat1' <- rnLPatAndThen mk pat1
- ; pat2' <- rnLPatAndThen mk pat2
- ; fixity <- liftCps $ lookupFixityRn (unLoc con')
- ; liftCps $ mkConOpPatRn con' fixity pat1' pat2' }
-
-rnConPatAndThen mk con (RecCon rpats)
- = do { con' <- lookupConCps con
- ; rpats' <- rnHsRecPatsAndThen mk con' rpats
- ; return (ConPatIn con' (RecCon rpats')) }
-
-checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn ()
-checkUnusedRecordWildcardCps loc dotdot_names =
- CpsRn (\thing -> do
- (r, fvs) <- thing ()
- checkUnusedRecordWildcard loc fvs dotdot_names
- return (r, fvs) )
---------------------
-rnHsRecPatsAndThen :: NameMaker
- -> Located Name -- Constructor
- -> HsRecFields GhcPs (LPat GhcPs)
- -> CpsRn (HsRecFields GhcRn (LPat GhcRn))
-rnHsRecPatsAndThen mk (L _ con)
- hs_rec_fields@(HsRecFields { rec_dotdot = dd })
- = do { flds <- liftCpsFV $ rnHsRecFields (HsRecFieldPat con) mkVarPat
- hs_rec_fields
- ; flds' <- mapM rn_field (flds `zip` [1..])
- ; check_unused_wildcard (implicit_binders flds' <$> dd)
- ; return (HsRecFields { rec_flds = flds', rec_dotdot = dd }) }
- where
- mkVarPat l n = VarPat noExtField (L l n)
- rn_field (L l fld, n') =
- do { arg' <- rnLPatAndThen (nested_mk dd mk n') (hsRecFieldArg fld)
- ; return (L l (fld { hsRecFieldArg = arg' })) }
-
- loc = maybe noSrcSpan getLoc dd
-
- -- Get the arguments of the implicit binders
- implicit_binders fs (unLoc -> n) = collectPatsBinders implicit_pats
- where
- implicit_pats = map (hsRecFieldArg . unLoc) (drop n fs)
-
- -- Don't warn for let P{..} = ... in ...
- check_unused_wildcard = case mk of
- LetMk{} -> const (return ())
- LamMk{} -> checkUnusedRecordWildcardCps loc
-
- -- Suppress unused-match reporting for fields introduced by ".."
- nested_mk Nothing mk _ = mk
- nested_mk (Just _) mk@(LetMk {}) _ = mk
- nested_mk (Just (unLoc -> n)) (LamMk report_unused) n'
- = LamMk (report_unused && (n' <= n))
-
-{-
-************************************************************************
-* *
- Record fields
-* *
-************************************************************************
--}
-
-data HsRecFieldContext
- = HsRecFieldCon Name
- | HsRecFieldPat Name
- | HsRecFieldUpd
-
-rnHsRecFields
- :: forall arg.
- HsRecFieldContext
- -> (SrcSpan -> RdrName -> arg)
- -- When punning, use this to build a new field
- -> HsRecFields GhcPs (Located arg)
- -> RnM ([LHsRecField GhcRn (Located arg)], FreeVars)
-
--- This surprisingly complicated pass
--- a) looks up the field name (possibly using disambiguation)
--- b) fills in puns and dot-dot stuff
--- When we've finished, we've renamed the LHS, but not the RHS,
--- of each x=e binding
---
--- This is used for record construction and pattern-matching, but not updates.
-
-rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot })
- = do { pun_ok <- xoptM LangExt.RecordPuns
- ; disambig_ok <- xoptM LangExt.DisambiguateRecordFields
- ; let parent = guard disambig_ok >> mb_con
- ; flds1 <- mapM (rn_fld pun_ok parent) flds
- ; mapM_ (addErr . dupFieldErr ctxt) dup_flds
- ; dotdot_flds <- rn_dotdot dotdot mb_con flds1
- ; let all_flds | null dotdot_flds = flds1
- | otherwise = flds1 ++ dotdot_flds
- ; return (all_flds, mkFVs (getFieldIds all_flds)) }
- where
- mb_con = case ctxt of
- HsRecFieldCon con -> Just con
- HsRecFieldPat con -> Just con
- _ {- update -} -> Nothing
-
- rn_fld :: Bool -> Maybe Name -> LHsRecField GhcPs (Located arg)
- -> RnM (LHsRecField GhcRn (Located arg))
- rn_fld pun_ok parent (L l
- (HsRecField
- { hsRecFieldLbl =
- (L loc (FieldOcc _ (L ll lbl)))
- , hsRecFieldArg = arg
- , hsRecPun = pun }))
- = do { sel <- setSrcSpan loc $ lookupRecFieldOcc parent lbl
- ; arg' <- if pun
- then do { checkErr pun_ok (badPun (L loc lbl))
- -- Discard any module qualifier (#11662)
- ; let arg_rdr = mkRdrUnqual (rdrNameOcc lbl)
- ; return (L loc (mk_arg loc arg_rdr)) }
- else return arg
- ; return (L l (HsRecField
- { hsRecFieldLbl = (L loc (FieldOcc
- sel (L ll lbl)))
- , hsRecFieldArg = arg'
- , hsRecPun = pun })) }
- rn_fld _ _ (L _ (HsRecField (L _ (XFieldOcc _)) _ _))
- = panic "rnHsRecFields"
-
-
- rn_dotdot :: Maybe (Located Int) -- See Note [DotDot fields] in GHC.Hs.Pat
- -> Maybe Name -- The constructor (Nothing for an
- -- out of scope constructor)
- -> [LHsRecField GhcRn (Located arg)] -- Explicit fields
- -> RnM ([LHsRecField GhcRn (Located arg)]) -- Field Labels we need to fill in
- rn_dotdot (Just (L loc n)) (Just con) flds -- ".." on record construction / pat match
- | not (isUnboundName con) -- This test is because if the constructor
- -- isn't in scope the constructor lookup will add
- -- an error but still return an unbound name. We
- -- don't want that to screw up the dot-dot fill-in stuff.
- = ASSERT( flds `lengthIs` n )
- do { dd_flag <- xoptM LangExt.RecordWildCards
- ; checkErr dd_flag (needFlagDotDot ctxt)
- ; (rdr_env, lcl_env) <- getRdrEnvs
- ; con_fields <- lookupConstructorFields con
- ; when (null con_fields) (addErr (badDotDotCon con))
- ; let present_flds = mkOccSet $ map rdrNameOcc (getFieldLbls flds)
-
- -- For constructor uses (but not patterns)
- -- the arg should be in scope locally;
- -- i.e. not top level or imported
- -- Eg. data R = R { x,y :: Int }
- -- f x = R { .. } -- Should expand to R {x=x}, not R{x=x,y=y}
- arg_in_scope lbl = mkRdrUnqual lbl `elemLocalRdrEnv` lcl_env
-
- (dot_dot_fields, dot_dot_gres)
- = unzip [ (fl, gre)
- | fl <- con_fields
- , let lbl = mkVarOccFS (flLabel fl)
- , not (lbl `elemOccSet` present_flds)
- , Just gre <- [lookupGRE_FieldLabel rdr_env fl]
- -- Check selector is in scope
- , case ctxt of
- HsRecFieldCon {} -> arg_in_scope lbl
- _other -> True ]
-
- ; addUsedGREs dot_dot_gres
- ; return [ L loc (HsRecField
- { hsRecFieldLbl = L loc (FieldOcc sel (L loc arg_rdr))
- , hsRecFieldArg = L loc (mk_arg loc arg_rdr)
- , hsRecPun = False })
- | fl <- dot_dot_fields
- , let sel = flSelector fl
- , let arg_rdr = mkVarUnqual (flLabel fl) ] }
-
- rn_dotdot _dotdot _mb_con _flds
- = return []
- -- _dotdot = Nothing => No ".." at all
- -- _mb_con = Nothing => Record update
- -- _mb_con = Just unbound => Out of scope data constructor
-
- dup_flds :: [NE.NonEmpty RdrName]
- -- Each list represents a RdrName that occurred more than once
- -- (the list contains all occurrences)
- -- Each list in dup_fields is non-empty
- (_, dup_flds) = removeDups compare (getFieldLbls flds)
-
-
--- NB: Consider this:
--- module Foo where { data R = R { fld :: Int } }
--- module Odd where { import Foo; fld x = x { fld = 3 } }
--- Arguably this should work, because the reference to 'fld' is
--- unambiguous because there is only one field id 'fld' in scope.
--- But currently it's rejected.
-
-rnHsRecUpdFields
- :: [LHsRecUpdField GhcPs]
- -> RnM ([LHsRecUpdField GhcRn], FreeVars)
-rnHsRecUpdFields flds
- = do { pun_ok <- xoptM LangExt.RecordPuns
- ; overload_ok <- xoptM LangExt.DuplicateRecordFields
- ; (flds1, fvss) <- mapAndUnzipM (rn_fld pun_ok overload_ok) flds
- ; mapM_ (addErr . dupFieldErr HsRecFieldUpd) dup_flds
-
- -- Check for an empty record update e {}
- -- NB: don't complain about e { .. }, because rn_dotdot has done that already
- ; when (null flds) $ addErr emptyUpdateErr
-
- ; return (flds1, plusFVs fvss) }
- where
- doc = text "constructor field name"
-
- rn_fld :: Bool -> Bool -> LHsRecUpdField GhcPs
- -> RnM (LHsRecUpdField GhcRn, FreeVars)
- rn_fld pun_ok overload_ok (L l (HsRecField { hsRecFieldLbl = L loc f
- , hsRecFieldArg = arg
- , hsRecPun = pun }))
- = do { let lbl = rdrNameAmbiguousFieldOcc f
- ; sel <- setSrcSpan loc $
- -- Defer renaming of overloaded fields to the typechecker
- -- See Note [Disambiguating record fields] in TcExpr
- if overload_ok
- then do { mb <- lookupGlobalOccRn_overloaded
- overload_ok lbl
- ; case mb of
- Nothing ->
- do { addErr
- (unknownSubordinateErr doc lbl)
- ; return (Right []) }
- Just r -> return r }
- else fmap Left $ lookupGlobalOccRn lbl
- ; arg' <- if pun
- then do { checkErr pun_ok (badPun (L loc lbl))
- -- Discard any module qualifier (#11662)
- ; let arg_rdr = mkRdrUnqual (rdrNameOcc lbl)
- ; return (L loc (HsVar noExtField (L loc arg_rdr))) }
- else return arg
- ; (arg'', fvs) <- rnLExpr arg'
-
- ; let fvs' = case sel of
- Left sel_name -> fvs `addOneFV` sel_name
- Right [sel_name] -> fvs `addOneFV` sel_name
- Right _ -> fvs
- lbl' = case sel of
- Left sel_name ->
- L loc (Unambiguous sel_name (L loc lbl))
- Right [sel_name] ->
- L loc (Unambiguous sel_name (L loc lbl))
- Right _ -> L loc (Ambiguous noExtField (L loc lbl))
-
- ; return (L l (HsRecField { hsRecFieldLbl = lbl'
- , hsRecFieldArg = arg''
- , hsRecPun = pun }), fvs') }
-
- dup_flds :: [NE.NonEmpty RdrName]
- -- Each list represents a RdrName that occurred more than once
- -- (the list contains all occurrences)
- -- Each list in dup_fields is non-empty
- (_, dup_flds) = removeDups compare (getFieldUpdLbls flds)
-
-
-
-getFieldIds :: [LHsRecField GhcRn arg] -> [Name]
-getFieldIds flds = map (unLoc . hsRecFieldSel . unLoc) flds
-
-getFieldLbls :: [LHsRecField id arg] -> [RdrName]
-getFieldLbls flds
- = map (unLoc . rdrNameFieldOcc . unLoc . hsRecFieldLbl . unLoc) flds
-
-getFieldUpdLbls :: [LHsRecUpdField GhcPs] -> [RdrName]
-getFieldUpdLbls flds = map (rdrNameAmbiguousFieldOcc . unLoc . hsRecFieldLbl . unLoc) flds
-
-needFlagDotDot :: HsRecFieldContext -> SDoc
-needFlagDotDot ctxt = vcat [text "Illegal `..' in record" <+> pprRFC ctxt,
- text "Use RecordWildCards to permit this"]
-
-badDotDotCon :: Name -> SDoc
-badDotDotCon con
- = vcat [ text "Illegal `..' notation for constructor" <+> quotes (ppr con)
- , nest 2 (text "The constructor has no labelled fields") ]
-
-emptyUpdateErr :: SDoc
-emptyUpdateErr = text "Empty record update"
-
-badPun :: Located RdrName -> SDoc
-badPun fld = vcat [text "Illegal use of punning for field" <+> quotes (ppr fld),
- text "Use NamedFieldPuns to permit this"]
-
-dupFieldErr :: HsRecFieldContext -> NE.NonEmpty RdrName -> SDoc
-dupFieldErr ctxt dups
- = hsep [text "duplicate field name",
- quotes (ppr (NE.head dups)),
- text "in record", pprRFC ctxt]
-
-pprRFC :: HsRecFieldContext -> SDoc
-pprRFC (HsRecFieldCon {}) = text "construction"
-pprRFC (HsRecFieldPat {}) = text "pattern"
-pprRFC (HsRecFieldUpd {}) = text "update"
-
-{-
-************************************************************************
-* *
-\subsubsection{Literals}
-* *
-************************************************************************
-
-When literals occur we have to make sure
-that the types and classes they involve
-are made available.
--}
-
-rnLit :: HsLit p -> RnM ()
-rnLit (HsChar _ c) = checkErr (inCharRange c) (bogusCharError c)
-rnLit _ = return ()
-
--- Turn a Fractional-looking literal which happens to be an integer into an
--- Integer-looking literal.
-generalizeOverLitVal :: OverLitVal -> OverLitVal
-generalizeOverLitVal (HsFractional (FL {fl_text=src,fl_neg=neg,fl_value=val}))
- | denominator val == 1 = HsIntegral (IL { il_text=src
- , il_neg=neg
- , il_value=numerator val})
-generalizeOverLitVal lit = lit
-
-isNegativeZeroOverLit :: HsOverLit t -> Bool
-isNegativeZeroOverLit lit
- = case ol_val lit of
- HsIntegral i -> 0 == il_value i && il_neg i
- HsFractional f -> 0 == fl_value f && fl_neg f
- _ -> False
-
-{-
-Note [Negative zero]
-~~~~~~~~~~~~~~~~~~~~~~~~~
-There were problems with negative zero in conjunction with Negative Literals
-extension. Numeric literal value is contained in Integer and Rational types
-inside IntegralLit and FractionalLit. These types cannot represent negative
-zero value. So we had to add explicit field 'neg' which would hold information
-about literal sign. Here in rnOverLit we use it to detect negative zeroes and
-in this case return not only literal itself but also negateName so that users
-can apply it explicitly. In this case it stays negative zero. #13211
--}
-
-rnOverLit :: HsOverLit t ->
- RnM ((HsOverLit GhcRn, Maybe (HsExpr GhcRn)), FreeVars)
-rnOverLit origLit
- = do { opt_NumDecimals <- xoptM LangExt.NumDecimals
- ; let { lit@(OverLit {ol_val=val})
- | opt_NumDecimals = origLit {ol_val = generalizeOverLitVal (ol_val origLit)}
- | otherwise = origLit
- }
- ; let std_name = hsOverLitName val
- ; (SyntaxExpr { syn_expr = from_thing_name }, fvs1)
- <- lookupSyntaxName std_name
- ; let rebindable = case from_thing_name of
- HsVar _ lv -> (unLoc lv) /= std_name
- _ -> panic "rnOverLit"
- ; let lit' = lit { ol_witness = from_thing_name
- , ol_ext = rebindable }
- ; if isNegativeZeroOverLit lit'
- then do { (SyntaxExpr { syn_expr = negate_name }, fvs2)
- <- lookupSyntaxName negateName
- ; return ((lit' { ol_val = negateOverLitVal val }, Just negate_name)
- , fvs1 `plusFV` fvs2) }
- else return ((lit', Nothing), fvs1) }
-
-{-
-************************************************************************
-* *
-\subsubsection{Errors}
-* *
-************************************************************************
--}
-
-patSigErr :: Outputable a => a -> SDoc
-patSigErr ty
- = (text "Illegal signature in pattern:" <+> ppr ty)
- $$ nest 4 (text "Use ScopedTypeVariables to permit it")
-
-bogusCharError :: Char -> SDoc
-bogusCharError c
- = text "character literal out of range: '\\" <> char c <> char '\''
-
-badViewPat :: Pat GhcPs -> SDoc
-badViewPat pat = vcat [text "Illegal view pattern: " <+> ppr pat,
- text "Use ViewPatterns to enable view patterns"]
diff --git a/compiler/rename/RnSource.hs b/compiler/rename/RnSource.hs
deleted file mode 100644
index a166a65bfb..0000000000
--- a/compiler/rename/RnSource.hs
+++ /dev/null
@@ -1,2415 +0,0 @@
-{-
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-\section[RnSource]{Main pass of renamer}
--}
-
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE ViewPatterns #-}
-
-module RnSource (
- rnSrcDecls, addTcgDUs, findSplice
- ) where
-
-#include "HsVersions.h"
-
-import GhcPrelude
-
-import {-# SOURCE #-} RnExpr( rnLExpr )
-import {-# SOURCE #-} RnSplice ( rnSpliceDecl, rnTopSpliceDecls )
-
-import GHC.Hs
-import FieldLabel
-import RdrName
-import RnTypes
-import RnBinds
-import RnEnv
-import RnUtils ( HsDocContext(..), mapFvRn, bindLocalNames
- , checkDupRdrNames, inHsDocContext, bindLocalNamesFV
- , checkShadowedRdrNames, warnUnusedTypePatterns
- , extendTyVarEnvFVRn, newLocalBndrsRn
- , withHsDocContext )
-import RnUnbound ( mkUnboundName, notInScopeErr )
-import RnNames
-import RnHsDoc ( rnHsDoc, rnMbLHsDoc )
-import TcAnnotations ( annCtxt )
-import TcRnMonad
-
-import ForeignCall ( CCallTarget(..) )
-import Module
-import HscTypes ( Warnings(..), plusWarns )
-import PrelNames ( applicativeClassName, pureAName, thenAName
- , monadClassName, returnMName, thenMName
- , semigroupClassName, sappendName
- , monoidClassName, mappendName
- )
-import Name
-import NameSet
-import NameEnv
-import Avail
-import Outputable
-import Bag
-import BasicTypes ( pprRuleName, TypeOrKind(..) )
-import FastString
-import SrcLoc
-import DynFlags
-import Util ( debugIsOn, filterOut, lengthExceeds, partitionWith )
-import HscTypes ( HscEnv, hsc_dflags )
-import ListSetOps ( findDupsEq, removeDups, equivClasses )
-import Digraph ( SCC, flattenSCC, flattenSCCs, Node(..)
- , stronglyConnCompFromEdgedVerticesUniq )
-import UniqSet
-import OrdList
-import qualified GHC.LanguageExtensions as LangExt
-
-import Control.Monad
-import Control.Arrow ( first )
-import Data.List ( mapAccumL )
-import qualified Data.List.NonEmpty as NE
-import Data.List.NonEmpty ( NonEmpty(..) )
-import Data.Maybe ( isNothing, fromMaybe, mapMaybe )
-import qualified Data.Set as Set ( difference, fromList, toList, null )
-import Data.Function ( on )
-
-{- | @rnSourceDecl@ "renames" declarations.
-It simultaneously performs dependency analysis and precedence parsing.
-It also does the following error checks:
-
-* Checks that tyvars are used properly. This includes checking
- for undefined tyvars, and tyvars in contexts that are ambiguous.
- (Some of this checking has now been moved to module @TcMonoType@,
- since we don't have functional dependency information at this point.)
-
-* Checks that all variable occurrences are defined.
-
-* Checks the @(..)@ etc constraints in the export list.
-
-Brings the binders of the group into scope in the appropriate places;
-does NOT assume that anything is in scope already
--}
-rnSrcDecls :: HsGroup GhcPs -> RnM (TcGblEnv, HsGroup GhcRn)
--- Rename a top-level HsGroup; used for normal source files *and* hs-boot files
-rnSrcDecls group@(HsGroup { hs_valds = val_decls,
- hs_splcds = splice_decls,
- hs_tyclds = tycl_decls,
- hs_derivds = deriv_decls,
- hs_fixds = fix_decls,
- hs_warnds = warn_decls,
- hs_annds = ann_decls,
- hs_fords = foreign_decls,
- hs_defds = default_decls,
- hs_ruleds = rule_decls,
- hs_docs = docs })
- = do {
- -- (A) Process the fixity declarations, creating a mapping from
- -- FastStrings to FixItems.
- -- Also checks for duplicates.
- local_fix_env <- makeMiniFixityEnv fix_decls ;
-
- -- (B) Bring top level binders (and their fixities) into scope,
- -- *except* for the value bindings, which get done in step (D)
- -- with collectHsIdBinders. However *do* include
- --
- -- * Class ops, data constructors, and record fields,
- -- because they do not have value declarations.
- --
- -- * For hs-boot files, include the value signatures
- -- Again, they have no value declarations
- --
- (tc_envs, tc_bndrs) <- getLocalNonValBinders local_fix_env group ;
-
-
- setEnvs tc_envs $ do {
-
- failIfErrsM ; -- No point in continuing if (say) we have duplicate declarations
-
- -- (D1) Bring pattern synonyms into scope.
- -- Need to do this before (D2) because rnTopBindsLHS
- -- looks up those pattern synonyms (#9889)
-
- extendPatSynEnv val_decls local_fix_env $ \pat_syn_bndrs -> do {
-
- -- (D2) Rename the left-hand sides of the value bindings.
- -- This depends on everything from (B) being in scope.
- -- It uses the fixity env from (A) to bind fixities for view patterns.
- new_lhs <- rnTopBindsLHS local_fix_env val_decls ;
-
- -- Bind the LHSes (and their fixities) in the global rdr environment
- let { id_bndrs = collectHsIdBinders new_lhs } ; -- Excludes pattern-synonym binders
- -- They are already in scope
- traceRn "rnSrcDecls" (ppr id_bndrs) ;
- tc_envs <- extendGlobalRdrEnvRn (map avail id_bndrs) local_fix_env ;
- setEnvs tc_envs $ do {
-
- -- Now everything is in scope, as the remaining renaming assumes.
-
- -- (E) Rename type and class decls
- -- (note that value LHSes need to be in scope for default methods)
- --
- -- 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
- -- analysis for them in the type checker.
- -- 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 "Start rnTyClDecls" (ppr tycl_decls) ;
- (rn_tycl_decls, src_fvs1) <- rnTyClDecls tycl_decls ;
-
- -- (F) Rename Value declarations right-hand sides
- traceRn "Start rnmono" empty ;
- let { val_bndr_set = mkNameSet id_bndrs `unionNameSet` mkNameSet pat_syn_bndrs } ;
- is_boot <- tcIsHsBootOrSig ;
- (rn_val_decls, bind_dus) <- if is_boot
- -- For an hs-boot, use tc_bndrs (which collects how we're renamed
- -- signatures), since val_bndr_set is empty (there are no x = ...
- -- bindings in an hs-boot.)
- then rnTopBindsBoot tc_bndrs new_lhs
- else rnValBindsRHS (TopSigCtxt val_bndr_set) new_lhs ;
- traceRn "finish rnmono" (ppr rn_val_decls) ;
-
- -- (G) Rename Fixity and deprecations
-
- -- Rename fixity declarations and error if we try to
- -- fix something from another module (duplicates were checked in (A))
- let { all_bndrs = tc_bndrs `unionNameSet` val_bndr_set } ;
- rn_fix_decls <- mapM (mapM (rnSrcFixityDecl (TopSigCtxt all_bndrs)))
- fix_decls ;
-
- -- Rename deprec decls;
- -- check for duplicates and ensure that deprecated things are defined locally
- -- at the moment, we don't keep these around past renaming
- rn_warns <- rnSrcWarnDecls all_bndrs warn_decls ;
-
- -- (H) Rename Everything else
-
- (rn_rule_decls, src_fvs2) <- setXOptM LangExt.ScopedTypeVariables $
- rnList rnHsRuleDecls rule_decls ;
- -- Inside RULES, scoped type variables are on
- (rn_foreign_decls, src_fvs3) <- rnList rnHsForeignDecl foreign_decls ;
- (rn_ann_decls, src_fvs4) <- rnList rnAnnDecl ann_decls ;
- (rn_default_decls, src_fvs5) <- rnList rnDefaultDecl default_decls ;
- (rn_deriv_decls, src_fvs6) <- rnList rnSrcDerivDecl deriv_decls ;
- (rn_splice_decls, src_fvs7) <- rnList rnSpliceDecl splice_decls ;
- -- Haddock docs; no free vars
- rn_docs <- mapM (wrapLocM rnDocDecl) docs ;
-
- last_tcg_env <- getGblEnv ;
- -- (I) Compute the results and return
- let {rn_group = HsGroup { hs_ext = noExtField,
- hs_valds = rn_val_decls,
- hs_splcds = rn_splice_decls,
- hs_tyclds = rn_tycl_decls,
- hs_derivds = rn_deriv_decls,
- hs_fixds = rn_fix_decls,
- hs_warnds = [], -- warns are returned in the tcg_env
- -- (see below) not in the HsGroup
- hs_fords = rn_foreign_decls,
- hs_annds = rn_ann_decls,
- hs_defds = rn_default_decls,
- hs_ruleds = rn_rule_decls,
- hs_docs = rn_docs } ;
-
- tcf_bndrs = hsTyClForeignBinders rn_tycl_decls rn_foreign_decls ;
- other_def = (Just (mkNameSet tcf_bndrs), emptyNameSet) ;
- other_fvs = plusFVs [src_fvs1, src_fvs2, src_fvs3, src_fvs4,
- src_fvs5, src_fvs6, src_fvs7] ;
- -- It is tiresome to gather the binders from type and class decls
-
- src_dus = unitOL other_def `plusDU` bind_dus `plusDU` usesOnly other_fvs ;
- -- Instance decls may have occurrences of things bound in bind_dus
- -- so we must put other_fvs last
-
- final_tcg_env = let tcg_env' = (last_tcg_env `addTcgDUs` src_dus)
- in -- we return the deprecs in the env, not in the HsGroup above
- tcg_env' { tcg_warns = tcg_warns tcg_env' `plusWarns` rn_warns };
- } ;
- traceRn "finish rnSrc" (ppr rn_group) ;
- traceRn "finish Dus" (ppr src_dus ) ;
- return (final_tcg_env, rn_group)
- }}}}
-rnSrcDecls (XHsGroup nec) = noExtCon nec
-
-addTcgDUs :: TcGblEnv -> DefUses -> TcGblEnv
--- This function could be defined lower down in the module hierarchy,
--- but there doesn't seem anywhere very logical to put it.
-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
-
-{-
-*********************************************************
-* *
- HsDoc stuff
-* *
-*********************************************************
--}
-
-rnDocDecl :: DocDecl -> RnM DocDecl
-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)
-
-{-
-*********************************************************
-* *
- Source-code deprecations declarations
-* *
-*********************************************************
-
-Check that the deprecated names are defined, are defined locally, and
-that there are no duplicate deprecations.
-
-It's only imported deprecations, dealt with in RnIfaces, that we
-gather them together.
--}
-
--- checks that the deprecations are defined locally, and that there are no duplicates
-rnSrcWarnDecls :: NameSet -> [LWarnDecls GhcPs] -> RnM Warnings
-rnSrcWarnDecls _ []
- = return NoWarnings
-
-rnSrcWarnDecls bndr_set decls'
- = do { -- check for duplicates
- ; mapM_ (\ dups -> let ((L loc rdr) :| (lrdr':_)) = dups
- in addErrAt loc (dupWarnDecl lrdr' rdr))
- warn_rdr_dups
- ; pairs_s <- mapM (addLocM rn_deprec) decls
- ; return (WarnSome ((concat pairs_s))) }
- where
- decls = concatMap (wd_warnings . unLoc) decls'
-
- sig_ctxt = TopSigCtxt bndr_set
-
- rn_deprec (Warning _ rdr_names txt)
- -- ensures that the names are defined locally
- = do { names <- concatMapM (lookupLocalTcNames sig_ctxt what . unLoc)
- rdr_names
- ; return [(rdrNameOcc rdr, txt) | (rdr, _) <- names] }
- rn_deprec (XWarnDecl nec) = noExtCon nec
-
- what = text "deprecation"
-
- warn_rdr_dups = findDupRdrNames
- $ concatMap (\(L _ (Warning _ ns _)) -> ns) decls
-
-findDupRdrNames :: [Located RdrName] -> [NonEmpty (Located RdrName)]
-findDupRdrNames = findDupsEq (\ x -> \ y -> rdrNameOcc (unLoc x) == rdrNameOcc (unLoc y))
-
--- look for duplicates among the OccNames;
--- we check that the names are defined above
--- invt: the lists returned by findDupsEq always have at least two elements
-
-dupWarnDecl :: Located RdrName -> RdrName -> SDoc
--- Located RdrName -> DeprecDecl RdrName -> SDoc
-dupWarnDecl d rdr_name
- = vcat [text "Multiple warning declarations for" <+> quotes (ppr rdr_name),
- text "also at " <+> ppr (getLoc d)]
-
-{-
-*********************************************************
-* *
-\subsection{Annotation declarations}
-* *
-*********************************************************
--}
-
-rnAnnDecl :: AnnDecl GhcPs -> RnM (AnnDecl GhcRn, FreeVars)
-rnAnnDecl ann@(HsAnnotation _ s provenance expr)
- = addErrCtxt (annCtxt ann) $
- do { (provenance', provenance_fvs) <- rnAnnProvenance provenance
- ; (expr', expr_fvs) <- setStage (Splice Untyped) $
- rnLExpr expr
- ; return (HsAnnotation noExtField s provenance' expr',
- provenance_fvs `plusFV` expr_fvs) }
-rnAnnDecl (XAnnDecl nec) = noExtCon nec
-
-rnAnnProvenance :: AnnProvenance RdrName
- -> RnM (AnnProvenance Name, FreeVars)
-rnAnnProvenance provenance = do
- provenance' <- traverse lookupTopBndrRn provenance
- return (provenance', maybe emptyFVs unitFV (annProvenanceName_maybe provenance'))
-
-{-
-*********************************************************
-* *
-\subsection{Default declarations}
-* *
-*********************************************************
--}
-
-rnDefaultDecl :: DefaultDecl GhcPs -> RnM (DefaultDecl GhcRn, FreeVars)
-rnDefaultDecl (DefaultDecl _ tys)
- = do { (tys', fvs) <- rnLHsTypes doc_str tys
- ; return (DefaultDecl noExtField tys', fvs) }
- where
- doc_str = DefaultDeclCtx
-rnDefaultDecl (XDefaultDecl nec) = noExtCon nec
-
-{-
-*********************************************************
-* *
-\subsection{Foreign declarations}
-* *
-*********************************************************
--}
-
-rnHsForeignDecl :: ForeignDecl GhcPs -> RnM (ForeignDecl GhcRn, FreeVars)
-rnHsForeignDecl (ForeignImport { fd_name = name, fd_sig_ty = ty, fd_fi = spec })
- = do { topEnv :: HscEnv <- getTopEnv
- ; name' <- lookupLocatedTopBndrRn name
- ; (ty', fvs) <- rnHsSigType (ForeignDeclCtx name) TypeLevel ty
-
- -- Mark any PackageTarget style imports as coming from the current package
- ; let unitId = thisPackage $ hsc_dflags topEnv
- spec' = patchForeignImport unitId spec
-
- ; return (ForeignImport { fd_i_ext = noExtField
- , fd_name = name', fd_sig_ty = ty'
- , fd_fi = spec' }, fvs) }
-
-rnHsForeignDecl (ForeignExport { fd_name = name, fd_sig_ty = ty, fd_fe = spec })
- = do { name' <- lookupLocatedOccRn name
- ; (ty', fvs) <- rnHsSigType (ForeignDeclCtx name) TypeLevel ty
- ; return (ForeignExport { fd_e_ext = noExtField
- , fd_name = name', fd_sig_ty = ty'
- , fd_fe = 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
-
-rnHsForeignDecl (XForeignDecl nec) = noExtCon nec
-
--- | For Windows DLLs we need to know what packages imported symbols are from
--- to generate correct calls. Imported symbols are tagged with the current
--- package, so if they get inlined across a package boundary we'll still
--- know where they're from.
---
-patchForeignImport :: UnitId -> ForeignImport -> ForeignImport
-patchForeignImport unitId (CImport cconv safety fs spec src)
- = CImport cconv safety fs (patchCImportSpec unitId spec) src
-
-patchCImportSpec :: UnitId -> CImportSpec -> CImportSpec
-patchCImportSpec unitId spec
- = case spec of
- CFunction callTarget -> CFunction $ patchCCallTarget unitId callTarget
- _ -> spec
-
-patchCCallTarget :: UnitId -> CCallTarget -> CCallTarget
-patchCCallTarget unitId callTarget =
- case callTarget of
- StaticTarget src label Nothing isFun
- -> StaticTarget src label (Just unitId) isFun
- _ -> callTarget
-
-{-
-*********************************************************
-* *
-\subsection{Instance declarations}
-* *
-*********************************************************
--}
-
-rnSrcInstDecl :: InstDecl GhcPs -> RnM (InstDecl GhcRn, FreeVars)
-rnSrcInstDecl (TyFamInstD { tfid_inst = tfi })
- = do { (tfi', fvs) <- rnTyFamInstDecl NonAssocTyFamEqn tfi
- ; return (TyFamInstD { tfid_ext = noExtField, tfid_inst = tfi' }, fvs) }
-
-rnSrcInstDecl (DataFamInstD { dfid_inst = dfi })
- = do { (dfi', fvs) <- rnDataFamInstDecl NonAssocTyFamEqn dfi
- ; return (DataFamInstD { dfid_ext = noExtField, dfid_inst = dfi' }, fvs) }
-
-rnSrcInstDecl (ClsInstD { cid_inst = cid })
- = do { traceRn "rnSrcIstDecl {" (ppr cid)
- ; (cid', fvs) <- rnClsInstDecl cid
- ; traceRn "rnSrcIstDecl end }" empty
- ; return (ClsInstD { cid_d_ext = noExtField, cid_inst = cid' }, fvs) }
-
-rnSrcInstDecl (XInstDecl nec) = noExtCon nec
-
--- | Warn about non-canonical typeclass instance declarations
---
--- A "non-canonical" instance definition can occur for instances of a
--- class which redundantly defines an operation its superclass
--- provides as well (c.f. `return`/`pure`). In such cases, a canonical
--- instance is one where the subclass inherits its method
--- implementation from its superclass instance (usually the subclass
--- has a default method implementation to that effect). Consequently,
--- a non-canonical instance occurs when this is not the case.
---
--- See also descriptions of 'checkCanonicalMonadInstances' and
--- 'checkCanonicalMonoidInstances'
-checkCanonicalInstances :: Name -> LHsSigType GhcRn -> LHsBinds GhcRn -> RnM ()
-checkCanonicalInstances cls poly_ty mbinds = do
- whenWOptM Opt_WarnNonCanonicalMonadInstances
- checkCanonicalMonadInstances
-
- whenWOptM Opt_WarnNonCanonicalMonoidInstances
- checkCanonicalMonoidInstances
-
- where
- -- | Warn about unsound/non-canonical 'Applicative'/'Monad' instance
- -- declarations. Specifically, the following conditions are verified:
- --
- -- In 'Monad' instances declarations:
- --
- -- * If 'return' is overridden it must be canonical (i.e. @return = pure@)
- -- * If '(>>)' is overridden it must be canonical (i.e. @(>>) = (*>)@)
- --
- -- In 'Applicative' instance declarations:
- --
- -- * Warn if 'pure' is defined backwards (i.e. @pure = return@).
- -- * Warn if '(*>)' is defined backwards (i.e. @(*>) = (>>)@).
- --
- checkCanonicalMonadInstances
- | cls == applicativeClassName = do
- forM_ (bagToList mbinds) $ \(L loc mbind) -> setSrcSpan loc $ do
- case mbind of
- FunBind { fun_id = L _ name
- , fun_matches = mg }
- | name == pureAName, isAliasMG mg == Just returnMName
- -> addWarnNonCanonicalMethod1
- Opt_WarnNonCanonicalMonadInstances "pure" "return"
-
- | name == thenAName, isAliasMG mg == Just thenMName
- -> addWarnNonCanonicalMethod1
- Opt_WarnNonCanonicalMonadInstances "(*>)" "(>>)"
-
- _ -> return ()
-
- | cls == monadClassName = do
- forM_ (bagToList mbinds) $ \(L loc mbind) -> setSrcSpan loc $ do
- case mbind of
- FunBind { fun_id = L _ name
- , fun_matches = mg }
- | name == returnMName, isAliasMG mg /= Just pureAName
- -> addWarnNonCanonicalMethod2
- Opt_WarnNonCanonicalMonadInstances "return" "pure"
-
- | name == thenMName, isAliasMG mg /= Just thenAName
- -> addWarnNonCanonicalMethod2
- Opt_WarnNonCanonicalMonadInstances "(>>)" "(*>)"
-
- _ -> return ()
-
- | otherwise = return ()
-
- -- | Check whether Monoid(mappend) is defined in terms of
- -- Semigroup((<>)) (and not the other way round). Specifically,
- -- the following conditions are verified:
- --
- -- In 'Monoid' instances declarations:
- --
- -- * If 'mappend' is overridden it must be canonical
- -- (i.e. @mappend = (<>)@)
- --
- -- In 'Semigroup' instance declarations:
- --
- -- * Warn if '(<>)' is defined backwards (i.e. @(<>) = mappend@).
- --
- checkCanonicalMonoidInstances
- | cls == semigroupClassName = do
- forM_ (bagToList mbinds) $ \(L loc mbind) -> setSrcSpan loc $ do
- case mbind of
- FunBind { fun_id = L _ name
- , fun_matches = mg }
- | name == sappendName, isAliasMG mg == Just mappendName
- -> addWarnNonCanonicalMethod1
- Opt_WarnNonCanonicalMonoidInstances "(<>)" "mappend"
-
- _ -> return ()
-
- | cls == monoidClassName = do
- forM_ (bagToList mbinds) $ \(L loc mbind) -> setSrcSpan loc $ do
- case mbind of
- FunBind { fun_id = L _ name
- , fun_matches = mg }
- | name == mappendName, isAliasMG mg /= Just sappendName
- -> addWarnNonCanonicalMethod2NoDefault
- Opt_WarnNonCanonicalMonoidInstances "mappend" "(<>)"
-
- _ -> return ()
-
- | otherwise = return ()
-
- -- | test whether MatchGroup represents a trivial \"lhsName = rhsName\"
- -- binding, and return @Just rhsName@ if this is the case
- isAliasMG :: MatchGroup GhcRn (LHsExpr GhcRn) -> Maybe Name
- isAliasMG MG {mg_alts = (L _ [L _ (Match { m_pats = []
- , m_grhss = grhss })])}
- | GRHSs _ [L _ (GRHS _ [] body)] lbinds <- grhss
- , EmptyLocalBinds _ <- unLoc lbinds
- , HsVar _ lrhsName <- unLoc body = Just (unLoc lrhsName)
- isAliasMG _ = Nothing
-
- -- got "lhs = rhs" but expected something different
- addWarnNonCanonicalMethod1 flag lhs rhs = do
- addWarn (Reason flag) $ vcat
- [ text "Noncanonical" <+>
- quotes (text (lhs ++ " = " ++ rhs)) <+>
- text "definition detected"
- , instDeclCtxt1 poly_ty
- , text "Move definition from" <+>
- quotes (text rhs) <+>
- text "to" <+> quotes (text lhs)
- ]
-
- -- expected "lhs = rhs" but got something else
- addWarnNonCanonicalMethod2 flag lhs rhs = do
- addWarn (Reason flag) $ vcat
- [ text "Noncanonical" <+>
- quotes (text lhs) <+>
- text "definition detected"
- , instDeclCtxt1 poly_ty
- , text "Either remove definition for" <+>
- quotes (text lhs) <+> text "or define as" <+>
- quotes (text (lhs ++ " = " ++ rhs))
- ]
-
- -- like above, but method has no default impl
- addWarnNonCanonicalMethod2NoDefault flag lhs rhs = do
- addWarn (Reason flag) $ vcat
- [ text "Noncanonical" <+>
- quotes (text lhs) <+>
- text "definition detected"
- , instDeclCtxt1 poly_ty
- , text "Define as" <+>
- quotes (text (lhs ++ " = " ++ rhs))
- ]
-
- -- stolen from TcInstDcls
- instDeclCtxt1 :: LHsSigType GhcRn -> SDoc
- instDeclCtxt1 hs_inst_ty
- = inst_decl_ctxt (ppr (getLHsInstDeclHead hs_inst_ty))
-
- inst_decl_ctxt :: SDoc -> SDoc
- inst_decl_ctxt doc = hang (text "in the instance declaration for")
- 2 (quotes doc <> text ".")
-
-
-rnClsInstDecl :: ClsInstDecl GhcPs -> RnM (ClsInstDecl GhcRn, FreeVars)
-rnClsInstDecl (ClsInstDecl { cid_poly_ty = inst_ty, cid_binds = mbinds
- , cid_sigs = uprags, cid_tyfam_insts = ats
- , cid_overlap_mode = oflag
- , cid_datafam_insts = adts })
- = do { (inst_ty', inst_fvs)
- <- rnHsSigType (GenericCtx $ text "an instance declaration") TypeLevel inst_ty
- ; let (ktv_names, _, head_ty') = splitLHsInstDeclTy inst_ty'
- ; cls <-
- case hsTyGetAppHead_maybe head_ty' of
- Just (L _ cls) -> pure cls
- Nothing -> do
- -- The instance is malformed. We'd still like
- -- to make *some* progress (rather than failing outright), so
- -- we report an error and continue for as long as we can.
- -- Importantly, this error should be thrown before we reach the
- -- typechecker, lest we encounter different errors that are
- -- hopelessly confusing (such as the one in #16114).
- addErrAt (getLoc (hsSigType inst_ty)) $
- hang (text "Illegal class instance:" <+> quotes (ppr inst_ty))
- 2 (vcat [ text "Class instances must be of the form"
- , nest 2 $ text "context => C ty_1 ... ty_n"
- , text "where" <+> quotes (char 'C')
- <+> text "is a class"
- ])
- pure $ mkUnboundName (mkTcOccFS (fsLit "<class>"))
-
- -- Rename the bindings
- -- The typechecker (not the renamer) checks that all
- -- the bindings are for the right class
- -- (Slightly strangely) when scoped type variables are on, the
- -- forall-d tyvars scope over the method bindings too
- ; (mbinds', uprags', meth_fvs) <- rnMethodBinds False cls ktv_names mbinds uprags
-
- ; checkCanonicalInstances cls inst_ty' mbinds'
-
- -- Rename the associated types, and type signatures
- -- Both need to have the instance type variables in scope
- ; traceRn "rnSrcInstDecl" (ppr inst_ty' $$ ppr ktv_names)
- ; ((ats', adts'), more_fvs)
- <- extendTyVarEnvFVRn ktv_names $
- do { (ats', at_fvs) <- rnATInstDecls rnTyFamInstDecl cls ktv_names ats
- ; (adts', adt_fvs) <- rnATInstDecls rnDataFamInstDecl cls ktv_names adts
- ; return ( (ats', adts'), at_fvs `plusFV` adt_fvs) }
-
- ; let all_fvs = meth_fvs `plusFV` more_fvs
- `plusFV` inst_fvs
- ; return (ClsInstDecl { cid_ext = noExtField
- , cid_poly_ty = inst_ty', cid_binds = mbinds'
- , cid_sigs = uprags', cid_tyfam_insts = ats'
- , cid_overlap_mode = oflag
- , cid_datafam_insts = adts' },
- all_fvs) }
- -- We return the renamed associated data type declarations so
- -- that they can be entered into the list of type declarations
- -- for the binding group, but we also keep a copy in the instance.
- -- The latter is needed for well-formedness checks in the type
- -- checker (eg, to ensure that all ATs of the instance actually
- -- receive a declaration).
- -- NB: Even the copies in the instance declaration carry copies of
- -- the instance context after renaming. This is a bit
- -- strange, but should not matter (and it would be more work
- -- to remove the context).
-rnClsInstDecl (XClsInstDecl nec) = noExtCon nec
-
-rnFamInstEqn :: HsDocContext
- -> AssocTyFamInfo
- -> [Located RdrName] -- Kind variables from the equation's RHS
- -> FamInstEqn GhcPs rhs
- -> (HsDocContext -> rhs -> RnM (rhs', FreeVars))
- -> RnM (FamInstEqn GhcRn rhs', FreeVars)
-rnFamInstEqn doc atfi rhs_kvars
- (HsIB { hsib_body = FamEqn { feqn_tycon = tycon
- , feqn_bndrs = mb_bndrs
- , feqn_pats = pats
- , feqn_fixity = fixity
- , feqn_rhs = payload }}) rn_payload
- = do { let mb_cls = case atfi of
- NonAssocTyFamEqn -> Nothing
- AssocTyFamDeflt cls -> Just cls
- AssocTyFamInst cls _ -> Just cls
- ; tycon' <- lookupFamInstName mb_cls tycon
- ; let pat_kity_vars_with_dups = extractHsTyArgRdrKiTyVarsDup pats
- -- Use the "...Dups" form because it's needed
- -- below to report unused binder on the LHS
-
- -- Implicitly bound variables, empty if we have an explicit 'forall' according
- -- to the "forall-or-nothing" rule.
- ; let imp_vars | isNothing mb_bndrs = nubL pat_kity_vars_with_dups
- | otherwise = []
- ; imp_var_names <- mapM (newTyVarNameRn mb_cls) imp_vars
-
- ; let bndrs = fromMaybe [] mb_bndrs
- bnd_vars = map hsLTyVarLocName bndrs
- payload_kvars = filterOut (`elemRdr` (bnd_vars ++ imp_vars)) rhs_kvars
- -- Make sure to filter out the kind variables that were explicitly
- -- bound in the type patterns.
- ; payload_kvar_names <- mapM (newTyVarNameRn mb_cls) payload_kvars
-
- -- all names not bound in an explict forall
- ; let all_imp_var_names = imp_var_names ++ payload_kvar_names
-
- -- All the free vars of the family patterns
- -- with a sensible binding location
- ; ((bndrs', pats', payload'), fvs)
- <- bindLocalNamesFV all_imp_var_names $
- bindLHsTyVarBndrs doc (Just $ inHsDocContext doc)
- Nothing bndrs $ \bndrs' ->
- -- Note: If we pass mb_cls instead of Nothing here,
- -- bindLHsTyVarBndrs will use class variables for any names
- -- the user meant to bring in scope here. This is an explicit
- -- forall, so we want fresh names, not class variables.
- -- Thus: always pass Nothing
- do { (pats', pat_fvs) <- rnLHsTypeArgs (FamPatCtx tycon) pats
- ; (payload', rhs_fvs) <- rn_payload doc payload
-
- -- Report unused binders on the LHS
- -- See Note [Unused type variables in family instances]
- ; let groups :: [NonEmpty (Located RdrName)]
- groups = equivClasses cmpLocated $
- pat_kity_vars_with_dups
- ; nms_dups <- mapM (lookupOccRn . unLoc) $
- [ tv | (tv :| (_:_)) <- groups ]
- -- Add to the used variables
- -- a) any variables that appear *more than once* on the LHS
- -- e.g. F a Int a = Bool
- -- b) for associated instances, the variables
- -- of the instance decl. See
- -- Note [Unused type variables in family instances]
- ; let nms_used = extendNameSetList rhs_fvs $
- inst_tvs ++ nms_dups
- inst_tvs = case atfi of
- NonAssocTyFamEqn -> []
- AssocTyFamDeflt _ -> []
- AssocTyFamInst _ inst_tvs -> inst_tvs
- all_nms = all_imp_var_names ++ hsLTyVarNames bndrs'
- ; warnUnusedTypePatterns all_nms nms_used
-
- ; return ((bndrs', pats', payload'), rhs_fvs `plusFV` pat_fvs) }
-
- ; let all_fvs = fvs `addOneFV` unLoc tycon'
- -- type instance => use, hence addOneFV
-
- ; return (HsIB { hsib_ext = all_imp_var_names -- Note [Wildcards in family instances]
- , hsib_body
- = FamEqn { feqn_ext = noExtField
- , feqn_tycon = tycon'
- , feqn_bndrs = bndrs' <$ mb_bndrs
- , feqn_pats = pats'
- , feqn_fixity = fixity
- , feqn_rhs = payload' } },
- all_fvs) }
-rnFamInstEqn _ _ _ (HsIB _ (XFamEqn nec)) _ = noExtCon nec
-rnFamInstEqn _ _ _ (XHsImplicitBndrs nec) _ = noExtCon nec
-
-rnTyFamInstDecl :: AssocTyFamInfo
- -> TyFamInstDecl GhcPs
- -> RnM (TyFamInstDecl GhcRn, FreeVars)
-rnTyFamInstDecl atfi (TyFamInstDecl { tfid_eqn = eqn })
- = do { (eqn', fvs) <- rnTyFamInstEqn atfi NotClosedTyFam eqn
- ; return (TyFamInstDecl { tfid_eqn = eqn' }, fvs) }
-
--- | Tracks whether we are renaming:
---
--- 1. A type family equation that is not associated
--- with a parent type class ('NonAssocTyFamEqn')
---
--- 2. An associated type family default delcaration ('AssocTyFamDeflt')
---
--- 3. An associated type family instance declaration ('AssocTyFamInst')
-data AssocTyFamInfo
- = NonAssocTyFamEqn
- | AssocTyFamDeflt Name -- Name of the parent class
- | AssocTyFamInst Name -- Name of the parent class
- [Name] -- Names of the tyvars of the parent instance decl
-
--- | Tracks whether we are renaming an equation in a closed type family
--- equation ('ClosedTyFam') or not ('NotClosedTyFam').
-data ClosedTyFamInfo
- = NotClosedTyFam
- | ClosedTyFam (Located RdrName) Name
- -- The names (RdrName and Name) of the closed type family
-
-rnTyFamInstEqn :: AssocTyFamInfo
- -> ClosedTyFamInfo
- -> TyFamInstEqn GhcPs
- -> RnM (TyFamInstEqn GhcRn, FreeVars)
-rnTyFamInstEqn atfi ctf_info
- eqn@(HsIB { hsib_body = FamEqn { feqn_tycon = tycon
- , feqn_rhs = rhs }})
- = do { let rhs_kvs = extractHsTyRdrTyVarsKindVars rhs
- ; (eqn'@(HsIB { hsib_body =
- FamEqn { feqn_tycon = L _ tycon' }}), fvs)
- <- rnFamInstEqn (TySynCtx tycon) atfi rhs_kvs eqn rnTySyn
- ; case ctf_info of
- NotClosedTyFam -> pure ()
- ClosedTyFam fam_rdr_name fam_name ->
- checkTc (fam_name == tycon') $
- withHsDocContext (TyFamilyCtx fam_rdr_name) $
- wrongTyFamName fam_name tycon'
- ; pure (eqn', fvs) }
-rnTyFamInstEqn _ _ (HsIB _ (XFamEqn nec)) = noExtCon nec
-rnTyFamInstEqn _ _ (XHsImplicitBndrs nec) = noExtCon nec
-
-rnTyFamDefltDecl :: Name
- -> TyFamDefltDecl GhcPs
- -> RnM (TyFamDefltDecl GhcRn, FreeVars)
-rnTyFamDefltDecl cls = rnTyFamInstDecl (AssocTyFamDeflt cls)
-
-rnDataFamInstDecl :: AssocTyFamInfo
- -> DataFamInstDecl GhcPs
- -> RnM (DataFamInstDecl GhcRn, FreeVars)
-rnDataFamInstDecl atfi (DataFamInstDecl { dfid_eqn = eqn@(HsIB { hsib_body =
- FamEqn { feqn_tycon = tycon
- , feqn_rhs = rhs }})})
- = do { let rhs_kvs = extractDataDefnKindVars rhs
- ; (eqn', fvs) <-
- rnFamInstEqn (TyDataCtx tycon) atfi rhs_kvs eqn rnDataDefn
- ; return (DataFamInstDecl { dfid_eqn = eqn' }, fvs) }
-rnDataFamInstDecl _ (DataFamInstDecl (HsIB _ (XFamEqn nec)))
- = noExtCon nec
-rnDataFamInstDecl _ (DataFamInstDecl (XHsImplicitBndrs nec))
- = noExtCon nec
-
--- Renaming of the associated types in instances.
-
--- Rename associated type family decl in class
-rnATDecls :: Name -- Class
- -> [LFamilyDecl GhcPs]
- -> RnM ([LFamilyDecl GhcRn], FreeVars)
-rnATDecls cls at_decls
- = rnList (rnFamDecl (Just cls)) at_decls
-
-rnATInstDecls :: (AssocTyFamInfo -> -- The function that renames
- decl GhcPs -> -- an instance. rnTyFamInstDecl
- RnM (decl GhcRn, FreeVars)) -- or rnDataFamInstDecl
- -> Name -- Class
- -> [Name]
- -> [Located (decl GhcPs)]
- -> RnM ([Located (decl GhcRn)], FreeVars)
--- Used for data and type family defaults in a class decl
--- and the family instance declarations in an instance
---
--- NB: We allow duplicate associated-type decls;
--- See Note [Associated type instances] in TcInstDcls
-rnATInstDecls rnFun cls tv_ns at_insts
- = rnList (rnFun (AssocTyFamInst cls tv_ns)) at_insts
- -- See Note [Renaming associated types]
-
-{- Note [Wildcards in family instances]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Wild cards can be used in type/data family instance declarations to indicate
-that the name of a type variable doesn't matter. Each wild card will be
-replaced with a new unique type variable. For instance:
-
- type family F a b :: *
- type instance F Int _ = Int
-
-is the same as
-
- type family F a b :: *
- type instance F Int b = Int
-
-This is implemented as follows: Unnamed wildcards remain unchanged after
-the renamer, and then given fresh meta-variables during typechecking, and
-it is handled pretty much the same way as the ones in partial type signatures.
-We however don't want to emit hole constraints on wildcards in family
-instances, so we turn on PartialTypeSignatures and turn off warning flag to
-let typechecker know this.
-See related Note [Wildcards in visible kind application] in TcHsType.hs
-
-Note [Unused type variables in family instances]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When the flag -fwarn-unused-type-patterns is on, the compiler reports
-warnings about unused type variables in type-family instances. A
-tpye variable is considered used (i.e. cannot be turned into a wildcard)
-when
-
- * it occurs on the RHS of the family instance
- e.g. type instance F a b = a -- a is used on the RHS
-
- * it occurs multiple times in the patterns on the LHS
- e.g. type instance F a a = Int -- a appears more than once on LHS
-
- * it is one of the instance-decl variables, for associated types
- e.g. instance C (a,b) where
- type T (a,b) = a
- Here the type pattern in the type instance must be the same as that
- for the class instance, so
- type T (a,_) = a
- would be rejected. So we should not complain about an unused variable b
-
-As usual, the warnings are not reported for type variables with names
-beginning with an underscore.
-
-Extra-constraints wild cards are not supported in type/data family
-instance declarations.
-
-Relevant tickets: #3699, #10586, #10982 and #11451.
-
-Note [Renaming associated types]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Check that the RHS of the decl mentions only type variables that are explicitly
-bound on the LHS. For example, this is not ok
- class C a b where
- type F a x :: *
- instance C (p,q) r where
- type F (p,q) x = (x, r) -- BAD: mentions 'r'
-c.f. #5515
-
-Kind variables, on the other hand, are allowed to be implicitly or explicitly
-bound. As examples, this (#9574) is acceptable:
- class Funct f where
- type Codomain f :: *
- instance Funct ('KProxy :: KProxy o) where
- -- o is implicitly bound by the kind signature
- -- of the LHS type pattern ('KProxy)
- type Codomain 'KProxy = NatTr (Proxy :: o -> *)
-And this (#14131) is also acceptable:
- data family Nat :: k -> k -> *
- -- k is implicitly bound by an invisible kind pattern
- newtype instance Nat :: (k -> *) -> (k -> *) -> * where
- Nat :: (forall xx. f xx -> g xx) -> Nat f g
-We could choose to disallow this, but then associated type families would not
-be able to be as expressive as top-level type synonyms. For example, this type
-synonym definition is allowed:
- type T = (Nothing :: Maybe a)
-So for parity with type synonyms, we also allow:
- type family T :: Maybe a
- type instance T = (Nothing :: Maybe a)
-
-All this applies only for *instance* declarations. In *class*
-declarations there is no RHS to worry about, and the class variables
-can all be in scope (#5862):
- class Category (x :: k -> k -> *) where
- type Ob x :: k -> Constraint
- id :: Ob x a => x a a
- (.) :: (Ob x a, Ob x b, Ob x c) => x b c -> x a b -> x a c
-Here 'k' is in scope in the kind signature, just like 'x'.
-
-Although type family equations can bind type variables with explicit foralls,
-it need not be the case that all variables that appear on the RHS must be bound
-by a forall. For instance, the following is acceptable:
-
- class C a where
- type T a b
- instance C (Maybe a) where
- type forall b. T (Maybe a) b = Either a b
-
-Even though `a` is not bound by the forall, this is still accepted because `a`
-was previously bound by the `instance C (Maybe a)` part. (see #16116).
-
-In each case, the function which detects improperly bound variables on the RHS
-is TcValidity.checkValidFamPats.
--}
-
-
-{-
-*********************************************************
-* *
-\subsection{Stand-alone deriving declarations}
-* *
-*********************************************************
--}
-
-rnSrcDerivDecl :: DerivDecl GhcPs -> RnM (DerivDecl GhcRn, FreeVars)
-rnSrcDerivDecl (DerivDecl _ ty mds overlap)
- = do { standalone_deriv_ok <- xoptM LangExt.StandaloneDeriving
- ; unless standalone_deriv_ok (addErr standaloneDerivErr)
- ; (mds', ty', fvs)
- <- rnLDerivStrategy DerivDeclCtx mds $
- rnHsSigWcType BindUnlessForall DerivDeclCtx ty
- ; warnNoDerivStrat mds' loc
- ; return (DerivDecl noExtField ty' mds' overlap, fvs) }
- where
- loc = getLoc $ hsib_body $ hswc_body ty
-rnSrcDerivDecl (XDerivDecl nec) = noExtCon nec
-
-standaloneDerivErr :: SDoc
-standaloneDerivErr
- = hang (text "Illegal standalone deriving declaration")
- 2 (text "Use StandaloneDeriving to enable this extension")
-
-{-
-*********************************************************
-* *
-\subsection{Rules}
-* *
-*********************************************************
--}
-
-rnHsRuleDecls :: RuleDecls GhcPs -> RnM (RuleDecls GhcRn, FreeVars)
-rnHsRuleDecls (HsRules { rds_src = src
- , rds_rules = rules })
- = do { (rn_rules,fvs) <- rnList rnHsRuleDecl rules
- ; return (HsRules { rds_ext = noExtField
- , rds_src = src
- , rds_rules = rn_rules }, fvs) }
-rnHsRuleDecls (XRuleDecls nec) = noExtCon nec
-
-rnHsRuleDecl :: RuleDecl GhcPs -> RnM (RuleDecl GhcRn, FreeVars)
-rnHsRuleDecl (HsRule { rd_name = rule_name
- , rd_act = act
- , rd_tyvs = tyvs
- , rd_tmvs = tmvs
- , rd_lhs = lhs
- , rd_rhs = rhs })
- = do { let rdr_names_w_loc = map (get_var . unLoc) tmvs
- ; checkDupRdrNames rdr_names_w_loc
- ; checkShadowedRdrNames rdr_names_w_loc
- ; names <- newLocalBndrsRn rdr_names_w_loc
- ; let doc = RuleCtx (snd $ unLoc rule_name)
- ; bindRuleTyVars doc in_rule tyvs $ \ tyvs' ->
- bindRuleTmVars doc tyvs' tmvs names $ \ tmvs' ->
- do { (lhs', fv_lhs') <- rnLExpr lhs
- ; (rhs', fv_rhs') <- rnLExpr rhs
- ; checkValidRule (snd $ unLoc rule_name) names lhs' fv_lhs'
- ; return (HsRule { rd_ext = HsRuleRn fv_lhs' fv_rhs'
- , rd_name = rule_name
- , rd_act = act
- , rd_tyvs = tyvs'
- , rd_tmvs = tmvs'
- , rd_lhs = lhs'
- , rd_rhs = rhs' }, fv_lhs' `plusFV` fv_rhs') } }
- where
- get_var (RuleBndrSig _ v _) = v
- get_var (RuleBndr _ v) = v
- get_var (XRuleBndr nec) = noExtCon nec
- in_rule = text "in the rule" <+> pprFullRuleName rule_name
-rnHsRuleDecl (XRuleDecl nec) = noExtCon nec
-
-bindRuleTmVars :: HsDocContext -> Maybe ty_bndrs
- -> [LRuleBndr GhcPs] -> [Name]
- -> ([LRuleBndr GhcRn] -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
-bindRuleTmVars doc tyvs vars names thing_inside
- = go vars names $ \ vars' ->
- bindLocalNamesFV names (thing_inside vars')
- where
- go ((L l (RuleBndr _ (L loc _))) : vars) (n : ns) thing_inside
- = go vars ns $ \ vars' ->
- thing_inside (L l (RuleBndr noExtField (L loc n)) : vars')
-
- go ((L l (RuleBndrSig _ (L loc _) bsig)) : vars)
- (n : ns) thing_inside
- = rnHsSigWcTypeScoped bind_free_tvs doc bsig $ \ bsig' ->
- go vars ns $ \ vars' ->
- thing_inside (L l (RuleBndrSig noExtField (L loc n) bsig') : vars')
-
- go [] [] thing_inside = thing_inside []
- go vars names _ = pprPanic "bindRuleVars" (ppr vars $$ ppr names)
-
- bind_free_tvs = case tyvs of Nothing -> AlwaysBind
- Just _ -> NeverBind
-
-bindRuleTyVars :: HsDocContext -> SDoc -> Maybe [LHsTyVarBndr GhcPs]
- -> (Maybe [LHsTyVarBndr GhcRn] -> RnM (b, FreeVars))
- -> RnM (b, FreeVars)
-bindRuleTyVars doc in_doc (Just bndrs) thing_inside
- = bindLHsTyVarBndrs doc (Just in_doc) Nothing bndrs (thing_inside . Just)
-bindRuleTyVars _ _ _ thing_inside = thing_inside Nothing
-
-{-
-Note [Rule LHS validity checking]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Check the shape of a transformation rule LHS. Currently we only allow
-LHSs of the form @(f e1 .. en)@, where @f@ is not one of the
-@forall@'d variables.
-
-We used restrict the form of the 'ei' to prevent you writing rules
-with LHSs with a complicated desugaring (and hence unlikely to match);
-(e.g. a case expression is not allowed: too elaborate.)
-
-But there are legitimate non-trivial args ei, like sections and
-lambdas. So it seems simmpler not to check at all, and that is why
-check_e is commented out.
--}
-
-checkValidRule :: FastString -> [Name] -> LHsExpr GhcRn -> NameSet -> RnM ()
-checkValidRule rule_name ids lhs' fv_lhs'
- = do { -- Check for the form of the LHS
- case (validRuleLhs ids lhs') of
- Nothing -> return ()
- Just bad -> failWithTc (badRuleLhsErr rule_name lhs' bad)
-
- -- Check that LHS vars are all bound
- ; let bad_vars = [var | var <- ids, not (var `elemNameSet` fv_lhs')]
- ; mapM_ (addErr . badRuleVar rule_name) bad_vars }
-
-validRuleLhs :: [Name] -> LHsExpr GhcRn -> Maybe (HsExpr GhcRn)
--- Nothing => OK
--- Just e => Not ok, and e is the offending sub-expression
-validRuleLhs foralls lhs
- = checkl lhs
- where
- checkl = check . unLoc
-
- check (OpApp _ e1 op e2) = checkl op `mplus` checkl_e e1
- `mplus` checkl_e e2
- check (HsApp _ e1 e2) = checkl e1 `mplus` checkl_e e2
- check (HsAppType _ e _) = checkl e
- check (HsVar _ lv)
- | (unLoc lv) `notElem` foralls = Nothing
- check other = Just other -- Failure
-
- -- Check an argument
- checkl_e _ = Nothing
- -- Was (check_e e); see Note [Rule LHS validity checking]
-
-{- Commented out; see Note [Rule LHS validity checking] above
- check_e (HsVar v) = Nothing
- check_e (HsPar e) = checkl_e e
- check_e (HsLit e) = Nothing
- check_e (HsOverLit e) = Nothing
-
- check_e (OpApp e1 op _ e2) = checkl_e e1 `mplus` checkl_e op `mplus` checkl_e e2
- check_e (HsApp e1 e2) = checkl_e e1 `mplus` checkl_e e2
- check_e (NegApp e _) = checkl_e e
- check_e (ExplicitList _ es) = checkl_es es
- check_e other = Just other -- Fails
-
- checkl_es es = foldr (mplus . checkl_e) Nothing es
--}
-
-badRuleVar :: FastString -> Name -> SDoc
-badRuleVar name var
- = sep [text "Rule" <+> doubleQuotes (ftext name) <> colon,
- text "Forall'd variable" <+> quotes (ppr var) <+>
- text "does not appear on left hand side"]
-
-badRuleLhsErr :: FastString -> LHsExpr GhcRn -> HsExpr GhcRn -> SDoc
-badRuleLhsErr name lhs bad_e
- = sep [text "Rule" <+> pprRuleName name <> colon,
- nest 2 (vcat [err,
- text "in left-hand side:" <+> ppr lhs])]
- $$
- text "LHS must be of form (f e1 .. en) where f is not forall'd"
- where
- err = case bad_e of
- HsUnboundVar _ uv -> notInScopeErr (mkRdrUnqual uv)
- _ -> text "Illegal expression:" <+> ppr bad_e
-
-{- **************************************************************
- * *
- Renaming type, class, instance and role declarations
-* *
-*****************************************************************
-
-@rnTyDecl@ uses the `global name function' to create a new type
-declaration in which local names have been replaced by their original
-names, reporting any unknown names.
-
-Renaming type variables is a pain. Because they now contain uniques,
-it is necessary to pass in an association list which maps a parsed
-tyvar to its @Name@ representation.
-In some cases (type signatures of values),
-it is even necessary to go over the type first
-in order to get the set of tyvars used by it, make an assoc list,
-and then go over it again to rename the tyvars!
-However, we can also do some scoping checks at the same time.
-
-Note [Dependency analysis of type, class, and instance decls]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A TyClGroup represents a strongly connected components of
-type/class/instance decls, together with the role annotations for the
-type/class declarations. The renamer uses strongly connected
-comoponent analysis to build these groups. We do this for a number of
-reasons:
-
-* Improve kind error messages. Consider
-
- data T f a = MkT f a
- data S f a = MkS f (T f a)
-
- This has a kind error, but the error message is better if you
- check T first, (fixing its kind) and *then* S. If you do kind
- inference together, you might get an error reported in S, which
- is jolly confusing. See #4875
-
-
-* Increase kind polymorphism. See TcTyClsDecls
- Note [Grouping of type and class declarations]
-
-Why do the instance declarations participate? At least two reasons
-
-* Consider (#11348)
-
- type family F a
- type instance F Int = Bool
-
- data R = MkR (F Int)
-
- type Foo = 'MkR 'True
-
- For Foo to kind-check we need to know that (F Int) ~ Bool. But we won't
- know that unless we've looked at the type instance declaration for F
- before kind-checking Foo.
-
-* Another example is this (#3990).
-
- data family Complex a
- data instance Complex Double = CD {-# UNPACK #-} !Double
- {-# UNPACK #-} !Double
-
- data T = T {-# UNPACK #-} !(Complex Double)
-
- Here, to generate the right kind of unpacked implementation for T,
- we must have access to the 'data instance' declaration.
-
-* Things become more complicated when we introduce transitive
- dependencies through imported definitions, like in this scenario:
-
- A.hs
- type family Closed (t :: Type) :: Type where
- Closed t = Open t
-
- type family Open (t :: Type) :: Type
-
- B.hs
- data Q where
- Q :: Closed Bool -> Q
-
- type instance Open Int = Bool
-
- type S = 'Q 'True
-
- Somehow, we must ensure that the instance Open Int = Bool is checked before
- the type synonym S. While we know that S depends upon 'Q depends upon Closed,
- we have no idea that Closed depends upon Open!
-
- To accommodate for these situations, we ensure that an instance is checked
- before every @TyClDecl@ on which it does not depend. That's to say, instances
- are checked as early as possible in @tcTyAndClassDecls@.
-
-------------------------------------
-So much for WHY. What about HOW? It's pretty easy:
-
-(1) Rename the type/class, instance, and role declarations
- individually
-
-(2) Do strongly-connected component analysis of the type/class decls,
- We'll make a TyClGroup for each SCC
-
- In this step we treat a reference to a (promoted) data constructor
- K as a dependency on its parent type. Thus
- data T = K1 | K2
- data S = MkS (Proxy 'K1)
- Here S depends on 'K1 and hence on its parent T.
-
- In this step we ignore instances; see
- Note [No dependencies on data instances]
-
-(3) Attach roles to the appropriate SCC
-
-(4) Attach instances to the appropriate SCC.
- We add an instance decl to SCC when:
- all its free types/classes are bound in this SCC or earlier ones
-
-(5) We make an initial TyClGroup, with empty group_tyclds, for any
- (orphan) instances that affect only imported types/classes
-
-Steps (3) and (4) are done by the (mapAccumL mk_group) call.
-
-Note [No dependencies on data instances]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider this
- data family D a
- data instance D Int = D1
- data S = MkS (Proxy 'D1)
-
-Here the declaration of S depends on the /data instance/ declaration
-for 'D Int'. That makes things a lot more complicated, especially
-if the data instance is an associated type of an enclosing class instance.
-(And the class instance might have several associated type instances
-with different dependency structure!)
-
-Ugh. For now we simply don't allow promotion of data constructors for
-data instances. See Note [AFamDataCon: not promoting data family
-constructors] in TcEnv
--}
-
-
-rnTyClDecls :: [TyClGroup GhcPs]
- -> RnM ([TyClGroup GhcRn], FreeVars)
--- Rename the declarations and do dependency analysis on them
-rnTyClDecls tycl_ds
- = do { -- Rename the type/class, instance, and role declaraations
- ; tycls_w_fvs <- mapM (wrapLocFstM rnTyClDecl) (tyClGroupTyClDecls tycl_ds)
- ; let tc_names = mkNameSet (map (tcdName . unLoc . fst) tycls_w_fvs)
- ; kisigs_w_fvs <- rnStandaloneKindSignatures tc_names (tyClGroupKindSigs tycl_ds)
- ; instds_w_fvs <- mapM (wrapLocFstM rnSrcInstDecl) (tyClGroupInstDecls tycl_ds)
- ; role_annots <- rnRoleAnnots tc_names (tyClGroupRoleDecls tycl_ds)
-
- -- Do SCC analysis on the type/class decls
- ; rdr_env <- getGlobalRdrEnv
- ; let tycl_sccs = depAnalTyClDecls rdr_env kisig_fv_env tycls_w_fvs
- role_annot_env = mkRoleAnnotEnv role_annots
- (kisig_env, kisig_fv_env) = mkKindSig_fv_env kisigs_w_fvs
-
- inst_ds_map = mkInstDeclFreeVarsMap rdr_env tc_names instds_w_fvs
- (init_inst_ds, rest_inst_ds) = getInsts [] inst_ds_map
-
- first_group
- | null init_inst_ds = []
- | otherwise = [TyClGroup { group_ext = noExtField
- , group_tyclds = []
- , group_kisigs = []
- , group_roles = []
- , group_instds = init_inst_ds }]
-
- (final_inst_ds, groups)
- = mapAccumL (mk_group role_annot_env kisig_env) rest_inst_ds tycl_sccs
-
- all_fvs = foldr (plusFV . snd) emptyFVs tycls_w_fvs `plusFV`
- foldr (plusFV . snd) emptyFVs instds_w_fvs `plusFV`
- foldr (plusFV . snd) emptyFVs kisigs_w_fvs
-
- all_groups = first_group ++ groups
-
- ; MASSERT2( null final_inst_ds, ppr instds_w_fvs $$ ppr inst_ds_map
- $$ ppr (flattenSCCs tycl_sccs) $$ ppr final_inst_ds )
-
- ; traceRn "rnTycl dependency analysis made groups" (ppr all_groups)
- ; return (all_groups, all_fvs) }
- where
- mk_group :: RoleAnnotEnv
- -> KindSigEnv
- -> InstDeclFreeVarsMap
- -> SCC (LTyClDecl GhcRn)
- -> (InstDeclFreeVarsMap, TyClGroup GhcRn)
- mk_group role_env kisig_env inst_map scc
- = (inst_map', group)
- where
- tycl_ds = flattenSCC scc
- bndrs = map (tcdName . unLoc) tycl_ds
- roles = getRoleAnnots bndrs role_env
- kisigs = getKindSigs bndrs kisig_env
- (inst_ds, inst_map') = getInsts bndrs inst_map
- group = TyClGroup { group_ext = noExtField
- , group_tyclds = tycl_ds
- , group_kisigs = kisigs
- , group_roles = roles
- , group_instds = inst_ds }
-
--- | Free variables of standalone kind signatures.
-newtype KindSig_FV_Env = KindSig_FV_Env (NameEnv FreeVars)
-
-lookupKindSig_FV_Env :: KindSig_FV_Env -> Name -> FreeVars
-lookupKindSig_FV_Env (KindSig_FV_Env e) name
- = fromMaybe emptyFVs (lookupNameEnv e name)
-
--- | Standalone kind signatures.
-type KindSigEnv = NameEnv (LStandaloneKindSig GhcRn)
-
-mkKindSig_fv_env :: [(LStandaloneKindSig GhcRn, FreeVars)] -> (KindSigEnv, KindSig_FV_Env)
-mkKindSig_fv_env kisigs_w_fvs = (kisig_env, kisig_fv_env)
- where
- kisig_env = mapNameEnv fst compound_env
- kisig_fv_env = KindSig_FV_Env (mapNameEnv snd compound_env)
- compound_env :: NameEnv (LStandaloneKindSig GhcRn, FreeVars)
- = mkNameEnvWith (standaloneKindSigName . unLoc . fst) kisigs_w_fvs
-
-getKindSigs :: [Name] -> KindSigEnv -> [LStandaloneKindSig GhcRn]
-getKindSigs bndrs kisig_env = mapMaybe (lookupNameEnv kisig_env) bndrs
-
-rnStandaloneKindSignatures
- :: NameSet -- names of types and classes in the current TyClGroup
- -> [LStandaloneKindSig GhcPs]
- -> RnM [(LStandaloneKindSig GhcRn, FreeVars)]
-rnStandaloneKindSignatures tc_names kisigs
- = do { let (no_dups, dup_kisigs) = removeDups (compare `on` get_name) kisigs
- get_name = standaloneKindSigName . unLoc
- ; mapM_ dupKindSig_Err dup_kisigs
- ; mapM (wrapLocFstM (rnStandaloneKindSignature tc_names)) no_dups
- }
-
-rnStandaloneKindSignature
- :: NameSet -- names of types and classes in the current TyClGroup
- -> StandaloneKindSig GhcPs
- -> RnM (StandaloneKindSig GhcRn, FreeVars)
-rnStandaloneKindSignature tc_names (StandaloneKindSig _ v ki)
- = do { standalone_ki_sig_ok <- xoptM LangExt.StandaloneKindSignatures
- ; unless standalone_ki_sig_ok $ addErr standaloneKiSigErr
- ; new_v <- lookupSigCtxtOccRn (TopSigCtxt tc_names) (text "standalone kind signature") v
- ; let doc = StandaloneKindSigCtx (ppr v)
- ; (new_ki, fvs) <- rnHsSigType doc KindLevel ki
- ; return (StandaloneKindSig noExtField new_v new_ki, fvs)
- }
- where
- standaloneKiSigErr :: SDoc
- standaloneKiSigErr =
- hang (text "Illegal standalone kind signature")
- 2 (text "Did you mean to enable StandaloneKindSignatures?")
-rnStandaloneKindSignature _ (XStandaloneKindSig nec) = noExtCon nec
-
-depAnalTyClDecls :: GlobalRdrEnv
- -> KindSig_FV_Env
- -> [(LTyClDecl GhcRn, FreeVars)]
- -> [SCC (LTyClDecl GhcRn)]
--- See Note [Dependency analysis of type, class, and instance decls]
-depAnalTyClDecls rdr_env kisig_fv_env ds_w_fvs
- = stronglyConnCompFromEdgedVerticesUniq edges
- where
- edges :: [ Node Name (LTyClDecl GhcRn) ]
- edges = [ DigraphNode d name (map (getParent rdr_env) (nonDetEltsUniqSet deps))
- | (d, fvs) <- ds_w_fvs,
- let { name = tcdName (unLoc d)
- ; kisig_fvs = lookupKindSig_FV_Env kisig_fv_env name
- ; deps = fvs `plusFV` kisig_fvs
- }
- ]
- -- It's OK to use nonDetEltsUFM here as
- -- stronglyConnCompFromEdgedVertices is still deterministic
- -- even if the edges are in nondeterministic order as explained
- -- in Note [Deterministic SCC] in Digraph.
-
-toParents :: GlobalRdrEnv -> NameSet -> NameSet
-toParents rdr_env ns
- = nonDetFoldUniqSet add emptyNameSet ns
- -- It's OK to use nonDetFoldUFM because we immediately forget the
- -- ordering by creating a set
- where
- add n s = extendNameSet s (getParent rdr_env n)
-
-getParent :: GlobalRdrEnv -> Name -> Name
-getParent rdr_env n
- = case lookupGRE_Name rdr_env n of
- Just gre -> case gre_par gre of
- ParentIs { par_is = p } -> p
- FldParent { par_is = p } -> p
- _ -> n
- Nothing -> n
-
-
-{- ******************************************************
-* *
- Role annotations
-* *
-****************************************************** -}
-
--- | Renames role annotations, returning them as the values in a NameEnv
--- and checks for duplicate role annotations.
--- It is quite convenient to do both of these in the same place.
--- See also Note [Role annotations in the renamer]
-rnRoleAnnots :: NameSet
- -> [LRoleAnnotDecl GhcPs]
- -> RnM [LRoleAnnotDecl GhcRn]
-rnRoleAnnots tc_names role_annots
- = do { -- Check for duplicates *before* renaming, to avoid
- -- lumping together all the unboundNames
- let (no_dups, dup_annots) = removeDups (compare `on` get_name) role_annots
- get_name = roleAnnotDeclName . unLoc
- ; mapM_ dupRoleAnnotErr dup_annots
- ; mapM (wrapLocM rn_role_annot1) no_dups }
- where
- rn_role_annot1 (RoleAnnotDecl _ tycon roles)
- = do { -- the name is an *occurrence*, but look it up only in the
- -- decls defined in this group (see #10263)
- tycon' <- lookupSigCtxtOccRn (RoleAnnotCtxt tc_names)
- (text "role annotation")
- tycon
- ; return $ RoleAnnotDecl noExtField tycon' roles }
- rn_role_annot1 (XRoleAnnotDecl nec) = noExtCon nec
-
-dupRoleAnnotErr :: NonEmpty (LRoleAnnotDecl GhcPs) -> RnM ()
-dupRoleAnnotErr list
- = addErrAt loc $
- hang (text "Duplicate role annotations for" <+>
- quotes (ppr $ roleAnnotDeclName first_decl) <> colon)
- 2 (vcat $ map pp_role_annot $ NE.toList sorted_list)
- where
- sorted_list = NE.sortBy cmp_annot list
- ((L loc first_decl) :| _) = sorted_list
-
- pp_role_annot (L loc decl) = hang (ppr decl)
- 4 (text "-- written at" <+> ppr loc)
-
- cmp_annot (L loc1 _) (L loc2 _) = loc1 `compare` loc2
-
-dupKindSig_Err :: NonEmpty (LStandaloneKindSig GhcPs) -> RnM ()
-dupKindSig_Err list
- = addErrAt loc $
- hang (text "Duplicate standalone kind signatures for" <+>
- quotes (ppr $ standaloneKindSigName first_decl) <> colon)
- 2 (vcat $ map pp_kisig $ NE.toList sorted_list)
- where
- sorted_list = NE.sortBy cmp_loc list
- ((L loc first_decl) :| _) = sorted_list
-
- pp_kisig (L loc decl) =
- hang (ppr decl) 4 (text "-- written at" <+> ppr loc)
-
- cmp_loc (L loc1 _) (L loc2 _) = loc1 `compare` loc2
-
-{- Note [Role annotations in the renamer]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We must ensure that a type's role annotation is put in the same group as the
-proper type declaration. This is because role annotations are needed during
-type-checking when creating the type's TyCon. So, rnRoleAnnots builds a
-NameEnv (LRoleAnnotDecl Name) that maps a name to a role annotation for that
-type, if any. Then, this map can be used to add the role annotations to the
-groups after dependency analysis.
-
-This process checks for duplicate role annotations, where we must be careful
-to do the check *before* renaming to avoid calling all unbound names duplicates
-of one another.
-
-The renaming process, as usual, might identify and report errors for unbound
-names. This is done by using lookupSigCtxtOccRn in rnRoleAnnots (using
-lookupGlobalOccRn led to #8485).
--}
-
-
-{- ******************************************************
-* *
- Dependency info for instances
-* *
-****************************************************** -}
-
-----------------------------------------------------------
--- | 'InstDeclFreeVarsMap is an association of an
--- @InstDecl@ with @FreeVars@. The @FreeVars@ are
--- the tycon names that are both
--- a) free in the instance declaration
--- b) bound by this group of type/class/instance decls
-type InstDeclFreeVarsMap = [(LInstDecl GhcRn, FreeVars)]
-
--- | Construct an @InstDeclFreeVarsMap@ by eliminating any @Name@s from the
--- @FreeVars@ which are *not* the binders of a @TyClDecl@.
-mkInstDeclFreeVarsMap :: GlobalRdrEnv
- -> NameSet
- -> [(LInstDecl GhcRn, FreeVars)]
- -> InstDeclFreeVarsMap
-mkInstDeclFreeVarsMap rdr_env tycl_bndrs inst_ds_fvs
- = [ (inst_decl, toParents rdr_env fvs `intersectFVs` tycl_bndrs)
- | (inst_decl, fvs) <- inst_ds_fvs ]
-
--- | Get the @LInstDecl@s which have empty @FreeVars@ sets, and the
--- @InstDeclFreeVarsMap@ with these entries removed.
--- We call (getInsts tcs instd_map) when we've completed the declarations
--- for 'tcs'. The call returns (inst_decls, instd_map'), where
--- inst_decls are the instance declarations all of
--- whose free vars are now defined
--- instd_map' is the inst-decl map with 'tcs' removed from
--- the free-var set
-getInsts :: [Name] -> InstDeclFreeVarsMap
- -> ([LInstDecl GhcRn], InstDeclFreeVarsMap)
-getInsts bndrs inst_decl_map
- = partitionWith pick_me inst_decl_map
- where
- pick_me :: (LInstDecl GhcRn, FreeVars)
- -> Either (LInstDecl GhcRn) (LInstDecl GhcRn, FreeVars)
- pick_me (decl, fvs)
- | isEmptyNameSet depleted_fvs = Left decl
- | otherwise = Right (decl, depleted_fvs)
- where
- depleted_fvs = delFVs bndrs fvs
-
-{- ******************************************************
-* *
- Renaming a type or class declaration
-* *
-****************************************************** -}
-
-rnTyClDecl :: TyClDecl GhcPs
- -> RnM (TyClDecl GhcRn, FreeVars)
-
--- All flavours of top-level type family declarations ("type family", "newtype
--- family", and "data family")
-rnTyClDecl (FamDecl { tcdFam = fam })
- = do { (fam', fvs) <- rnFamDecl Nothing fam
- ; return (FamDecl noExtField fam', fvs) }
-
-rnTyClDecl (SynDecl { tcdLName = tycon, tcdTyVars = tyvars,
- tcdFixity = fixity, tcdRhs = rhs })
- = do { tycon' <- lookupLocatedTopBndrRn tycon
- ; let kvs = extractHsTyRdrTyVarsKindVars rhs
- doc = TySynCtx tycon
- ; traceRn "rntycl-ty" (ppr tycon <+> ppr kvs)
- ; bindHsQTyVars doc Nothing Nothing kvs tyvars $ \ tyvars' _ ->
- do { (rhs', fvs) <- rnTySyn doc rhs
- ; return (SynDecl { tcdLName = tycon', tcdTyVars = tyvars'
- , tcdFixity = fixity
- , tcdRhs = rhs', tcdSExt = fvs }, fvs) } }
-
--- "data", "newtype" declarations
-rnTyClDecl (DataDecl _ _ _ _ (XHsDataDefn nec)) = noExtCon nec
-rnTyClDecl (DataDecl
- { tcdLName = tycon, tcdTyVars = tyvars,
- tcdFixity = fixity,
- tcdDataDefn = defn@HsDataDefn{ dd_ND = new_or_data
- , dd_kindSig = kind_sig} })
- = do { tycon' <- lookupLocatedTopBndrRn tycon
- ; let kvs = extractDataDefnKindVars defn
- doc = TyDataCtx tycon
- ; traceRn "rntycl-data" (ppr tycon <+> ppr kvs)
- ; bindHsQTyVars doc Nothing Nothing kvs tyvars $ \ tyvars' no_rhs_kvs ->
- do { (defn', fvs) <- rnDataDefn doc defn
- ; cusk <- data_decl_has_cusk tyvars' new_or_data no_rhs_kvs kind_sig
- ; let rn_info = DataDeclRn { tcdDataCusk = cusk
- , tcdFVs = fvs }
- ; traceRn "rndata" (ppr tycon <+> ppr cusk <+> ppr no_rhs_kvs)
- ; return (DataDecl { tcdLName = tycon'
- , tcdTyVars = tyvars'
- , tcdFixity = fixity
- , tcdDataDefn = defn'
- , tcdDExt = rn_info }, fvs) } }
-
-rnTyClDecl (ClassDecl { tcdCtxt = context, tcdLName = lcls,
- tcdTyVars = tyvars, tcdFixity = fixity,
- tcdFDs = fds, tcdSigs = sigs,
- tcdMeths = mbinds, tcdATs = ats, tcdATDefs = at_defs,
- tcdDocs = docs})
- = do { lcls' <- lookupLocatedTopBndrRn lcls
- ; let cls' = unLoc lcls'
- kvs = [] -- No scoped kind vars except those in
- -- kind signatures on the tyvars
-
- -- Tyvars scope over superclass context and method signatures
- ; ((tyvars', context', fds', ats'), stuff_fvs)
- <- bindHsQTyVars cls_doc Nothing Nothing kvs tyvars $ \ tyvars' _ -> do
- -- Checks for distinct tyvars
- { (context', cxt_fvs) <- rnContext cls_doc context
- ; fds' <- rnFds fds
- -- The fundeps have no free variables
- ; (ats', fv_ats) <- rnATDecls cls' ats
- ; let fvs = cxt_fvs `plusFV`
- fv_ats
- ; return ((tyvars', context', fds', ats'), fvs) }
-
- ; (at_defs', fv_at_defs) <- rnList (rnTyFamDefltDecl cls') at_defs
-
- -- No need to check for duplicate associated type decls
- -- since that is done by RnNames.extendGlobalRdrEnvRn
-
- -- 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 _ (ClassOpSig _ False ops _) <- sigs
- , op <- ops]
- ; checkDupRdrNames 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
- -- op :: a -> a
- -- op {| x+y |} (Inl a) = ...
- -- op {| x+y |} (Inr b) = ...
- -- 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.
- ; (mbinds', sigs', meth_fvs)
- <- rnMethodBinds True cls' (hsAllLTyVarNames tyvars') mbinds sigs
- -- No need to check for duplicate method signatures
- -- since that is done by RnNames.extendGlobalRdrEnvRn
- -- and the methods are already in scope
-
- -- Haddock docs
- ; docs' <- mapM (wrapLocM rnDocDecl) docs
-
- ; let all_fvs = meth_fvs `plusFV` stuff_fvs `plusFV` fv_at_defs
- ; return (ClassDecl { tcdCtxt = context', tcdLName = lcls',
- tcdTyVars = tyvars', tcdFixity = fixity,
- tcdFDs = fds', tcdSigs = sigs',
- tcdMeths = mbinds', tcdATs = ats', tcdATDefs = at_defs',
- tcdDocs = docs', tcdCExt = all_fvs },
- all_fvs ) }
- where
- cls_doc = ClassDeclCtx lcls
-
-rnTyClDecl (XTyClDecl nec) = noExtCon nec
-
--- Does the data type declaration include a CUSK?
-data_decl_has_cusk :: LHsQTyVars pass -> NewOrData -> Bool -> Maybe (LHsKind pass') -> RnM Bool
-data_decl_has_cusk tyvars new_or_data no_rhs_kvs kind_sig = do
- { -- See Note [Unlifted Newtypes and CUSKs], and for a broader
- -- picture, see Note [Implementation of UnliftedNewtypes].
- ; unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes
- ; let non_cusk_newtype
- | NewType <- new_or_data =
- unlifted_newtypes && isNothing kind_sig
- | otherwise = False
- -- See Note [CUSKs: complete user-supplied kind signatures] in GHC.Hs.Decls
- ; return $ hsTvbAllKinded tyvars && no_rhs_kvs && not non_cusk_newtype
- }
-
-{- Note [Unlifted Newtypes and CUSKs]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When unlifted newtypes are enabled, a newtype must have a kind signature
-in order to be considered have a CUSK. This is because the flow of
-kind inference works differently. Consider:
-
- newtype Foo = FooC Int
-
-When UnliftedNewtypes is disabled, we decide that Foo has kind
-`TYPE 'LiftedRep` without looking inside the data constructor. So, we
-can say that Foo has a CUSK. However, when UnliftedNewtypes is enabled,
-we fill in the kind of Foo as a metavar that gets solved by unification
-with the kind of the field inside FooC (that is, Int, whose kind is
-`TYPE 'LiftedRep`). But since we have to look inside the data constructors
-to figure out the kind signature of Foo, it does not have a CUSK.
-
-See Note [Implementation of UnliftedNewtypes] for where this fits in to
-the broader picture of UnliftedNewtypes.
--}
-
--- "type" and "type instance" declarations
-rnTySyn :: HsDocContext -> LHsType GhcPs -> RnM (LHsType GhcRn, FreeVars)
-rnTySyn doc rhs = rnLHsType doc rhs
-
-rnDataDefn :: HsDocContext -> HsDataDefn GhcPs
- -> RnM (HsDataDefn GhcRn, FreeVars)
-rnDataDefn doc (HsDataDefn { dd_ND = new_or_data, dd_cType = cType
- , dd_ctxt = context, dd_cons = condecls
- , dd_kindSig = m_sig, dd_derivs = derivs })
- = do { checkTc (h98_style || null (unLoc context))
- (badGadtStupidTheta doc)
-
- ; (m_sig', sig_fvs) <- case m_sig of
- Just sig -> first Just <$> rnLHsKind doc sig
- Nothing -> return (Nothing, emptyFVs)
- ; (context', fvs1) <- rnContext doc context
- ; (derivs', fvs3) <- rn_derivs derivs
-
- -- For the constructor declarations, drop the LocalRdrEnv
- -- in the GADT case, where the type variables in the declaration
- -- do not scope over the constructor signatures
- -- data T a where { T1 :: forall b. b-> b }
- ; let { zap_lcl_env | h98_style = \ thing -> thing
- | otherwise = setLocalRdrEnv emptyLocalRdrEnv }
- ; (condecls', con_fvs) <- zap_lcl_env $ rnConDecls condecls
- -- No need to check for duplicate constructor decls
- -- since that is done by RnNames.extendGlobalRdrEnvRn
-
- ; let all_fvs = fvs1 `plusFV` fvs3 `plusFV`
- con_fvs `plusFV` sig_fvs
- ; return ( HsDataDefn { dd_ext = noExtField
- , dd_ND = new_or_data, dd_cType = cType
- , dd_ctxt = context', dd_kindSig = m_sig'
- , dd_cons = condecls'
- , dd_derivs = derivs' }
- , all_fvs )
- }
- where
- h98_style = case condecls of -- Note [Stupid theta]
- (L _ (ConDeclGADT {})) : _ -> False
- _ -> True
-
- rn_derivs (L loc ds)
- = do { deriv_strats_ok <- xoptM LangExt.DerivingStrategies
- ; failIfTc (lengthExceeds ds 1 && not deriv_strats_ok)
- multipleDerivClausesErr
- ; (ds', fvs) <- mapFvRn (rnLHsDerivingClause doc) ds
- ; return (L loc ds', fvs) }
-rnDataDefn _ (XHsDataDefn nec) = noExtCon nec
-
-warnNoDerivStrat :: Maybe (LDerivStrategy GhcRn)
- -> SrcSpan
- -> RnM ()
-warnNoDerivStrat mds loc
- = do { dyn_flags <- getDynFlags
- ; when (wopt Opt_WarnMissingDerivingStrategies dyn_flags) $
- case mds of
- Nothing -> addWarnAt
- (Reason Opt_WarnMissingDerivingStrategies)
- loc
- (if xopt LangExt.DerivingStrategies dyn_flags
- then no_strat_warning
- else no_strat_warning $+$ deriv_strat_nenabled
- )
- _ -> pure ()
- }
- where
- no_strat_warning :: SDoc
- no_strat_warning = text "No deriving strategy specified. Did you want stock"
- <> text ", newtype, or anyclass?"
- deriv_strat_nenabled :: SDoc
- deriv_strat_nenabled = text "Use DerivingStrategies to specify a strategy."
-
-rnLHsDerivingClause :: HsDocContext -> LHsDerivingClause GhcPs
- -> RnM (LHsDerivingClause GhcRn, FreeVars)
-rnLHsDerivingClause doc
- (L loc (HsDerivingClause
- { deriv_clause_ext = noExtField
- , deriv_clause_strategy = dcs
- , deriv_clause_tys = L loc' dct }))
- = do { (dcs', dct', fvs)
- <- rnLDerivStrategy doc dcs $ mapFvRn (rnHsSigType doc TypeLevel) dct
- ; warnNoDerivStrat dcs' loc
- ; pure ( L loc (HsDerivingClause { deriv_clause_ext = noExtField
- , deriv_clause_strategy = dcs'
- , deriv_clause_tys = L loc' dct' })
- , fvs ) }
-rnLHsDerivingClause _ (L _ (XHsDerivingClause nec))
- = noExtCon nec
-
-rnLDerivStrategy :: forall a.
- HsDocContext
- -> Maybe (LDerivStrategy GhcPs)
- -> RnM (a, FreeVars)
- -> RnM (Maybe (LDerivStrategy GhcRn), a, FreeVars)
-rnLDerivStrategy doc mds thing_inside
- = case mds of
- Nothing -> boring_case Nothing
- Just (L loc ds) ->
- setSrcSpan loc $ do
- (ds', thing, fvs) <- rn_deriv_strat ds
- pure (Just (L loc ds'), thing, fvs)
- where
- rn_deriv_strat :: DerivStrategy GhcPs
- -> RnM (DerivStrategy GhcRn, a, FreeVars)
- rn_deriv_strat ds = do
- let extNeeded :: LangExt.Extension
- extNeeded
- | ViaStrategy{} <- ds
- = LangExt.DerivingVia
- | otherwise
- = LangExt.DerivingStrategies
-
- unlessXOptM extNeeded $
- failWith $ illegalDerivStrategyErr ds
-
- case ds of
- StockStrategy -> boring_case StockStrategy
- AnyclassStrategy -> boring_case AnyclassStrategy
- NewtypeStrategy -> boring_case NewtypeStrategy
- ViaStrategy via_ty ->
- do (via_ty', fvs1) <- rnHsSigType doc TypeLevel via_ty
- let HsIB { hsib_ext = via_imp_tvs
- , hsib_body = via_body } = via_ty'
- (via_exp_tv_bndrs, _, _) = splitLHsSigmaTy via_body
- via_exp_tvs = hsLTyVarNames via_exp_tv_bndrs
- via_tvs = via_imp_tvs ++ via_exp_tvs
- (thing, fvs2) <- extendTyVarEnvFVRn via_tvs thing_inside
- pure (ViaStrategy via_ty', thing, fvs1 `plusFV` fvs2)
-
- boring_case :: ds -> RnM (ds, a, FreeVars)
- boring_case ds = do
- (thing, fvs) <- thing_inside
- pure (ds, thing, fvs)
-
-badGadtStupidTheta :: HsDocContext -> SDoc
-badGadtStupidTheta _
- = vcat [text "No context is allowed on a GADT-style data declaration",
- text "(You can put a context on each constructor, though.)"]
-
-illegalDerivStrategyErr :: DerivStrategy GhcPs -> SDoc
-illegalDerivStrategyErr ds
- = vcat [ text "Illegal deriving strategy" <> colon <+> derivStrategyName ds
- , text enableStrategy ]
-
- where
- enableStrategy :: String
- enableStrategy
- | ViaStrategy{} <- ds
- = "Use DerivingVia to enable this extension"
- | otherwise
- = "Use DerivingStrategies to enable this extension"
-
-multipleDerivClausesErr :: SDoc
-multipleDerivClausesErr
- = vcat [ text "Illegal use of multiple, consecutive deriving clauses"
- , text "Use DerivingStrategies to allow this" ]
-
-rnFamDecl :: Maybe Name -- Just cls => this FamilyDecl is nested
- -- inside an *class decl* for cls
- -- used for associated types
- -> FamilyDecl GhcPs
- -> RnM (FamilyDecl GhcRn, FreeVars)
-rnFamDecl mb_cls (FamilyDecl { fdLName = tycon, fdTyVars = tyvars
- , fdFixity = fixity
- , fdInfo = info, fdResultSig = res_sig
- , fdInjectivityAnn = injectivity })
- = do { tycon' <- lookupLocatedTopBndrRn tycon
- ; ((tyvars', res_sig', injectivity'), fv1) <-
- bindHsQTyVars doc Nothing mb_cls kvs tyvars $ \ tyvars' _ ->
- do { let rn_sig = rnFamResultSig doc
- ; (res_sig', fv_kind) <- wrapLocFstM rn_sig res_sig
- ; injectivity' <- traverse (rnInjectivityAnn tyvars' res_sig')
- injectivity
- ; return ( (tyvars', res_sig', injectivity') , fv_kind ) }
- ; (info', fv2) <- rn_info tycon' info
- ; return (FamilyDecl { fdExt = noExtField
- , fdLName = tycon', fdTyVars = tyvars'
- , fdFixity = fixity
- , fdInfo = info', fdResultSig = res_sig'
- , fdInjectivityAnn = injectivity' }
- , fv1 `plusFV` fv2) }
- where
- doc = TyFamilyCtx tycon
- kvs = extractRdrKindSigVars res_sig
-
- ----------------------
- rn_info :: Located Name
- -> FamilyInfo GhcPs -> RnM (FamilyInfo GhcRn, FreeVars)
- rn_info (L _ fam_name) (ClosedTypeFamily (Just eqns))
- = do { (eqns', fvs)
- <- rnList (rnTyFamInstEqn NonAssocTyFamEqn (ClosedTyFam tycon fam_name))
- -- no class context
- eqns
- ; return (ClosedTypeFamily (Just eqns'), fvs) }
- rn_info _ (ClosedTypeFamily Nothing)
- = return (ClosedTypeFamily Nothing, emptyFVs)
- rn_info _ OpenTypeFamily = return (OpenTypeFamily, emptyFVs)
- rn_info _ DataFamily = return (DataFamily, emptyFVs)
-rnFamDecl _ (XFamilyDecl nec) = noExtCon nec
-
-rnFamResultSig :: HsDocContext
- -> FamilyResultSig GhcPs
- -> RnM (FamilyResultSig GhcRn, FreeVars)
-rnFamResultSig _ (NoSig _)
- = return (NoSig noExtField, emptyFVs)
-rnFamResultSig doc (KindSig _ kind)
- = do { (rndKind, ftvs) <- rnLHsKind doc kind
- ; return (KindSig noExtField rndKind, ftvs) }
-rnFamResultSig doc (TyVarSig _ tvbndr)
- = do { -- `TyVarSig` tells us that user named the result of a type family by
- -- writing `= tyvar` or `= (tyvar :: kind)`. In such case we want to
- -- be sure that the supplied result name is not identical to an
- -- already in-scope type variable from an enclosing class.
- --
- -- Example of disallowed declaration:
- -- class C a b where
- -- type F b = a | a -> b
- rdr_env <- getLocalRdrEnv
- ; let resName = hsLTyVarName tvbndr
- ; when (resName `elemLocalRdrEnv` rdr_env) $
- addErrAt (getLoc tvbndr) $
- (hsep [ text "Type variable", quotes (ppr resName) <> comma
- , text "naming a type family result,"
- ] $$
- text "shadows an already bound type variable")
-
- ; bindLHsTyVarBndr doc Nothing -- This might be a lie, but it's used for
- -- scoping checks that are irrelevant here
- tvbndr $ \ tvbndr' ->
- return (TyVarSig noExtField tvbndr', unitFV (hsLTyVarName tvbndr')) }
-rnFamResultSig _ (XFamilyResultSig nec) = noExtCon nec
-
--- Note [Renaming injectivity annotation]
--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---
--- During renaming of injectivity annotation we have to make several checks to
--- make sure that it is well-formed. At the moment injectivity annotation
--- consists of a single injectivity condition, so the terms "injectivity
--- annotation" and "injectivity condition" might be used interchangeably. See
--- Note [Injectivity annotation] for a detailed discussion of currently allowed
--- injectivity annotations.
---
--- Checking LHS is simple because the only type variable allowed on the LHS of
--- injectivity condition is the variable naming the result in type family head.
--- Example of disallowed annotation:
---
--- type family Foo a b = r | b -> a
---
--- Verifying RHS of injectivity consists of checking that:
---
--- 1. only variables defined in type family head appear on the RHS (kind
--- variables are also allowed). Example of disallowed annotation:
---
--- type family Foo a = r | r -> b
---
--- 2. for associated types the result variable does not shadow any of type
--- class variables. Example of disallowed annotation:
---
--- class Foo a b where
--- type F a = b | b -> a
---
--- Breaking any of these assumptions results in an error.
-
--- | Rename injectivity annotation. Note that injectivity annotation is just the
--- part after the "|". Everything that appears before it is renamed in
--- rnFamDecl.
-rnInjectivityAnn :: LHsQTyVars GhcRn -- ^ Type variables declared in
- -- type family head
- -> LFamilyResultSig GhcRn -- ^ Result signature
- -> LInjectivityAnn GhcPs -- ^ Injectivity annotation
- -> RnM (LInjectivityAnn GhcRn)
-rnInjectivityAnn tvBndrs (L _ (TyVarSig _ resTv))
- (L srcSpan (InjectivityAnn injFrom injTo))
- = do
- { (injDecl'@(L _ (InjectivityAnn injFrom' injTo')), noRnErrors)
- <- askNoErrs $
- bindLocalNames [hsLTyVarName resTv] $
- -- The return type variable scopes over the injectivity annotation
- -- e.g. type family F a = (r::*) | r -> a
- do { injFrom' <- rnLTyVar injFrom
- ; injTo' <- mapM rnLTyVar injTo
- ; return $ L srcSpan (InjectivityAnn injFrom' injTo') }
-
- ; let tvNames = Set.fromList $ hsAllLTyVarNames tvBndrs
- resName = hsLTyVarName resTv
- -- See Note [Renaming injectivity annotation]
- lhsValid = EQ == (stableNameCmp resName (unLoc injFrom'))
- rhsValid = Set.fromList (map unLoc injTo') `Set.difference` tvNames
-
- -- if renaming of type variables ended with errors (eg. there were
- -- not-in-scope variables) don't check the validity of injectivity
- -- annotation. This gives better error messages.
- ; when (noRnErrors && not lhsValid) $
- addErrAt (getLoc injFrom)
- ( vcat [ text $ "Incorrect type variable on the LHS of "
- ++ "injectivity condition"
- , nest 5
- ( vcat [ text "Expected :" <+> ppr resName
- , text "Actual :" <+> ppr injFrom ])])
-
- ; when (noRnErrors && not (Set.null rhsValid)) $
- do { let errorVars = Set.toList rhsValid
- ; addErrAt srcSpan $ ( hsep
- [ text "Unknown type variable" <> plural errorVars
- , text "on the RHS of injectivity condition:"
- , interpp'SP errorVars ] ) }
-
- ; return injDecl' }
-
--- We can only hit this case when the user writes injectivity annotation without
--- naming the result:
---
--- type family F a | result -> a
--- type family F a :: * | result -> a
---
--- So we rename injectivity annotation like we normally would except that
--- this time we expect "result" to be reported not in scope by rnLTyVar.
-rnInjectivityAnn _ _ (L srcSpan (InjectivityAnn injFrom injTo)) =
- setSrcSpan srcSpan $ do
- (injDecl', _) <- askNoErrs $ do
- injFrom' <- rnLTyVar injFrom
- injTo' <- mapM rnLTyVar injTo
- return $ L srcSpan (InjectivityAnn injFrom' injTo')
- return $ injDecl'
-
-{-
-Note [Stupid theta]
-~~~~~~~~~~~~~~~~~~~
-#3850 complains about a regression wrt 6.10 for
- data Show a => T a
-There is no reason not to allow the stupid theta if there are no data
-constructors. It's still stupid, but does no harm, and I don't want
-to cause programs to break unnecessarily (notably HList). So if there
-are no data constructors we allow h98_style = True
--}
-
-
-{- *****************************************************
-* *
- Support code for type/data declarations
-* *
-***************************************************** -}
-
----------------
-wrongTyFamName :: Name -> Name -> SDoc
-wrongTyFamName fam_tc_name eqn_tc_name
- = hang (text "Mismatched type name in type family instance.")
- 2 (vcat [ text "Expected:" <+> ppr fam_tc_name
- , text " Actual:" <+> ppr eqn_tc_name ])
-
------------------
-rnConDecls :: [LConDecl GhcPs] -> RnM ([LConDecl GhcRn], FreeVars)
-rnConDecls = mapFvRn (wrapLocFstM rnConDecl)
-
-rnConDecl :: ConDecl GhcPs -> RnM (ConDecl GhcRn, FreeVars)
-rnConDecl decl@(ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs
- , con_mb_cxt = mcxt, con_args = args
- , con_doc = mb_doc })
- = do { _ <- addLocM checkConName name
- ; new_name <- lookupLocatedTopBndrRn name
- ; mb_doc' <- rnMbLHsDoc mb_doc
-
- -- We bind no implicit binders here; this is just like
- -- a nested HsForAllTy. E.g. consider
- -- data T a = forall (b::k). MkT (...)
- -- The 'k' will already be in scope from the bindHsQTyVars
- -- for the data decl itself. So we'll get
- -- data T {k} a = ...
- -- And indeed we may later discover (a::k). But that's the
- -- scoping we get. So no implicit binders at the existential forall
-
- ; let ctxt = ConDeclCtx [new_name]
- ; bindLHsTyVarBndrs ctxt (Just (inHsDocContext ctxt))
- Nothing ex_tvs $ \ new_ex_tvs ->
- do { (new_context, fvs1) <- rnMbContext ctxt mcxt
- ; (new_args, fvs2) <- rnConDeclDetails (unLoc new_name) ctxt args
- ; let all_fvs = fvs1 `plusFV` fvs2
- ; traceRn "rnConDecl" (ppr name <+> vcat
- [ text "ex_tvs:" <+> ppr ex_tvs
- , text "new_ex_dqtvs':" <+> ppr new_ex_tvs ])
-
- ; return (decl { con_ext = noExtField
- , con_name = new_name, con_ex_tvs = new_ex_tvs
- , con_mb_cxt = new_context, con_args = new_args
- , con_doc = mb_doc' },
- all_fvs) }}
-
-rnConDecl decl@(ConDeclGADT { con_names = names
- , con_forall = L _ explicit_forall
- , con_qvars = qtvs
- , con_mb_cxt = mcxt
- , con_args = args
- , con_res_ty = res_ty
- , con_doc = mb_doc })
- = do { mapM_ (addLocM checkConName) names
- ; new_names <- mapM lookupLocatedTopBndrRn names
- ; mb_doc' <- rnMbLHsDoc mb_doc
-
- ; let explicit_tkvs = hsQTvExplicit qtvs
- theta = hsConDeclTheta mcxt
- arg_tys = hsConDeclArgTys args
-
- -- We must ensure that we extract the free tkvs in left-to-right
- -- order of their appearance in the constructor type.
- -- That order governs the order the implicitly-quantified type
- -- variable, and hence the order needed for visible type application
- -- See #14808.
- free_tkvs = extractHsTvBndrs explicit_tkvs $
- extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty])
-
- ctxt = ConDeclCtx new_names
- mb_ctxt = Just (inHsDocContext ctxt)
-
- ; traceRn "rnConDecl" (ppr names $$ ppr free_tkvs $$ ppr explicit_forall )
- ; rnImplicitBndrs (not explicit_forall) free_tkvs $ \ implicit_tkvs ->
- bindLHsTyVarBndrs ctxt mb_ctxt Nothing explicit_tkvs $ \ explicit_tkvs ->
- do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt
- ; (new_args, fvs2) <- rnConDeclDetails (unLoc (head new_names)) ctxt args
- ; (new_res_ty, fvs3) <- rnLHsType ctxt res_ty
-
- ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3
- (args', res_ty')
- = case args of
- InfixCon {} -> pprPanic "rnConDecl" (ppr names)
- RecCon {} -> (new_args, new_res_ty)
- PrefixCon as | (arg_tys, final_res_ty) <- splitHsFunType new_res_ty
- -> ASSERT( null as )
- -- See Note [GADT abstract syntax] in GHC.Hs.Decls
- (PrefixCon arg_tys, final_res_ty)
-
- new_qtvs = HsQTvs { hsq_ext = implicit_tkvs
- , hsq_explicit = explicit_tkvs }
-
- ; traceRn "rnConDecl2" (ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs)
- ; return (decl { con_g_ext = noExtField, con_names = new_names
- , con_qvars = new_qtvs, con_mb_cxt = new_cxt
- , con_args = args', con_res_ty = res_ty'
- , con_doc = mb_doc' },
- all_fvs) } }
-
-rnConDecl (XConDecl nec) = noExtCon nec
-
-
-rnMbContext :: HsDocContext -> Maybe (LHsContext GhcPs)
- -> RnM (Maybe (LHsContext GhcRn), FreeVars)
-rnMbContext _ Nothing = return (Nothing, emptyFVs)
-rnMbContext doc (Just cxt) = do { (ctx',fvs) <- rnContext doc cxt
- ; return (Just ctx',fvs) }
-
-rnConDeclDetails
- :: Name
- -> HsDocContext
- -> HsConDetails (LHsType GhcPs) (Located [LConDeclField GhcPs])
- -> RnM (HsConDetails (LHsType GhcRn) (Located [LConDeclField GhcRn]),
- FreeVars)
-rnConDeclDetails _ doc (PrefixCon tys)
- = do { (new_tys, fvs) <- rnLHsTypes doc tys
- ; return (PrefixCon new_tys, fvs) }
-
-rnConDeclDetails _ doc (InfixCon ty1 ty2)
- = do { (new_ty1, fvs1) <- rnLHsType doc ty1
- ; (new_ty2, fvs2) <- rnLHsType doc ty2
- ; return (InfixCon new_ty1 new_ty2, fvs1 `plusFV` fvs2) }
-
-rnConDeclDetails con doc (RecCon (L l fields))
- = do { fls <- lookupConstructorFields con
- ; (new_fields, fvs) <- rnConDeclFields doc fls fields
- -- No need to check for duplicate fields
- -- since that is done by RnNames.extendGlobalRdrEnvRn
- ; return (RecCon (L l new_fields), fvs) }
-
--------------------------------------------------
-
--- | Brings pattern synonym names and also pattern synonym selectors
--- from record pattern synonyms into scope.
-extendPatSynEnv :: HsValBinds GhcPs -> MiniFixityEnv
- -> ([Name] -> TcRnIf TcGblEnv TcLclEnv a) -> TcM a
-extendPatSynEnv val_decls local_fix_env thing = do {
- names_with_fls <- new_ps val_decls
- ; let pat_syn_bndrs = concat [ name: map flSelector fields
- | (name, fields) <- names_with_fls ]
- ; let avails = map avail pat_syn_bndrs
- ; (gbl_env, lcl_env) <- extendGlobalRdrEnvRn avails local_fix_env
-
- ; let field_env' = extendNameEnvList (tcg_field_env gbl_env) names_with_fls
- final_gbl_env = gbl_env { tcg_field_env = field_env' }
- ; setEnvs (final_gbl_env, lcl_env) (thing pat_syn_bndrs) }
- where
- new_ps :: HsValBinds GhcPs -> TcM [(Name, [FieldLabel])]
- new_ps (ValBinds _ binds _) = foldrM new_ps' [] binds
- new_ps _ = panic "new_ps"
-
- new_ps' :: LHsBindLR GhcPs GhcPs
- -> [(Name, [FieldLabel])]
- -> TcM [(Name, [FieldLabel])]
- new_ps' bind names
- | (L bind_loc (PatSynBind _ (PSB { psb_id = L _ n
- , psb_args = RecCon as }))) <- bind
- = do
- bnd_name <- newTopSrcBinder (L bind_loc n)
- let rnames = map recordPatSynSelectorId as
- mkFieldOcc :: Located RdrName -> LFieldOcc GhcPs
- mkFieldOcc (L l name) = L l (FieldOcc noExtField (L l name))
- field_occs = map mkFieldOcc rnames
- flds <- mapM (newRecordSelector False [bnd_name]) field_occs
- return ((bnd_name, flds): names)
- | L bind_loc (PatSynBind _ (PSB { psb_id = L _ n})) <- bind
- = do
- bnd_name <- newTopSrcBinder (L bind_loc n)
- return ((bnd_name, []): names)
- | otherwise
- = return names
-
-{-
-*********************************************************
-* *
-\subsection{Support code to rename types}
-* *
-*********************************************************
--}
-
-rnFds :: [LHsFunDep GhcPs] -> RnM [LHsFunDep GhcRn]
-rnFds fds
- = mapM (wrapLocM rn_fds) fds
- where
- rn_fds (tys1, tys2)
- = do { tys1' <- rnHsTyVars tys1
- ; tys2' <- rnHsTyVars tys2
- ; return (tys1', tys2') }
-
-rnHsTyVars :: [Located RdrName] -> RnM [Located Name]
-rnHsTyVars tvs = mapM rnHsTyVar tvs
-
-rnHsTyVar :: Located RdrName -> RnM (Located Name)
-rnHsTyVar (L l tyvar) = do
- tyvar' <- lookupOccRn tyvar
- return (L l tyvar')
-
-{-
-*********************************************************
-* *
- findSplice
-* *
-*********************************************************
-
-This code marches down the declarations, looking for the first
-Template Haskell splice. As it does so it
- a) groups the declarations into a HsGroup
- b) runs any top-level quasi-quotes
--}
-
-findSplice :: [LHsDecl GhcPs]
- -> RnM (HsGroup GhcPs, Maybe (SpliceDecl GhcPs, [LHsDecl GhcPs]))
-findSplice ds = addl emptyRdrGroup ds
-
-addl :: HsGroup GhcPs -> [LHsDecl GhcPs]
- -> RnM (HsGroup GhcPs, Maybe (SpliceDecl GhcPs, [LHsDecl GhcPs]))
--- This stuff reverses the declarations (again) but it doesn't matter
-addl gp [] = return (gp, Nothing)
-addl gp (L l d : ds) = add gp l d ds
-
-
-add :: HsGroup GhcPs -> SrcSpan -> HsDecl GhcPs -> [LHsDecl GhcPs]
- -> RnM (HsGroup GhcPs, Maybe (SpliceDecl GhcPs, [LHsDecl GhcPs]))
-
--- #10047: Declaration QuasiQuoters are expanded immediately, without
--- causing a group split
-add gp _ (SpliceD _ (SpliceDecl _ (L _ qq@HsQuasiQuote{}) _)) ds
- = do { (ds', _) <- rnTopSpliceDecls qq
- ; addl gp (ds' ++ ds)
- }
-
-add gp loc (SpliceD _ splice@(SpliceDecl _ _ flag)) ds
- = do { -- We've found a top-level splice. If it is an *implicit* one
- -- (i.e. a naked top level expression)
- case flag of
- ExplicitSplice -> return ()
- ImplicitSplice -> do { th_on <- xoptM LangExt.TemplateHaskell
- ; unless th_on $ setSrcSpan loc $
- failWith badImplicitSplice }
-
- ; return (gp, Just (splice, ds)) }
- where
- badImplicitSplice = text "Parse error: module header, import declaration"
- $$ text "or top-level declaration expected."
- -- The compiler should suggest the above, and not using
- -- TemplateHaskell since the former suggestion is more
- -- relevant to the larger base of users.
- -- See #12146 for discussion.
-
--- Class declarations: pull out the fixity signatures to the top
-add gp@(HsGroup {hs_tyclds = ts, hs_fixds = fs}) l (TyClD _ d) ds
- | isClassDecl d
- = let fsigs = [ L l f
- | L l (FixSig _ f) <- tcdSigs d ] in
- addl (gp { hs_tyclds = add_tycld (L l d) ts, hs_fixds = fsigs ++ fs}) ds
- | otherwise
- = addl (gp { hs_tyclds = add_tycld (L l d) ts }) ds
-
--- Signatures: fixity sigs go a different place than all others
-add gp@(HsGroup {hs_fixds = ts}) l (SigD _ (FixSig _ f)) ds
- = addl (gp {hs_fixds = L l f : ts}) ds
-
--- Standalone kind signatures: added to the TyClGroup
-add gp@(HsGroup {hs_tyclds = ts}) l (KindSigD _ s) ds
- = addl (gp {hs_tyclds = add_kisig (L l s) ts}) ds
-
-add gp@(HsGroup {hs_valds = ts}) l (SigD _ d) ds
- = addl (gp {hs_valds = add_sig (L l d) ts}) ds
-
--- Value declarations: use add_bind
-add gp@(HsGroup {hs_valds = ts}) l (ValD _ d) ds
- = addl (gp { hs_valds = add_bind (L l d) ts }) ds
-
--- Role annotations: added to the TyClGroup
-add gp@(HsGroup {hs_tyclds = ts}) l (RoleAnnotD _ d) ds
- = addl (gp { hs_tyclds = add_role_annot (L l d) ts }) ds
-
--- NB instance declarations go into TyClGroups. We throw them into the first
--- group, just as we do for the TyClD case. The renamer will go on to group
--- and order them later.
-add gp@(HsGroup {hs_tyclds = ts}) l (InstD _ d) ds
- = addl (gp { hs_tyclds = add_instd (L l d) ts }) ds
-
--- The rest are routine
-add gp@(HsGroup {hs_derivds = ts}) l (DerivD _ d) ds
- = addl (gp { hs_derivds = L l d : ts }) ds
-add gp@(HsGroup {hs_defds = ts}) l (DefD _ d) ds
- = addl (gp { hs_defds = L l d : ts }) ds
-add gp@(HsGroup {hs_fords = ts}) l (ForD _ d) ds
- = addl (gp { hs_fords = L l d : ts }) ds
-add gp@(HsGroup {hs_warnds = ts}) l (WarningD _ d) ds
- = addl (gp { hs_warnds = L l d : ts }) ds
-add gp@(HsGroup {hs_annds = ts}) l (AnnD _ d) ds
- = addl (gp { hs_annds = L l d : ts }) ds
-add gp@(HsGroup {hs_ruleds = ts}) l (RuleD _ d) ds
- = addl (gp { hs_ruleds = L l d : ts }) ds
-add gp l (DocD _ d) ds
- = addl (gp { hs_docs = (L l d) : (hs_docs gp) }) ds
-add (HsGroup {}) _ (SpliceD _ (XSpliceDecl nec)) _ = noExtCon nec
-add (HsGroup {}) _ (XHsDecl nec) _ = noExtCon nec
-add (XHsGroup nec) _ _ _ = noExtCon nec
-
-add_tycld :: LTyClDecl (GhcPass p) -> [TyClGroup (GhcPass p)]
- -> [TyClGroup (GhcPass p)]
-add_tycld d [] = [TyClGroup { group_ext = noExtField
- , group_tyclds = [d]
- , group_kisigs = []
- , group_roles = []
- , group_instds = []
- }
- ]
-add_tycld d (ds@(TyClGroup { group_tyclds = tyclds }):dss)
- = ds { group_tyclds = d : tyclds } : dss
-add_tycld _ (XTyClGroup nec: _) = noExtCon nec
-
-add_instd :: LInstDecl (GhcPass p) -> [TyClGroup (GhcPass p)]
- -> [TyClGroup (GhcPass p)]
-add_instd d [] = [TyClGroup { group_ext = noExtField
- , group_tyclds = []
- , group_kisigs = []
- , group_roles = []
- , group_instds = [d]
- }
- ]
-add_instd d (ds@(TyClGroup { group_instds = instds }):dss)
- = ds { group_instds = d : instds } : dss
-add_instd _ (XTyClGroup nec: _) = noExtCon nec
-
-add_role_annot :: LRoleAnnotDecl (GhcPass p) -> [TyClGroup (GhcPass p)]
- -> [TyClGroup (GhcPass p)]
-add_role_annot d [] = [TyClGroup { group_ext = noExtField
- , group_tyclds = []
- , group_kisigs = []
- , group_roles = [d]
- , group_instds = []
- }
- ]
-add_role_annot d (tycls@(TyClGroup { group_roles = roles }) : rest)
- = tycls { group_roles = d : roles } : rest
-add_role_annot _ (XTyClGroup nec: _) = noExtCon nec
-
-add_kisig :: LStandaloneKindSig (GhcPass p)
- -> [TyClGroup (GhcPass p)] -> [TyClGroup (GhcPass p)]
-add_kisig d [] = [TyClGroup { group_ext = noExtField
- , group_tyclds = []
- , group_kisigs = [d]
- , group_roles = []
- , group_instds = []
- }
- ]
-add_kisig d (tycls@(TyClGroup { group_kisigs = kisigs }) : rest)
- = tycls { group_kisigs = d : kisigs } : rest
-add_kisig _ (XTyClGroup nec : _) = noExtCon nec
-
-add_bind :: LHsBind a -> HsValBinds a -> HsValBinds a
-add_bind b (ValBinds x bs sigs) = ValBinds x (bs `snocBag` b) sigs
-add_bind _ (XValBindsLR {}) = panic "RdrHsSyn:add_bind"
-
-add_sig :: LSig (GhcPass a) -> HsValBinds (GhcPass a) -> HsValBinds (GhcPass a)
-add_sig s (ValBinds x bs sigs) = ValBinds x bs (s:sigs)
-add_sig _ (XValBindsLR {}) = panic "RdrHsSyn:add_sig"
diff --git a/compiler/rename/RnSplice.hs b/compiler/rename/RnSplice.hs
deleted file mode 100644
index 4094402697..0000000000
--- a/compiler/rename/RnSplice.hs
+++ /dev/null
@@ -1,902 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE ViewPatterns #-}
-
-module RnSplice (
- rnTopSpliceDecls,
- rnSpliceType, rnSpliceExpr, rnSplicePat, rnSpliceDecl,
- rnBracket,
- checkThLocalName
- , traceSplice, SpliceInfo(..)
- ) where
-
-#include "HsVersions.h"
-
-import GhcPrelude
-
-import Name
-import NameSet
-import GHC.Hs
-import RdrName
-import TcRnMonad
-
-import RnEnv
-import RnUtils ( HsDocContext(..), newLocalBndrRn )
-import RnUnbound ( isUnboundName )
-import RnSource ( rnSrcDecls, findSplice )
-import RnPat ( rnPat )
-import BasicTypes ( TopLevelFlag, isTopLevel, SourceText(..) )
-import Outputable
-import Module
-import SrcLoc
-import RnTypes ( rnLHsType )
-
-import Control.Monad ( unless, when )
-
-import {-# SOURCE #-} RnExpr ( rnLExpr )
-
-import TcEnv ( checkWellStaged )
-import THNames ( liftName )
-
-import DynFlags
-import FastString
-import ErrUtils ( dumpIfSet_dyn_printer, DumpFormat (..) )
-import TcEnv ( tcMetaTy )
-import Hooks
-import THNames ( quoteExpName, quotePatName, quoteDecName, quoteTypeName
- , decsQTyConName, expQTyConName, patQTyConName, typeQTyConName, )
-
-import {-# SOURCE #-} TcExpr ( tcPolyExpr )
-import {-# SOURCE #-} TcSplice
- ( runMetaD
- , runMetaE
- , runMetaP
- , runMetaT
- , tcTopSpliceExpr
- )
-
-import TcHsSyn
-
-import GHCi.RemoteTypes ( ForeignRef )
-import qualified Language.Haskell.TH as TH (Q)
-
-import qualified GHC.LanguageExtensions as LangExt
-
-{-
-************************************************************************
-* *
- Template Haskell brackets
-* *
-************************************************************************
--}
-
-rnBracket :: HsExpr GhcPs -> HsBracket GhcPs -> RnM (HsExpr GhcRn, FreeVars)
-rnBracket e br_body
- = addErrCtxt (quotationCtxtDoc br_body) $
- do { -- Check that -XTemplateHaskellQuotes is enabled and available
- thQuotesEnabled <- xoptM LangExt.TemplateHaskellQuotes
- ; unless thQuotesEnabled $
- failWith ( vcat
- [ text "Syntax error on" <+> ppr e
- , text ("Perhaps you intended to use TemplateHaskell"
- ++ " or TemplateHaskellQuotes") ] )
-
- -- Check for nested brackets
- ; cur_stage <- getStage
- ; case cur_stage of
- { Splice Typed -> checkTc (isTypedBracket br_body)
- illegalUntypedBracket
- ; Splice Untyped -> checkTc (not (isTypedBracket br_body))
- illegalTypedBracket
- ; RunSplice _ ->
- -- See Note [RunSplice ThLevel] in "TcRnTypes".
- pprPanic "rnBracket: Renaming bracket when running a splice"
- (ppr e)
- ; Comp -> return ()
- ; Brack {} -> failWithTc illegalBracket
- }
-
- -- Brackets are desugared to code that mentions the TH package
- ; recordThUse
-
- ; case isTypedBracket br_body of
- True -> do { traceRn "Renaming typed TH bracket" empty
- ; (body', fvs_e) <-
- setStage (Brack cur_stage RnPendingTyped) $
- rn_bracket cur_stage br_body
- ; return (HsBracket noExtField body', fvs_e) }
-
- False -> do { traceRn "Renaming untyped TH bracket" empty
- ; ps_var <- newMutVar []
- ; (body', fvs_e) <-
- setStage (Brack cur_stage (RnPendingUntyped ps_var)) $
- rn_bracket cur_stage br_body
- ; pendings <- readMutVar ps_var
- ; return (HsRnBracketOut noExtField body' pendings, fvs_e) }
- }
-
-rn_bracket :: ThStage -> HsBracket GhcPs -> RnM (HsBracket GhcRn, FreeVars)
-rn_bracket outer_stage br@(VarBr x flg rdr_name)
- = do { name <- lookupOccRn rdr_name
- ; this_mod <- getModule
-
- ; when (flg && nameIsLocalOrFrom this_mod name) $
- -- Type variables can be quoted in TH. See #5721.
- do { mb_bind_lvl <- lookupLocalOccThLvl_maybe name
- ; case mb_bind_lvl of
- { Nothing -> return () -- Can happen for data constructors,
- -- but nothing needs to be done for them
-
- ; Just (top_lvl, bind_lvl) -- See Note [Quoting names]
- | isTopLevel top_lvl
- -> when (isExternalName name) (keepAlive name)
- | otherwise
- -> do { traceRn "rn_bracket VarBr"
- (ppr name <+> ppr bind_lvl
- <+> ppr outer_stage)
- ; checkTc (thLevel outer_stage + 1 == bind_lvl)
- (quotedNameStageErr br) }
- }
- }
- ; return (VarBr x flg name, unitFV name) }
-
-rn_bracket _ (ExpBr x e) = do { (e', fvs) <- rnLExpr e
- ; return (ExpBr x e', fvs) }
-
-rn_bracket _ (PatBr x p)
- = rnPat ThPatQuote p $ \ p' -> return (PatBr x p', emptyFVs)
-
-rn_bracket _ (TypBr x t) = do { (t', fvs) <- rnLHsType TypBrCtx t
- ; return (TypBr x t', fvs) }
-
-rn_bracket _ (DecBrL x decls)
- = do { group <- groupDecls decls
- ; gbl_env <- getGblEnv
- ; let new_gbl_env = gbl_env { tcg_dus = emptyDUs }
- -- The emptyDUs is so that we just collect uses for this
- -- group alone in the call to rnSrcDecls below
- ; (tcg_env, group') <- setGblEnv new_gbl_env $
- rnSrcDecls group
-
- -- Discard the tcg_env; it contains only extra info about fixity
- ; traceRn "rn_bracket dec" (ppr (tcg_dus tcg_env) $$
- ppr (duUses (tcg_dus tcg_env)))
- ; return (DecBrG x group', duUses (tcg_dus tcg_env)) }
- where
- groupDecls :: [LHsDecl GhcPs] -> RnM (HsGroup GhcPs)
- groupDecls decls
- = do { (group, mb_splice) <- findSplice decls
- ; case mb_splice of
- { Nothing -> return group
- ; Just (splice, rest) ->
- do { group' <- groupDecls rest
- ; let group'' = appendGroups group group'
- ; return group'' { hs_splcds = noLoc splice : hs_splcds group' }
- }
- }}
-
-rn_bracket _ (DecBrG {}) = panic "rn_bracket: unexpected DecBrG"
-
-rn_bracket _ (TExpBr x e) = do { (e', fvs) <- rnLExpr e
- ; return (TExpBr x e', fvs) }
-
-rn_bracket _ (XBracket nec) = noExtCon nec
-
-quotationCtxtDoc :: HsBracket GhcPs -> SDoc
-quotationCtxtDoc br_body
- = hang (text "In the Template Haskell quotation")
- 2 (ppr br_body)
-
-illegalBracket :: SDoc
-illegalBracket =
- text "Template Haskell brackets cannot be nested" <+>
- text "(without intervening splices)"
-
-illegalTypedBracket :: SDoc
-illegalTypedBracket =
- text "Typed brackets may only appear in typed splices."
-
-illegalUntypedBracket :: SDoc
-illegalUntypedBracket =
- text "Untyped brackets may only appear in untyped splices."
-
-quotedNameStageErr :: HsBracket GhcPs -> SDoc
-quotedNameStageErr br
- = sep [ text "Stage error: the non-top-level quoted name" <+> ppr br
- , text "must be used at the same stage at which it is bound" ]
-
-
-{-
-*********************************************************
-* *
- Splices
-* *
-*********************************************************
-
-Note [Free variables of typed splices]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider renaming this:
- f = ...
- h = ...$(thing "f")...
-
-where the splice is a *typed* splice. The splice can expand into
-literally anything, so when we do dependency analysis we must assume
-that it might mention 'f'. So we simply treat all locally-defined
-names as mentioned by any splice. This is terribly brutal, but I
-don't see what else to do. For example, it'll mean that every
-locally-defined thing will appear to be used, so no unused-binding
-warnings. But if we miss the dependency, then we might typecheck 'h'
-before 'f', and that will crash the type checker because 'f' isn't in
-scope.
-
-Currently, I'm not treating a splice as also mentioning every import,
-which is a bit inconsistent -- but there are a lot of them. We might
-thereby get some bogus unused-import warnings, but we won't crash the
-type checker. Not very satisfactory really.
-
-Note [Renamer errors]
-~~~~~~~~~~~~~~~~~~~~~
-It's important to wrap renamer calls in checkNoErrs, because the
-renamer does not fail for out of scope variables etc. Instead it
-returns a bogus term/type, so that it can report more than one error.
-We don't want the type checker to see these bogus unbound variables.
--}
-
-rnSpliceGen :: (HsSplice GhcRn -> RnM (a, FreeVars))
- -- Outside brackets, run splice
- -> (HsSplice GhcRn -> (PendingRnSplice, a))
- -- Inside brackets, make it pending
- -> HsSplice GhcPs
- -> RnM (a, FreeVars)
-rnSpliceGen run_splice pend_splice splice
- = addErrCtxt (spliceCtxt splice) $ do
- { stage <- getStage
- ; case stage of
- Brack pop_stage RnPendingTyped
- -> do { checkTc is_typed_splice illegalUntypedSplice
- ; (splice', fvs) <- setStage pop_stage $
- rnSplice splice
- ; let (_pending_splice, result) = pend_splice splice'
- ; return (result, fvs) }
-
- Brack pop_stage (RnPendingUntyped ps_var)
- -> do { checkTc (not is_typed_splice) illegalTypedSplice
- ; (splice', fvs) <- setStage pop_stage $
- rnSplice splice
- ; let (pending_splice, result) = pend_splice splice'
- ; ps <- readMutVar ps_var
- ; writeMutVar ps_var (pending_splice : ps)
- ; return (result, fvs) }
-
- _ -> do { (splice', fvs1) <- checkNoErrs $
- setStage (Splice splice_type) $
- rnSplice splice
- -- checkNoErrs: don't attempt to run the splice if
- -- renaming it failed; otherwise we get a cascade of
- -- errors from e.g. unbound variables
- ; (result, fvs2) <- run_splice splice'
- ; return (result, fvs1 `plusFV` fvs2) } }
- where
- is_typed_splice = isTypedSplice splice
- splice_type = if is_typed_splice
- then Typed
- else Untyped
-
-------------------
-
--- | Returns the result of running a splice and the modFinalizers collected
--- during the execution.
---
--- See Note [Delaying modFinalizers in untyped splices].
-runRnSplice :: UntypedSpliceFlavour
- -> (LHsExpr GhcTc -> TcRn res)
- -> (res -> SDoc) -- How to pretty-print res
- -- Usually just ppr, but not for [Decl]
- -> HsSplice GhcRn -- Always untyped
- -> TcRn (res, [ForeignRef (TH.Q ())])
-runRnSplice flavour run_meta ppr_res splice
- = do { splice' <- getHooked runRnSpliceHook return >>= ($ splice)
-
- ; let the_expr = case splice' of
- HsUntypedSplice _ _ _ e -> e
- HsQuasiQuote _ _ q qs str -> mkQuasiQuoteExpr flavour q qs str
- HsTypedSplice {} -> pprPanic "runRnSplice" (ppr splice)
- HsSpliced {} -> pprPanic "runRnSplice" (ppr splice)
- HsSplicedT {} -> pprPanic "runRnSplice" (ppr splice)
- XSplice nec -> noExtCon nec
-
- -- Typecheck the expression
- ; meta_exp_ty <- tcMetaTy meta_ty_name
- ; zonked_q_expr <- zonkTopLExpr =<<
- tcTopSpliceExpr Untyped
- (tcPolyExpr the_expr meta_exp_ty)
-
- -- Run the expression
- ; mod_finalizers_ref <- newTcRef []
- ; result <- setStage (RunSplice mod_finalizers_ref) $
- run_meta zonked_q_expr
- ; mod_finalizers <- readTcRef mod_finalizers_ref
- ; traceSplice (SpliceInfo { spliceDescription = what
- , spliceIsDecl = is_decl
- , spliceSource = Just the_expr
- , spliceGenerated = ppr_res result })
-
- ; return (result, mod_finalizers) }
-
- where
- meta_ty_name = case flavour of
- UntypedExpSplice -> expQTyConName
- UntypedPatSplice -> patQTyConName
- UntypedTypeSplice -> typeQTyConName
- UntypedDeclSplice -> decsQTyConName
- what = case flavour of
- UntypedExpSplice -> "expression"
- UntypedPatSplice -> "pattern"
- UntypedTypeSplice -> "type"
- UntypedDeclSplice -> "declarations"
- is_decl = case flavour of
- UntypedDeclSplice -> True
- _ -> False
-
-------------------
-makePending :: UntypedSpliceFlavour
- -> HsSplice GhcRn
- -> PendingRnSplice
-makePending flavour (HsUntypedSplice _ _ n e)
- = PendingRnSplice flavour n e
-makePending flavour (HsQuasiQuote _ n quoter q_span quote)
- = PendingRnSplice flavour n (mkQuasiQuoteExpr flavour quoter q_span quote)
-makePending _ splice@(HsTypedSplice {})
- = pprPanic "makePending" (ppr splice)
-makePending _ splice@(HsSpliced {})
- = pprPanic "makePending" (ppr splice)
-makePending _ splice@(HsSplicedT {})
- = pprPanic "makePending" (ppr splice)
-makePending _ (XSplice nec)
- = noExtCon nec
-
-------------------
-mkQuasiQuoteExpr :: UntypedSpliceFlavour -> Name -> SrcSpan -> FastString
- -> LHsExpr GhcRn
--- Return the expression (quoter "...quote...")
--- which is what we must run in a quasi-quote
-mkQuasiQuoteExpr flavour quoter q_span quote
- = L q_span $ HsApp noExtField (L q_span
- $ HsApp noExtField (L q_span (HsVar noExtField (L q_span quote_selector)))
- quoterExpr)
- quoteExpr
- where
- quoterExpr = L q_span $! HsVar noExtField $! (L q_span quoter)
- quoteExpr = L q_span $! HsLit noExtField $! HsString NoSourceText quote
- quote_selector = case flavour of
- UntypedExpSplice -> quoteExpName
- UntypedPatSplice -> quotePatName
- UntypedTypeSplice -> quoteTypeName
- UntypedDeclSplice -> quoteDecName
-
----------------------
-rnSplice :: HsSplice GhcPs -> RnM (HsSplice GhcRn, FreeVars)
--- Not exported...used for all
-rnSplice (HsTypedSplice x hasParen splice_name expr)
- = do { loc <- getSrcSpanM
- ; n' <- newLocalBndrRn (L loc splice_name)
- ; (expr', fvs) <- rnLExpr expr
- ; return (HsTypedSplice x hasParen n' expr', fvs) }
-
-rnSplice (HsUntypedSplice x hasParen splice_name expr)
- = do { loc <- getSrcSpanM
- ; n' <- newLocalBndrRn (L loc splice_name)
- ; (expr', fvs) <- rnLExpr expr
- ; return (HsUntypedSplice x hasParen n' expr', fvs) }
-
-rnSplice (HsQuasiQuote x splice_name quoter q_loc quote)
- = do { loc <- getSrcSpanM
- ; splice_name' <- newLocalBndrRn (L loc splice_name)
-
- -- Rename the quoter; akin to the HsVar case of rnExpr
- ; quoter' <- lookupOccRn quoter
- ; this_mod <- getModule
- ; when (nameIsLocalOrFrom this_mod quoter') $
- checkThLocalName quoter'
-
- ; return (HsQuasiQuote x splice_name' quoter' q_loc quote
- , unitFV quoter') }
-
-rnSplice splice@(HsSpliced {}) = pprPanic "rnSplice" (ppr splice)
-rnSplice splice@(HsSplicedT {}) = pprPanic "rnSplice" (ppr splice)
-rnSplice (XSplice nec) = noExtCon nec
-
----------------------
-rnSpliceExpr :: HsSplice GhcPs -> RnM (HsExpr GhcRn, FreeVars)
-rnSpliceExpr splice
- = rnSpliceGen run_expr_splice pend_expr_splice splice
- where
- pend_expr_splice :: HsSplice GhcRn -> (PendingRnSplice, HsExpr GhcRn)
- pend_expr_splice rn_splice
- = (makePending UntypedExpSplice rn_splice, HsSpliceE noExtField rn_splice)
-
- run_expr_splice :: HsSplice GhcRn -> RnM (HsExpr GhcRn, FreeVars)
- run_expr_splice rn_splice
- | isTypedSplice rn_splice -- Run it later, in the type checker
- = do { -- Ugh! See Note [Splices] above
- traceRn "rnSpliceExpr: typed expression splice" empty
- ; lcl_rdr <- getLocalRdrEnv
- ; gbl_rdr <- getGlobalRdrEnv
- ; let gbl_names = mkNameSet [gre_name gre | gre <- globalRdrEnvElts gbl_rdr
- , isLocalGRE gre]
- lcl_names = mkNameSet (localRdrEnvElts lcl_rdr)
-
- ; return (HsSpliceE noExtField rn_splice, lcl_names `plusFV` gbl_names) }
-
- | otherwise -- Run it here, see Note [Running splices in the Renamer]
- = do { traceRn "rnSpliceExpr: untyped expression splice" empty
- ; (rn_expr, mod_finalizers) <-
- runRnSplice UntypedExpSplice runMetaE ppr rn_splice
- ; (lexpr3, fvs) <- checkNoErrs (rnLExpr rn_expr)
- -- See Note [Delaying modFinalizers in untyped splices].
- ; return ( HsPar noExtField $ HsSpliceE noExtField
- . HsSpliced noExtField (ThModFinalizers mod_finalizers)
- . HsSplicedExpr <$>
- lexpr3
- , fvs)
- }
-
-{- Note [Running splices in the Renamer]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Splices used to be run in the typechecker, which led to (#4364). Since the
-renamer must decide which expressions depend on which others, and it cannot
-reliably do this for arbitrary splices, we used to conservatively say that
-splices depend on all other expressions in scope. Unfortunately, this led to
-the problem of cyclic type declarations seen in (#4364). Instead, by
-running splices in the renamer, we side-step the problem of determining
-dependencies: by the time the dependency analysis happens, any splices have
-already been run, and expression dependencies can be determined as usual.
-
-However, see (#9813), for an example where we would like to run splices
-*after* performing dependency analysis (that is, after renaming). It would be
-desirable to typecheck "non-splicy" expressions (those expressions that do not
-contain splices directly or via dependence on an expression that does) before
-"splicy" expressions, such that types/expressions within the same declaration
-group would be available to `reify` calls, for example consider the following:
-
-> module M where
-> data D = C
-> f = 1
-> g = $(mapM reify ['f, 'D, ''C] ...)
-
-Compilation of this example fails since D/C/f are not in the type environment
-and thus cannot be reified as they have not been typechecked by the time the
-splice is renamed and thus run.
-
-These requirements are at odds: we do not want to run splices in the renamer as
-we wish to first determine dependencies and typecheck certain expressions,
-making them available to reify, but cannot accurately determine dependencies
-without running splices in the renamer!
-
-Indeed, the conclusion of (#9813) was that it is not worth the complexity
-to try and
- a) implement and maintain the code for renaming/typechecking non-splicy
- expressions before splicy expressions,
- b) explain to TH users which expressions are/not available to reify at any
- given point.
-
--}
-
-{- Note [Delaying modFinalizers in untyped splices]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When splices run in the renamer, 'reify' does not have access to the local
-type environment (#11832, [1]).
-
-For instance, in
-
-> let x = e in $(reify (mkName "x") >>= runIO . print >> [| return () |])
-
-'reify' cannot find @x@, because the local type environment is not yet
-populated. To address this, we allow 'reify' execution to be deferred with
-'addModFinalizer'.
-
-> let x = e in $(do addModFinalizer (reify (mkName "x") >>= runIO . print)
- [| return () |]
- )
-
-The finalizer is run with the local type environment when type checking is
-complete.
-
-Since the local type environment is not available in the renamer, we annotate
-the tree at the splice point [2] with @HsSpliceE (HsSpliced finalizers e)@ where
-@e@ is the result of splicing and @finalizers@ are the finalizers that have been
-collected during evaluation of the splice [3]. In our example,
-
-> HsLet
-> (x = e)
-> (HsSpliceE $ HsSpliced [reify (mkName "x") >>= runIO . print]
-> (HsSplicedExpr $ return ())
-> )
-
-When the typechecker finds the annotation, it inserts the finalizers in the
-global environment and exposes the current local environment to them [4, 5, 6].
-
-> addModFinalizersWithLclEnv [reify (mkName "x") >>= runIO . print]
-
-References:
-
-[1] https://gitlab.haskell.org/ghc/ghc/wikis/template-haskell/reify
-[2] 'rnSpliceExpr'
-[3] 'TcSplice.qAddModFinalizer'
-[4] 'TcExpr.tcExpr' ('HsSpliceE' ('HsSpliced' ...))
-[5] 'TcHsType.tc_hs_type' ('HsSpliceTy' ('HsSpliced' ...))
-[6] 'TcPat.tc_pat' ('SplicePat' ('HsSpliced' ...))
-
--}
-
-----------------------
-rnSpliceType :: HsSplice GhcPs -> RnM (HsType GhcRn, FreeVars)
-rnSpliceType splice
- = rnSpliceGen run_type_splice pend_type_splice splice
- where
- pend_type_splice rn_splice
- = ( makePending UntypedTypeSplice rn_splice
- , HsSpliceTy noExtField rn_splice)
-
- run_type_splice rn_splice
- = do { traceRn "rnSpliceType: untyped type splice" empty
- ; (hs_ty2, mod_finalizers) <-
- runRnSplice UntypedTypeSplice runMetaT ppr rn_splice
- ; (hs_ty3, fvs) <- do { let doc = SpliceTypeCtx hs_ty2
- ; checkNoErrs $ rnLHsType doc hs_ty2 }
- -- checkNoErrs: see Note [Renamer errors]
- -- See Note [Delaying modFinalizers in untyped splices].
- ; return ( HsParTy noExtField
- $ HsSpliceTy noExtField
- . HsSpliced noExtField (ThModFinalizers mod_finalizers)
- . HsSplicedTy <$>
- hs_ty3
- , fvs
- ) }
- -- Wrap the result of the splice in parens so that we don't
- -- lose the outermost location set by runQuasiQuote (#7918)
-
-{- Note [Partial Type Splices]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Partial Type Signatures are partially supported in TH type splices: only
-anonymous wild cards are allowed.
-
- -- ToDo: SLPJ says: I don't understand all this
-
-Normally, named wild cards are collected before renaming a (partial) type
-signature. However, TH type splices are run during renaming, i.e. after the
-initial traversal, leading to out of scope errors for named wild cards. We
-can't just extend the initial traversal to collect the named wild cards in TH
-type splices, as we'd need to expand them, which is supposed to happen only
-once, during renaming.
-
-Similarly, the extra-constraints wild card is handled right before renaming
-too, and is therefore also not supported in a TH type splice. Another reason
-to forbid extra-constraints wild cards in TH type splices is that a single
-signature can contain many TH type splices, whereas it mustn't contain more
-than one extra-constraints wild card. Enforcing would this be hard the way
-things are currently organised.
-
-Anonymous wild cards pose no problem, because they start out without names and
-are given names during renaming. These names are collected right after
-renaming. The names generated for anonymous wild cards in TH type splices will
-thus be collected as well.
-
-For more details about renaming wild cards, see RnTypes.rnHsSigWcType
-
-Note that partial type signatures are fully supported in TH declaration
-splices, e.g.:
-
- [d| foo :: _ => _
- foo x y = x == y |]
-
-This is because in this case, the partial type signature can be treated as a
-whole signature, instead of as an arbitrary type.
-
--}
-
-
-----------------------
--- | Rename a splice pattern. See Note [rnSplicePat]
-rnSplicePat :: HsSplice GhcPs -> RnM ( Either (Pat GhcPs) (Pat GhcRn)
- , FreeVars)
-rnSplicePat splice
- = rnSpliceGen run_pat_splice pend_pat_splice splice
- where
- pend_pat_splice :: HsSplice GhcRn ->
- (PendingRnSplice, Either b (Pat GhcRn))
- pend_pat_splice rn_splice
- = (makePending UntypedPatSplice rn_splice
- , Right (SplicePat noExtField rn_splice))
-
- run_pat_splice :: HsSplice GhcRn ->
- RnM (Either (Pat GhcPs) (Pat GhcRn), FreeVars)
- run_pat_splice rn_splice
- = do { traceRn "rnSplicePat: untyped pattern splice" empty
- ; (pat, mod_finalizers) <-
- runRnSplice UntypedPatSplice runMetaP ppr rn_splice
- -- See Note [Delaying modFinalizers in untyped splices].
- ; return ( Left $ ParPat noExtField $ ((SplicePat noExtField)
- . HsSpliced noExtField (ThModFinalizers mod_finalizers)
- . HsSplicedPat) `mapLoc`
- pat
- , emptyFVs
- ) }
- -- Wrap the result of the quasi-quoter in parens so that we don't
- -- lose the outermost location set by runQuasiQuote (#7918)
-
-----------------------
-rnSpliceDecl :: SpliceDecl GhcPs -> RnM (SpliceDecl GhcRn, FreeVars)
-rnSpliceDecl (SpliceDecl _ (L loc splice) flg)
- = rnSpliceGen run_decl_splice pend_decl_splice splice
- where
- pend_decl_splice rn_splice
- = ( makePending UntypedDeclSplice rn_splice
- , SpliceDecl noExtField (L loc rn_splice) flg)
-
- run_decl_splice rn_splice = pprPanic "rnSpliceDecl" (ppr rn_splice)
-rnSpliceDecl (XSpliceDecl nec) = noExtCon nec
-
-rnTopSpliceDecls :: HsSplice GhcPs -> RnM ([LHsDecl GhcPs], FreeVars)
--- Declaration splice at the very top level of the module
-rnTopSpliceDecls splice
- = do { (rn_splice, fvs) <- checkNoErrs $
- setStage (Splice Untyped) $
- rnSplice splice
- -- As always, be sure to checkNoErrs above lest we end up with
- -- holes making it to typechecking, hence #12584.
- --
- -- Note that we cannot call checkNoErrs for the whole duration
- -- of rnTopSpliceDecls. The reason is that checkNoErrs changes
- -- the local environment to temporarily contain a new
- -- reference to store errors, and add_mod_finalizers would
- -- cause this reference to be stored after checkNoErrs finishes.
- -- This is checked by test TH_finalizer.
- ; traceRn "rnTopSpliceDecls: untyped declaration splice" empty
- ; (decls, mod_finalizers) <- checkNoErrs $
- runRnSplice UntypedDeclSplice runMetaD ppr_decls rn_splice
- ; add_mod_finalizers_now mod_finalizers
- ; return (decls,fvs) }
- where
- ppr_decls :: [LHsDecl GhcPs] -> SDoc
- ppr_decls ds = vcat (map ppr ds)
-
- -- Adds finalizers to the global environment instead of delaying them
- -- to the type checker.
- --
- -- Declaration splices do not have an interesting local environment so
- -- there is no point in delaying them.
- --
- -- See Note [Delaying modFinalizers in untyped splices].
- add_mod_finalizers_now :: [ForeignRef (TH.Q ())] -> TcRn ()
- add_mod_finalizers_now [] = return ()
- add_mod_finalizers_now mod_finalizers = do
- th_modfinalizers_var <- fmap tcg_th_modfinalizers getGblEnv
- env <- getLclEnv
- updTcRef th_modfinalizers_var $ \fins ->
- (env, ThModFinalizers mod_finalizers) : fins
-
-
-{-
-Note [rnSplicePat]
-~~~~~~~~~~~~~~~~~~
-Renaming a pattern splice is a bit tricky, because we need the variables
-bound in the pattern to be in scope in the RHS of the pattern. This scope
-management is effectively done by using continuation-passing style in
-RnPat, through the CpsRn monad. We don't wish to be in that monad here
-(it would create import cycles and generally conflict with renaming other
-splices), so we really want to return a (Pat RdrName) -- the result of
-running the splice -- which can then be further renamed in RnPat, in
-the CpsRn monad.
-
-The problem is that if we're renaming a splice within a bracket, we
-*don't* want to run the splice now. We really do just want to rename
-it to an HsSplice Name. Of course, then we can't know what variables
-are bound within the splice. So we accept any unbound variables and
-rename them again when the bracket is spliced in. If a variable is brought
-into scope by a pattern splice all is fine. If it is not then an error is
-reported.
-
-In any case, when we're done in rnSplicePat, we'll either have a
-Pat RdrName (the result of running a top-level splice) or a Pat Name
-(the renamed nested splice). Thus, the awkward return type of
-rnSplicePat.
--}
-
-spliceCtxt :: HsSplice GhcPs -> SDoc
-spliceCtxt splice
- = hang (text "In the" <+> what) 2 (ppr splice)
- where
- what = case splice of
- HsUntypedSplice {} -> text "untyped splice:"
- HsTypedSplice {} -> text "typed splice:"
- HsQuasiQuote {} -> text "quasi-quotation:"
- HsSpliced {} -> text "spliced expression:"
- HsSplicedT {} -> text "spliced expression:"
- XSplice {} -> text "spliced expression:"
-
--- | The splice data to be logged
-data SpliceInfo
- = SpliceInfo
- { spliceDescription :: String
- , spliceSource :: Maybe (LHsExpr GhcRn) -- Nothing <=> top-level decls
- -- added by addTopDecls
- , spliceIsDecl :: Bool -- True <=> put the generate code in a file
- -- when -dth-dec-file is on
- , spliceGenerated :: SDoc
- }
- -- Note that 'spliceSource' is *renamed* but not *typechecked*
- -- Reason (a) less typechecking crap
- -- (b) data constructors after type checking have been
- -- changed to their *wrappers*, and that makes them
- -- print always fully qualified
-
--- | outputs splice information for 2 flags which have different output formats:
--- `-ddump-splices` and `-dth-dec-file`
-traceSplice :: SpliceInfo -> TcM ()
-traceSplice (SpliceInfo { spliceDescription = sd, spliceSource = mb_src
- , spliceGenerated = gen, spliceIsDecl = is_decl })
- = do { loc <- case mb_src of
- Nothing -> getSrcSpanM
- Just (L loc _) -> return loc
- ; traceOptTcRn Opt_D_dump_splices (spliceDebugDoc loc)
-
- ; when is_decl $ -- Raw material for -dth-dec-file
- do { dflags <- getDynFlags
- ; liftIO $ dumpIfSet_dyn_printer alwaysQualify dflags Opt_D_th_dec_file
- "" FormatHaskell (spliceCodeDoc loc) } }
- where
- -- `-ddump-splices`
- spliceDebugDoc :: SrcSpan -> SDoc
- spliceDebugDoc loc
- = let code = case mb_src of
- Nothing -> ending
- Just e -> nest 2 (ppr (stripParensHsExpr e)) : ending
- ending = [ text "======>", nest 2 gen ]
- in hang (ppr loc <> colon <+> text "Splicing" <+> text sd)
- 2 (sep code)
-
- -- `-dth-dec-file`
- spliceCodeDoc :: SrcSpan -> SDoc
- spliceCodeDoc loc
- = vcat [ text "--" <+> ppr loc <> colon <+> text "Splicing" <+> text sd
- , gen ]
-
-illegalTypedSplice :: SDoc
-illegalTypedSplice = text "Typed splices may not appear in untyped brackets"
-
-illegalUntypedSplice :: SDoc
-illegalUntypedSplice = text "Untyped splices may not appear in typed brackets"
-
-checkThLocalName :: Name -> RnM ()
-checkThLocalName name
- | isUnboundName name -- Do not report two errors for
- = return () -- $(not_in_scope args)
-
- | otherwise
- = do { traceRn "checkThLocalName" (ppr name)
- ; mb_local_use <- getStageAndBindLevel name
- ; case mb_local_use of {
- Nothing -> return () ; -- Not a locally-bound thing
- Just (top_lvl, bind_lvl, use_stage) ->
- do { let use_lvl = thLevel use_stage
- ; checkWellStaged (quotes (ppr name)) bind_lvl use_lvl
- ; traceRn "checkThLocalName" (ppr name <+> ppr bind_lvl
- <+> ppr use_stage
- <+> ppr use_lvl)
- ; checkCrossStageLifting top_lvl bind_lvl use_stage use_lvl name } } }
-
---------------------------------------
-checkCrossStageLifting :: TopLevelFlag -> ThLevel -> ThStage -> ThLevel
- -> Name -> TcM ()
--- We are inside brackets, and (use_lvl > bind_lvl)
--- Now we must check whether there's a cross-stage lift to do
--- Examples \x -> [| x |]
--- [| map |]
---
--- This code is similar to checkCrossStageLifting in TcExpr, but
--- this is only run on *untyped* brackets.
-
-checkCrossStageLifting top_lvl bind_lvl use_stage use_lvl name
- | Brack _ (RnPendingUntyped ps_var) <- use_stage -- Only for untyped brackets
- , use_lvl > bind_lvl -- Cross-stage condition
- = check_cross_stage_lifting top_lvl name ps_var
- | otherwise
- = return ()
-
-check_cross_stage_lifting :: TopLevelFlag -> Name -> TcRef [PendingRnSplice] -> TcM ()
-check_cross_stage_lifting top_lvl name ps_var
- | isTopLevel top_lvl
- -- Top-level identifiers in this module,
- -- (which have External Names)
- -- are just like the imported case:
- -- no need for the 'lifting' treatment
- -- E.g. this is fine:
- -- f x = x
- -- g y = [| f 3 |]
- = when (isExternalName name) (keepAlive name)
- -- See Note [Keeping things alive for Template Haskell]
-
- | otherwise
- = -- Nested identifiers, such as 'x' in
- -- E.g. \x -> [| h x |]
- -- We must behave as if the reference to x was
- -- h $(lift x)
- -- We use 'x' itself as the SplicePointName, used by
- -- the desugarer to stitch it all back together.
- -- If 'x' occurs many times we may get many identical
- -- bindings of the same SplicePointName, but that doesn't
- -- matter, although it's a mite untidy.
- do { traceRn "checkCrossStageLifting" (ppr name)
-
- -- Construct the (lift x) expression
- ; let lift_expr = nlHsApp (nlHsVar liftName) (nlHsVar name)
- pend_splice = PendingRnSplice UntypedExpSplice name lift_expr
-
- -- Update the pending splices
- ; ps <- readMutVar ps_var
- ; writeMutVar ps_var (pend_splice : ps) }
-
-{-
-Note [Keeping things alive for Template Haskell]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider
- f x = x+1
- g y = [| f 3 |]
-
-Here 'f' is referred to from inside the bracket, which turns into data
-and mentions only f's *name*, not 'f' itself. So we need some other
-way to keep 'f' alive, lest it get dropped as dead code. That's what
-keepAlive does. It puts it in the keep-alive set, which subsequently
-ensures that 'f' stays as a top level binding.
-
-This must be done by the renamer, not the type checker (as of old),
-because the type checker doesn't typecheck the body of untyped
-brackets (#8540).
-
-A thing can have a bind_lvl of outerLevel, but have an internal name:
- foo = [d| op = 3
- bop = op + 1 |]
-Here the bind_lvl of 'op' is (bogusly) outerLevel, even though it is
-bound inside a bracket. That is because we don't even even record
-binding levels for top-level things; the binding levels are in the
-LocalRdrEnv.
-
-So the occurrence of 'op' in the rhs of 'bop' looks a bit like a
-cross-stage thing, but it isn't really. And in fact we never need
-to do anything here for top-level bound things, so all is fine, if
-a bit hacky.
-
-For these chaps (which have Internal Names) we don't want to put
-them in the keep-alive set.
-
-Note [Quoting names]
-~~~~~~~~~~~~~~~~~~~~
-A quoted name 'n is a bit like a quoted expression [| n |], except that we
-have no cross-stage lifting (c.f. TcExpr.thBrackId). So, after incrementing
-the use-level to account for the brackets, the cases are:
-
- bind > use Error
- bind = use+1 OK
- bind < use
- Imported things OK
- Top-level things OK
- Non-top-level Error
-
-where 'use' is the binding level of the 'n quote. (So inside the implied
-bracket the level would be use+1.)
-
-Examples:
-
- f 'map -- OK; also for top-level defns of this module
-
- \x. f 'x -- Not ok (bind = 1, use = 1)
- -- (whereas \x. f [| x |] might have been ok, by
- -- cross-stage lifting
-
- \y. [| \x. $(f 'y) |] -- Not ok (bind =1, use = 1)
-
- [| \x. $(f 'x) |] -- OK (bind = 2, use = 1)
--}
diff --git a/compiler/rename/RnSplice.hs-boot b/compiler/rename/RnSplice.hs-boot
deleted file mode 100644
index cd6021027e..0000000000
--- a/compiler/rename/RnSplice.hs-boot
+++ /dev/null
@@ -1,14 +0,0 @@
-module RnSplice where
-
-import GhcPrelude
-import GHC.Hs
-import TcRnMonad
-import NameSet
-
-
-rnSpliceType :: HsSplice GhcPs -> RnM (HsType GhcRn, FreeVars)
-rnSplicePat :: HsSplice GhcPs -> RnM ( Either (Pat GhcPs) (Pat GhcRn)
- , FreeVars )
-rnSpliceDecl :: SpliceDecl GhcPs -> RnM (SpliceDecl GhcRn, FreeVars)
-
-rnTopSpliceDecls :: HsSplice GhcPs -> RnM ([LHsDecl GhcPs], FreeVars)
diff --git a/compiler/rename/RnTypes.hs b/compiler/rename/RnTypes.hs
deleted file mode 100644
index 724dea866d..0000000000
--- a/compiler/rename/RnTypes.hs
+++ /dev/null
@@ -1,1784 +0,0 @@
-{-
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-
-\section[RnSource]{Main pass of renamer}
--}
-
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ViewPatterns #-}
-{-# LANGUAGE TypeFamilies #-}
-
-module RnTypes (
- -- Type related stuff
- rnHsType, rnLHsType, rnLHsTypes, rnContext,
- rnHsKind, rnLHsKind, rnLHsTypeArgs,
- rnHsSigType, rnHsWcType,
- HsSigWcTypeScoping(..), rnHsSigWcType, rnHsSigWcTypeScoped,
- newTyVarNameRn,
- rnConDeclFields,
- rnLTyVar,
-
- -- Precence related stuff
- mkOpAppRn, mkNegAppRn, mkOpFormRn, mkConOpPatRn,
- checkPrecMatch, checkSectionPrec,
-
- -- Binding related stuff
- bindLHsTyVarBndr, bindLHsTyVarBndrs, rnImplicitBndrs,
- bindSigTyVarsFV, bindHsQTyVars, bindLRdrNames,
- extractHsTyRdrTyVars, extractHsTyRdrTyVarsKindVars,
- extractHsTysRdrTyVarsDups,
- extractRdrKindSigVars, extractDataDefnKindVars,
- extractHsTvBndrs, extractHsTyArgRdrKiTyVarsDup,
- nubL, elemRdr
- ) where
-
-import GhcPrelude
-
-import {-# SOURCE #-} RnSplice( rnSpliceType )
-
-import DynFlags
-import GHC.Hs
-import RnHsDoc ( rnLHsDoc, rnMbLHsDoc )
-import RnEnv
-import RnUtils ( HsDocContext(..), withHsDocContext, mapFvRn
- , pprHsDocContext, bindLocalNamesFV, typeAppErr
- , newLocalBndrRn, checkDupRdrNames, checkShadowedRdrNames )
-import RnFixity ( lookupFieldFixityRn, lookupFixityRn
- , lookupTyFixityRn )
-import TcRnMonad
-import RdrName
-import PrelNames
-import TysPrim ( funTyConName )
-import Name
-import SrcLoc
-import NameSet
-import FieldLabel
-
-import Util
-import ListSetOps ( deleteBys )
-import BasicTypes ( compareFixity, funTyFixity, negateFixity
- , Fixity(..), FixityDirection(..), LexicalFixity(..)
- , TypeOrKind(..) )
-import Outputable
-import FastString
-import Maybes
-import qualified GHC.LanguageExtensions as LangExt
-
-import Data.List ( nubBy, partition, (\\) )
-import Control.Monad ( unless, when )
-
-#include "HsVersions.h"
-
-{-
-These type renamers are in a separate module, rather than in (say) RnSource,
-to break several loop.
-
-*********************************************************
-* *
- HsSigWcType (i.e with wildcards)
-* *
-*********************************************************
--}
-
-data HsSigWcTypeScoping = AlwaysBind
- -- ^ Always bind any free tyvars of the given type,
- -- regardless of whether we have a forall at the top
- | BindUnlessForall
- -- ^ Unless there's forall at the top, do the same
- -- thing as 'AlwaysBind'
- | NeverBind
- -- ^ Never bind any free tyvars
-
-rnHsSigWcType :: HsSigWcTypeScoping -> HsDocContext -> LHsSigWcType GhcPs
- -> RnM (LHsSigWcType GhcRn, FreeVars)
-rnHsSigWcType scoping doc sig_ty
- = rn_hs_sig_wc_type scoping doc sig_ty $ \sig_ty' ->
- return (sig_ty', emptyFVs)
-
-rnHsSigWcTypeScoped :: HsSigWcTypeScoping
- -- AlwaysBind: for pattern type sigs and rules we /do/ want
- -- to bring those type variables into scope, even
- -- if there's a forall at the top which usually
- -- stops that happening
- -- e.g \ (x :: forall a. a-> b) -> e
- -- Here we do bring 'b' into scope
- -> HsDocContext -> LHsSigWcType GhcPs
- -> (LHsSigWcType GhcRn -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
--- Used for
--- - Signatures on binders in a RULE
--- - Pattern type signatures
--- Wildcards are allowed
--- type signatures on binders only allowed with ScopedTypeVariables
-rnHsSigWcTypeScoped scoping ctx sig_ty thing_inside
- = do { ty_sig_okay <- xoptM LangExt.ScopedTypeVariables
- ; checkErr ty_sig_okay (unexpectedTypeSigErr sig_ty)
- ; rn_hs_sig_wc_type scoping ctx sig_ty thing_inside
- }
-
-rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> LHsSigWcType GhcPs
- -> (LHsSigWcType GhcRn -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
--- rn_hs_sig_wc_type is used for source-language type signatures
-rn_hs_sig_wc_type scoping ctxt
- (HsWC { hswc_body = HsIB { hsib_body = hs_ty }})
- thing_inside
- = do { free_vars <- extractFilteredRdrTyVarsDups hs_ty
- ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars
- ; let nwc_rdrs = nubL nwc_rdrs'
- bind_free_tvs = case scoping of
- AlwaysBind -> True
- BindUnlessForall -> not (isLHsForAllTy hs_ty)
- NeverBind -> False
- ; rnImplicitBndrs bind_free_tvs tv_rdrs $ \ vars ->
- do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty
- ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = ib_ty' }
- ib_ty' = HsIB { hsib_ext = vars
- , hsib_body = hs_ty' }
- ; (res, fvs2) <- thing_inside sig_ty'
- ; return (res, fvs1 `plusFV` fvs2) } }
-rn_hs_sig_wc_type _ _ (HsWC _ (XHsImplicitBndrs nec)) _
- = noExtCon nec
-rn_hs_sig_wc_type _ _ (XHsWildCardBndrs nec) _
- = noExtCon nec
-
-rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars)
-rnHsWcType ctxt (HsWC { hswc_body = hs_ty })
- = do { free_vars <- extractFilteredRdrTyVars hs_ty
- ; (nwc_rdrs, _) <- partition_nwcs free_vars
- ; (wcs, hs_ty', fvs) <- rnWcBody ctxt nwc_rdrs hs_ty
- ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = hs_ty' }
- ; return (sig_ty', fvs) }
-rnHsWcType _ (XHsWildCardBndrs nec) = noExtCon nec
-
-rnWcBody :: HsDocContext -> [Located RdrName] -> LHsType GhcPs
- -> RnM ([Name], LHsType GhcRn, FreeVars)
-rnWcBody ctxt nwc_rdrs hs_ty
- = do { nwcs <- mapM newLocalBndrRn nwc_rdrs
- ; let env = RTKE { rtke_level = TypeLevel
- , rtke_what = RnTypeBody
- , rtke_nwcs = mkNameSet nwcs
- , rtke_ctxt = ctxt }
- ; (hs_ty', fvs) <- bindLocalNamesFV nwcs $
- rn_lty env hs_ty
- ; return (nwcs, hs_ty', fvs) }
- where
- rn_lty env (L loc hs_ty)
- = setSrcSpan loc $
- do { (hs_ty', fvs) <- rn_ty env hs_ty
- ; return (L loc hs_ty', fvs) }
-
- rn_ty :: RnTyKiEnv -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars)
- -- A lot of faff just to allow the extra-constraints wildcard to appear
- rn_ty env hs_ty@(HsForAllTy { hst_fvf = fvf, hst_bndrs = tvs
- , hst_body = hs_body })
- = bindLHsTyVarBndrs (rtke_ctxt env) (Just $ inTypeDoc hs_ty) Nothing tvs $ \ tvs' ->
- do { (hs_body', fvs) <- rn_lty env hs_body
- ; return (HsForAllTy { hst_fvf = fvf, hst_xforall = noExtField
- , hst_bndrs = tvs', hst_body = hs_body' }
- , fvs) }
-
- rn_ty env (HsQualTy { hst_ctxt = L cx hs_ctxt
- , hst_body = hs_ty })
- | Just (hs_ctxt1, hs_ctxt_last) <- snocView hs_ctxt
- , L lx (HsWildCardTy _) <- ignoreParens hs_ctxt_last
- = do { (hs_ctxt1', fvs1) <- mapFvRn (rn_top_constraint env) hs_ctxt1
- ; setSrcSpan lx $ checkExtraConstraintWildCard env hs_ctxt1
- ; let hs_ctxt' = hs_ctxt1' ++ [L lx (HsWildCardTy noExtField)]
- ; (hs_ty', fvs2) <- rnLHsTyKi env hs_ty
- ; return (HsQualTy { hst_xqual = noExtField
- , hst_ctxt = L cx hs_ctxt', hst_body = hs_ty' }
- , fvs1 `plusFV` fvs2) }
-
- | otherwise
- = do { (hs_ctxt', fvs1) <- mapFvRn (rn_top_constraint env) hs_ctxt
- ; (hs_ty', fvs2) <- rnLHsTyKi env hs_ty
- ; return (HsQualTy { hst_xqual = noExtField
- , hst_ctxt = L cx hs_ctxt'
- , hst_body = hs_ty' }
- , fvs1 `plusFV` fvs2) }
-
- rn_ty env hs_ty = rnHsTyKi env hs_ty
-
- rn_top_constraint env = rnLHsTyKi (env { rtke_what = RnTopConstraint })
-
-
-checkExtraConstraintWildCard :: RnTyKiEnv -> HsContext GhcPs -> RnM ()
--- Rename the extra-constraint spot in a type signature
--- (blah, _) => type
--- Check that extra-constraints are allowed at all, and
--- if so that it's an anonymous wildcard
-checkExtraConstraintWildCard env hs_ctxt
- = checkWildCard env mb_bad
- where
- mb_bad | not (extraConstraintWildCardsAllowed env)
- = Just base_msg
- -- Currently, we do not allow wildcards in their full glory in
- -- standalone deriving declarations. We only allow a single
- -- extra-constraints wildcard à la:
- --
- -- deriving instance _ => Eq (Foo a)
- --
- -- i.e., we don't support things like
- --
- -- deriving instance (Eq a, _) => Eq (Foo a)
- | DerivDeclCtx {} <- rtke_ctxt env
- , not (null hs_ctxt)
- = Just deriv_decl_msg
- | otherwise
- = Nothing
-
- base_msg = text "Extra-constraint wildcard" <+> quotes pprAnonWildCard
- <+> text "not allowed"
-
- deriv_decl_msg
- = hang base_msg
- 2 (vcat [ text "except as the sole constraint"
- , nest 2 (text "e.g., deriving instance _ => Eq (Foo a)") ])
-
-extraConstraintWildCardsAllowed :: RnTyKiEnv -> Bool
-extraConstraintWildCardsAllowed env
- = case rtke_ctxt env of
- TypeSigCtx {} -> True
- ExprWithTySigCtx {} -> True
- DerivDeclCtx {} -> True
- StandaloneKindSigCtx {} -> False -- See Note [Wildcards in standalone kind signatures] in GHC/Hs/Decls
- _ -> False
-
--- | Finds free type and kind variables in a type,
--- without duplicates, and
--- without variables that are already in scope in LocalRdrEnv
--- NB: this includes named wildcards, which look like perfectly
--- ordinary type variables at this point
-extractFilteredRdrTyVars :: LHsType GhcPs -> RnM FreeKiTyVarsNoDups
-extractFilteredRdrTyVars hs_ty = filterInScopeM (extractHsTyRdrTyVars hs_ty)
-
--- | Finds free type and kind variables in a type,
--- with duplicates, but
--- without variables that are already in scope in LocalRdrEnv
--- NB: this includes named wildcards, which look like perfectly
--- ordinary type variables at this point
-extractFilteredRdrTyVarsDups :: LHsType GhcPs -> RnM FreeKiTyVarsWithDups
-extractFilteredRdrTyVarsDups hs_ty = filterInScopeM (extractHsTyRdrTyVarsDups hs_ty)
-
--- | When the NamedWildCards extension is enabled, partition_nwcs
--- removes type variables that start with an underscore from the
--- FreeKiTyVars in the argument and returns them in a separate list.
--- When the extension is disabled, the function returns the argument
--- and empty list. See Note [Renaming named wild cards]
-partition_nwcs :: FreeKiTyVars -> RnM ([Located RdrName], FreeKiTyVars)
-partition_nwcs free_vars
- = do { wildcards_enabled <- xoptM LangExt.NamedWildCards
- ; return $
- if wildcards_enabled
- then partition is_wildcard free_vars
- else ([], free_vars) }
- where
- is_wildcard :: Located RdrName -> Bool
- is_wildcard rdr = startsWithUnderscore (rdrNameOcc (unLoc rdr))
-
-{- Note [Renaming named wild cards]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Identifiers starting with an underscore are always parsed as type variables.
-It is only here in the renamer that we give the special treatment.
-See Note [The wildcard story for types] in GHC.Hs.Types.
-
-It's easy! When we collect the implicitly bound type variables, ready
-to bring them into scope, and NamedWildCards is on, we partition the
-variables into the ones that start with an underscore (the named
-wildcards) and the rest. Then we just add them to the hswc_wcs field
-of the HsWildCardBndrs structure, and we are done.
-
-
-*********************************************************
-* *
- HsSigtype (i.e. no wildcards)
-* *
-****************************************************** -}
-
-rnHsSigType :: HsDocContext
- -> TypeOrKind
- -> LHsSigType GhcPs
- -> RnM (LHsSigType GhcRn, FreeVars)
--- Used for source-language type signatures
--- that cannot have wildcards
-rnHsSigType ctx level (HsIB { hsib_body = hs_ty })
- = do { traceRn "rnHsSigType" (ppr hs_ty)
- ; vars <- extractFilteredRdrTyVarsDups hs_ty
- ; rnImplicitBndrs (not (isLHsForAllTy hs_ty)) vars $ \ vars ->
- do { (body', fvs) <- rnLHsTyKi (mkTyKiEnv ctx level RnTypeBody) hs_ty
-
- ; return ( HsIB { hsib_ext = vars
- , hsib_body = body' }
- , fvs ) } }
-rnHsSigType _ _ (XHsImplicitBndrs nec) = noExtCon nec
-
-rnImplicitBndrs :: Bool -- True <=> bring into scope any free type variables
- -- E.g. f :: forall a. a->b
- -- we do not want to bring 'b' into scope, hence False
- -- But f :: a -> b
- -- we want to bring both 'a' and 'b' into scope
- -> FreeKiTyVarsWithDups
- -- Free vars of hs_ty (excluding wildcards)
- -- May have duplicates, which is
- -- checked here
- -> ([Name] -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
-rnImplicitBndrs bind_free_tvs
- fvs_with_dups
- thing_inside
- = do { let fvs = nubL fvs_with_dups
- real_fvs | bind_free_tvs = fvs
- | otherwise = []
-
- ; traceRn "rnImplicitBndrs" $
- vcat [ ppr fvs_with_dups, ppr fvs, ppr real_fvs ]
-
- ; loc <- getSrcSpanM
- ; vars <- mapM (newLocalBndrRn . L loc . unLoc) real_fvs
-
- ; bindLocalNamesFV vars $
- thing_inside vars }
-
-{- ******************************************************
-* *
- LHsType and HsType
-* *
-****************************************************** -}
-
-{-
-rnHsType is here because we call it from loadInstDecl, and I didn't
-want a gratuitous knot.
-
-Note [Context quantification]
------------------------------
-Variables in type signatures are implicitly quantified
-when (1) they are in a type signature not beginning
-with "forall" or (2) in any qualified type T => R.
-We are phasing out (2) since it leads to inconsistencies
-(#4426):
-
-data A = A (a -> a) is an error
-data A = A (Eq a => a -> a) binds "a"
-data A = A (Eq a => a -> b) binds "a" and "b"
-data A = A (() => a -> b) binds "a" and "b"
-f :: forall a. a -> b is an error
-f :: forall a. () => a -> b is an error
-f :: forall a. a -> (() => b) binds "a" and "b"
-
-This situation is now considered to be an error. See rnHsTyKi for case
-HsForAllTy Qualified.
-
-Note [QualTy in kinds]
-~~~~~~~~~~~~~~~~~~~~~~
-I was wondering whether QualTy could occur only at TypeLevel. But no,
-we can have a qualified type in a kind too. Here is an example:
-
- type family F a where
- F Bool = Nat
- F Nat = Type
-
- type family G a where
- G Type = Type -> Type
- G () = Nat
-
- data X :: forall k1 k2. (F k1 ~ G k2) => k1 -> k2 -> Type where
- MkX :: X 'True '()
-
-See that k1 becomes Bool and k2 becomes (), so the equality is
-satisfied. If I write MkX :: X 'True 'False, compilation fails with a
-suitable message:
-
- MkX :: X 'True '()
- • Couldn't match kind ‘G Bool’ with ‘Nat’
- Expected kind: G Bool
- Actual kind: F Bool
-
-However: in a kind, the constraints in the QualTy must all be
-equalities; or at least, any kinds with a class constraint are
-uninhabited.
--}
-
-data RnTyKiEnv
- = RTKE { rtke_ctxt :: HsDocContext
- , rtke_level :: TypeOrKind -- Am I renaming a type or a kind?
- , rtke_what :: RnTyKiWhat -- And within that what am I renaming?
- , rtke_nwcs :: NameSet -- These are the in-scope named wildcards
- }
-
-data RnTyKiWhat = RnTypeBody
- | RnTopConstraint -- Top-level context of HsSigWcTypes
- | RnConstraint -- All other constraints
-
-instance Outputable RnTyKiEnv where
- ppr (RTKE { rtke_level = lev, rtke_what = what
- , rtke_nwcs = wcs, rtke_ctxt = ctxt })
- = text "RTKE"
- <+> braces (sep [ ppr lev, ppr what, ppr wcs
- , pprHsDocContext ctxt ])
-
-instance Outputable RnTyKiWhat where
- ppr RnTypeBody = text "RnTypeBody"
- ppr RnTopConstraint = text "RnTopConstraint"
- ppr RnConstraint = text "RnConstraint"
-
-mkTyKiEnv :: HsDocContext -> TypeOrKind -> RnTyKiWhat -> RnTyKiEnv
-mkTyKiEnv cxt level what
- = RTKE { rtke_level = level, rtke_nwcs = emptyNameSet
- , rtke_what = what, rtke_ctxt = cxt }
-
-isRnKindLevel :: RnTyKiEnv -> Bool
-isRnKindLevel (RTKE { rtke_level = KindLevel }) = True
-isRnKindLevel _ = False
-
---------------
-rnLHsType :: HsDocContext -> LHsType GhcPs -> RnM (LHsType GhcRn, FreeVars)
-rnLHsType ctxt ty = rnLHsTyKi (mkTyKiEnv ctxt TypeLevel RnTypeBody) ty
-
-rnLHsTypes :: HsDocContext -> [LHsType GhcPs] -> RnM ([LHsType GhcRn], FreeVars)
-rnLHsTypes doc tys = mapFvRn (rnLHsType doc) tys
-
-rnHsType :: HsDocContext -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars)
-rnHsType ctxt ty = rnHsTyKi (mkTyKiEnv ctxt TypeLevel RnTypeBody) ty
-
-rnLHsKind :: HsDocContext -> LHsKind GhcPs -> RnM (LHsKind GhcRn, FreeVars)
-rnLHsKind ctxt kind = rnLHsTyKi (mkTyKiEnv ctxt KindLevel RnTypeBody) kind
-
-rnHsKind :: HsDocContext -> HsKind GhcPs -> RnM (HsKind GhcRn, FreeVars)
-rnHsKind ctxt kind = rnHsTyKi (mkTyKiEnv ctxt KindLevel RnTypeBody) kind
-
--- renaming a type only, not a kind
-rnLHsTypeArg :: HsDocContext -> LHsTypeArg GhcPs
- -> RnM (LHsTypeArg GhcRn, FreeVars)
-rnLHsTypeArg ctxt (HsValArg ty)
- = do { (tys_rn, fvs) <- rnLHsType ctxt ty
- ; return (HsValArg tys_rn, fvs) }
-rnLHsTypeArg ctxt (HsTypeArg l ki)
- = do { (kis_rn, fvs) <- rnLHsKind ctxt ki
- ; return (HsTypeArg l kis_rn, fvs) }
-rnLHsTypeArg _ (HsArgPar sp)
- = return (HsArgPar sp, emptyFVs)
-
-rnLHsTypeArgs :: HsDocContext -> [LHsTypeArg GhcPs]
- -> RnM ([LHsTypeArg GhcRn], FreeVars)
-rnLHsTypeArgs doc args = mapFvRn (rnLHsTypeArg doc) args
-
---------------
-rnTyKiContext :: RnTyKiEnv -> LHsContext GhcPs
- -> RnM (LHsContext GhcRn, FreeVars)
-rnTyKiContext env (L loc cxt)
- = do { traceRn "rncontext" (ppr cxt)
- ; let env' = env { rtke_what = RnConstraint }
- ; (cxt', fvs) <- mapFvRn (rnLHsTyKi env') cxt
- ; return (L loc cxt', fvs) }
-
-rnContext :: HsDocContext -> LHsContext GhcPs
- -> RnM (LHsContext GhcRn, FreeVars)
-rnContext doc theta = rnTyKiContext (mkTyKiEnv doc TypeLevel RnConstraint) theta
-
---------------
-rnLHsTyKi :: RnTyKiEnv -> LHsType GhcPs -> RnM (LHsType GhcRn, FreeVars)
-rnLHsTyKi env (L loc ty)
- = setSrcSpan loc $
- do { (ty', fvs) <- rnHsTyKi env ty
- ; return (L loc ty', fvs) }
-
-rnHsTyKi :: RnTyKiEnv -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars)
-
-rnHsTyKi env ty@(HsForAllTy { hst_fvf = fvf, hst_bndrs = tyvars
- , hst_body = tau })
- = do { checkPolyKinds env ty
- ; bindLHsTyVarBndrs (rtke_ctxt env) (Just $ inTypeDoc ty)
- Nothing tyvars $ \ tyvars' ->
- do { (tau', fvs) <- rnLHsTyKi env tau
- ; return ( HsForAllTy { hst_fvf = fvf, hst_xforall = noExtField
- , hst_bndrs = tyvars' , hst_body = tau' }
- , fvs) } }
-
-rnHsTyKi env ty@(HsQualTy { hst_ctxt = lctxt, hst_body = tau })
- = do { checkPolyKinds env ty -- See Note [QualTy in kinds]
- ; (ctxt', fvs1) <- rnTyKiContext env lctxt
- ; (tau', fvs2) <- rnLHsTyKi env tau
- ; return (HsQualTy { hst_xqual = noExtField, hst_ctxt = ctxt'
- , hst_body = tau' }
- , fvs1 `plusFV` fvs2) }
-
-rnHsTyKi env (HsTyVar _ ip (L loc rdr_name))
- = do { when (isRnKindLevel env && isRdrTyVar rdr_name) $
- unlessXOptM LangExt.PolyKinds $ addErr $
- withHsDocContext (rtke_ctxt env) $
- vcat [ text "Unexpected kind variable" <+> quotes (ppr rdr_name)
- , text "Perhaps you intended to use PolyKinds" ]
- -- Any type variable at the kind level is illegal without the use
- -- of PolyKinds (see #14710)
- ; name <- rnTyVar env rdr_name
- ; return (HsTyVar noExtField ip (L loc name), unitFV name) }
-
-rnHsTyKi env ty@(HsOpTy _ ty1 l_op ty2)
- = setSrcSpan (getLoc l_op) $
- do { (l_op', fvs1) <- rnHsTyOp env ty l_op
- ; fix <- lookupTyFixityRn l_op'
- ; (ty1', fvs2) <- rnLHsTyKi env ty1
- ; (ty2', fvs3) <- rnLHsTyKi env ty2
- ; res_ty <- mkHsOpTyRn (\t1 t2 -> HsOpTy noExtField t1 l_op' t2)
- (unLoc l_op') fix ty1' ty2'
- ; return (res_ty, plusFVs [fvs1, fvs2, fvs3]) }
-
-rnHsTyKi env (HsParTy _ ty)
- = do { (ty', fvs) <- rnLHsTyKi env ty
- ; return (HsParTy noExtField ty', fvs) }
-
-rnHsTyKi env (HsBangTy _ b ty)
- = do { (ty', fvs) <- rnLHsTyKi env ty
- ; return (HsBangTy noExtField b ty', fvs) }
-
-rnHsTyKi env ty@(HsRecTy _ flds)
- = do { let ctxt = rtke_ctxt env
- ; fls <- get_fields ctxt
- ; (flds', fvs) <- rnConDeclFields ctxt fls flds
- ; return (HsRecTy noExtField flds', fvs) }
- where
- get_fields (ConDeclCtx names)
- = concatMapM (lookupConstructorFields . unLoc) names
- get_fields _
- = do { addErr (hang (text "Record syntax is illegal here:")
- 2 (ppr ty))
- ; return [] }
-
-rnHsTyKi env (HsFunTy _ ty1 ty2)
- = do { (ty1', fvs1) <- rnLHsTyKi env ty1
- -- Might find a for-all as the arg of a function type
- ; (ty2', fvs2) <- rnLHsTyKi env ty2
- -- Or as the result. This happens when reading Prelude.hi
- -- when we find return :: forall m. Monad m -> forall a. a -> m a
-
- -- Check for fixity rearrangements
- ; res_ty <- mkHsOpTyRn (HsFunTy noExtField) funTyConName funTyFixity ty1' ty2'
- ; return (res_ty, fvs1 `plusFV` fvs2) }
-
-rnHsTyKi env listTy@(HsListTy _ ty)
- = do { data_kinds <- xoptM LangExt.DataKinds
- ; when (not data_kinds && isRnKindLevel env)
- (addErr (dataKindsErr env listTy))
- ; (ty', fvs) <- rnLHsTyKi env ty
- ; return (HsListTy noExtField ty', fvs) }
-
-rnHsTyKi env t@(HsKindSig _ ty k)
- = do { checkPolyKinds env t
- ; kind_sigs_ok <- xoptM LangExt.KindSignatures
- ; unless kind_sigs_ok (badKindSigErr (rtke_ctxt env) ty)
- ; (ty', lhs_fvs) <- rnLHsTyKi env ty
- ; (k', sig_fvs) <- rnLHsTyKi (env { rtke_level = KindLevel }) k
- ; return (HsKindSig noExtField ty' k', lhs_fvs `plusFV` sig_fvs) }
-
--- Unboxed tuples are allowed to have poly-typed arguments. These
--- sometimes crop up as a result of CPR worker-wrappering dictionaries.
-rnHsTyKi env tupleTy@(HsTupleTy _ tup_con tys)
- = do { data_kinds <- xoptM LangExt.DataKinds
- ; when (not data_kinds && isRnKindLevel env)
- (addErr (dataKindsErr env tupleTy))
- ; (tys', fvs) <- mapFvRn (rnLHsTyKi env) tys
- ; return (HsTupleTy noExtField tup_con tys', fvs) }
-
-rnHsTyKi env sumTy@(HsSumTy _ tys)
- = do { data_kinds <- xoptM LangExt.DataKinds
- ; when (not data_kinds && isRnKindLevel env)
- (addErr (dataKindsErr env sumTy))
- ; (tys', fvs) <- mapFvRn (rnLHsTyKi env) tys
- ; return (HsSumTy noExtField tys', fvs) }
-
--- Ensure that a type-level integer is nonnegative (#8306, #8412)
-rnHsTyKi env tyLit@(HsTyLit _ t)
- = do { data_kinds <- xoptM LangExt.DataKinds
- ; unless data_kinds (addErr (dataKindsErr env tyLit))
- ; when (negLit t) (addErr negLitErr)
- ; checkPolyKinds env tyLit
- ; return (HsTyLit noExtField t, emptyFVs) }
- where
- negLit (HsStrTy _ _) = False
- negLit (HsNumTy _ i) = i < 0
- negLitErr = text "Illegal literal in type (type literals must not be negative):" <+> ppr tyLit
-
-rnHsTyKi env (HsAppTy _ ty1 ty2)
- = do { (ty1', fvs1) <- rnLHsTyKi env ty1
- ; (ty2', fvs2) <- rnLHsTyKi env ty2
- ; return (HsAppTy noExtField ty1' ty2', fvs1 `plusFV` fvs2) }
-
-rnHsTyKi env (HsAppKindTy l ty k)
- = do { kind_app <- xoptM LangExt.TypeApplications
- ; unless kind_app (addErr (typeAppErr "kind" k))
- ; (ty', fvs1) <- rnLHsTyKi env ty
- ; (k', fvs2) <- rnLHsTyKi (env {rtke_level = KindLevel }) k
- ; return (HsAppKindTy l ty' k', fvs1 `plusFV` fvs2) }
-
-rnHsTyKi env t@(HsIParamTy _ n ty)
- = do { notInKinds env t
- ; (ty', fvs) <- rnLHsTyKi env ty
- ; return (HsIParamTy noExtField n ty', fvs) }
-
-rnHsTyKi _ (HsStarTy _ isUni)
- = return (HsStarTy noExtField isUni, emptyFVs)
-
-rnHsTyKi _ (HsSpliceTy _ sp)
- = rnSpliceType sp
-
-rnHsTyKi env (HsDocTy _ ty haddock_doc)
- = do { (ty', fvs) <- rnLHsTyKi env ty
- ; haddock_doc' <- rnLHsDoc haddock_doc
- ; return (HsDocTy noExtField ty' haddock_doc', fvs) }
-
-rnHsTyKi _ (XHsType (NHsCoreTy ty))
- = return (XHsType (NHsCoreTy ty), emptyFVs)
- -- The emptyFVs probably isn't quite right
- -- but I don't think it matters
-
-rnHsTyKi env ty@(HsExplicitListTy _ ip tys)
- = do { checkPolyKinds env ty
- ; data_kinds <- xoptM LangExt.DataKinds
- ; unless data_kinds (addErr (dataKindsErr env ty))
- ; (tys', fvs) <- mapFvRn (rnLHsTyKi env) tys
- ; return (HsExplicitListTy noExtField ip tys', fvs) }
-
-rnHsTyKi env ty@(HsExplicitTupleTy _ tys)
- = do { checkPolyKinds env ty
- ; data_kinds <- xoptM LangExt.DataKinds
- ; unless data_kinds (addErr (dataKindsErr env ty))
- ; (tys', fvs) <- mapFvRn (rnLHsTyKi env) tys
- ; return (HsExplicitTupleTy noExtField tys', fvs) }
-
-rnHsTyKi env (HsWildCardTy _)
- = do { checkAnonWildCard env
- ; return (HsWildCardTy noExtField, emptyFVs) }
-
---------------
-rnTyVar :: RnTyKiEnv -> RdrName -> RnM Name
-rnTyVar env rdr_name
- = do { name <- lookupTypeOccRn rdr_name
- ; checkNamedWildCard env name
- ; return name }
-
-rnLTyVar :: Located RdrName -> RnM (Located Name)
--- Called externally; does not deal with wildards
-rnLTyVar (L loc rdr_name)
- = do { tyvar <- lookupTypeOccRn rdr_name
- ; return (L loc tyvar) }
-
---------------
-rnHsTyOp :: Outputable a
- => RnTyKiEnv -> a -> Located RdrName
- -> RnM (Located Name, FreeVars)
-rnHsTyOp env overall_ty (L loc op)
- = do { ops_ok <- xoptM LangExt.TypeOperators
- ; op' <- rnTyVar env op
- ; unless (ops_ok || op' `hasKey` eqTyConKey) $
- addErr (opTyErr op overall_ty)
- ; let l_op' = L loc op'
- ; return (l_op', unitFV op') }
-
---------------
-notAllowed :: SDoc -> SDoc
-notAllowed doc
- = text "Wildcard" <+> quotes doc <+> ptext (sLit "not allowed")
-
-checkWildCard :: RnTyKiEnv -> Maybe SDoc -> RnM ()
-checkWildCard env (Just doc)
- = addErr $ vcat [doc, nest 2 (text "in" <+> pprHsDocContext (rtke_ctxt env))]
-checkWildCard _ Nothing
- = return ()
-
-checkAnonWildCard :: RnTyKiEnv -> RnM ()
--- Report an error if an anonymous wildcard is illegal here
-checkAnonWildCard env
- = checkWildCard env mb_bad
- where
- mb_bad :: Maybe SDoc
- mb_bad | not (wildCardsAllowed env)
- = Just (notAllowed pprAnonWildCard)
- | otherwise
- = case rtke_what env of
- RnTypeBody -> Nothing
- RnTopConstraint -> Just constraint_msg
- RnConstraint -> Just constraint_msg
-
- constraint_msg = hang
- (notAllowed pprAnonWildCard <+> text "in a constraint")
- 2 hint_msg
- hint_msg = vcat [ text "except as the last top-level constraint of a type signature"
- , nest 2 (text "e.g f :: (Eq a, _) => blah") ]
-
-checkNamedWildCard :: RnTyKiEnv -> Name -> RnM ()
--- Report an error if a named wildcard is illegal here
-checkNamedWildCard env name
- = checkWildCard env mb_bad
- where
- mb_bad | not (name `elemNameSet` rtke_nwcs env)
- = Nothing -- Not a wildcard
- | not (wildCardsAllowed env)
- = Just (notAllowed (ppr name))
- | otherwise
- = case rtke_what env of
- RnTypeBody -> Nothing -- Allowed
- RnTopConstraint -> Nothing -- Allowed; e.g.
- -- f :: (Eq _a) => _a -> Int
- -- g :: (_a, _b) => T _a _b -> Int
- -- The named tyvars get filled in from elsewhere
- RnConstraint -> Just constraint_msg
- constraint_msg = notAllowed (ppr name) <+> text "in a constraint"
-
-wildCardsAllowed :: RnTyKiEnv -> Bool
--- ^ In what contexts are wildcards permitted
-wildCardsAllowed env
- = case rtke_ctxt env of
- TypeSigCtx {} -> True
- TypBrCtx {} -> True -- Template Haskell quoted type
- SpliceTypeCtx {} -> True -- Result of a Template Haskell splice
- ExprWithTySigCtx {} -> True
- PatCtx {} -> True
- RuleCtx {} -> True
- FamPatCtx {} -> True -- Not named wildcards though
- GHCiCtx {} -> True
- HsTypeCtx {} -> True
- StandaloneKindSigCtx {} -> False -- See Note [Wildcards in standalone kind signatures] in GHC/Hs/Decls
- _ -> False
-
-
-
----------------
--- | Ensures either that we're in a type or that -XPolyKinds is set
-checkPolyKinds :: Outputable ty
- => RnTyKiEnv
- -> ty -- ^ type
- -> RnM ()
-checkPolyKinds env ty
- | isRnKindLevel env
- = do { polykinds <- xoptM LangExt.PolyKinds
- ; unless polykinds $
- addErr (text "Illegal kind:" <+> ppr ty $$
- text "Did you mean to enable PolyKinds?") }
-checkPolyKinds _ _ = return ()
-
-notInKinds :: Outputable ty
- => RnTyKiEnv
- -> ty
- -> RnM ()
-notInKinds env ty
- | isRnKindLevel env
- = addErr (text "Illegal kind:" <+> ppr ty)
-notInKinds _ _ = return ()
-
-{- *****************************************************
-* *
- Binding type variables
-* *
-***************************************************** -}
-
-bindSigTyVarsFV :: [Name]
- -> RnM (a, FreeVars)
- -> RnM (a, FreeVars)
--- Used just before renaming the defn of a function
--- with a separate type signature, to bring its tyvars into scope
--- With no -XScopedTypeVariables, this is a no-op
-bindSigTyVarsFV tvs thing_inside
- = do { scoped_tyvars <- xoptM LangExt.ScopedTypeVariables
- ; if not scoped_tyvars then
- thing_inside
- else
- bindLocalNamesFV tvs thing_inside }
-
--- | Simply bring a bunch of RdrNames into scope. No checking for
--- validity, at all. The binding location is taken from the location
--- on each name.
-bindLRdrNames :: [Located RdrName]
- -> ([Name] -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
-bindLRdrNames rdrs thing_inside
- = do { var_names <- mapM (newTyVarNameRn Nothing) rdrs
- ; bindLocalNamesFV var_names $
- thing_inside var_names }
-
----------------
-bindHsQTyVars :: forall a b.
- HsDocContext
- -> Maybe SDoc -- Just d => check for unused tvs
- -- d is a phrase like "in the type ..."
- -> Maybe a -- Just _ => an associated type decl
- -> [Located RdrName] -- Kind variables from scope, no dups
- -> (LHsQTyVars GhcPs)
- -> (LHsQTyVars GhcRn -> Bool -> RnM (b, FreeVars))
- -- The Bool is True <=> all kind variables used in the
- -- kind signature are bound on the left. Reason:
- -- the last clause of Note [CUSKs: Complete user-supplied
- -- kind signatures] in GHC.Hs.Decls
- -> RnM (b, FreeVars)
-
--- See Note [bindHsQTyVars examples]
--- (a) Bring kind variables into scope
--- both (i) passed in body_kv_occs
--- and (ii) mentioned in the kinds of hsq_bndrs
--- (b) Bring type variables into scope
---
-bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside
- = do { let hs_tv_bndrs = hsQTvExplicit hsq_bndrs
- bndr_kv_occs = extractHsTyVarBndrsKVs hs_tv_bndrs
-
- ; let -- See Note [bindHsQTyVars examples] for what
- -- all these various things are doing
- bndrs, kv_occs, implicit_kvs :: [Located RdrName]
- bndrs = map hsLTyVarLocName hs_tv_bndrs
- kv_occs = nubL (bndr_kv_occs ++ body_kv_occs)
- -- Make sure to list the binder kvs before the
- -- body kvs, as mandated by
- -- Note [Ordering of implicit variables]
- implicit_kvs = filter_occs bndrs kv_occs
- del = deleteBys eqLocated
- all_bound_on_lhs = null ((body_kv_occs `del` bndrs) `del` bndr_kv_occs)
-
- ; traceRn "checkMixedVars3" $
- vcat [ text "kv_occs" <+> ppr kv_occs
- , text "bndrs" <+> ppr hs_tv_bndrs
- , text "bndr_kv_occs" <+> ppr bndr_kv_occs
- , text "wubble" <+> ppr ((kv_occs \\ bndrs) \\ bndr_kv_occs)
- ]
-
- ; implicit_kv_nms <- mapM (newTyVarNameRn mb_assoc) implicit_kvs
-
- ; bindLocalNamesFV implicit_kv_nms $
- bindLHsTyVarBndrs doc mb_in_doc mb_assoc hs_tv_bndrs $ \ rn_bndrs ->
- do { traceRn "bindHsQTyVars" (ppr hsq_bndrs $$ ppr implicit_kv_nms $$ ppr rn_bndrs)
- ; thing_inside (HsQTvs { hsq_ext = implicit_kv_nms
- , hsq_explicit = rn_bndrs })
- all_bound_on_lhs } }
-
- where
- filter_occs :: [Located RdrName] -- Bound here
- -> [Located RdrName] -- Potential implicit binders
- -> [Located RdrName] -- Final implicit binders
- -- Filter out any potential implicit binders that are either
- -- already in scope, or are explicitly bound in the same HsQTyVars
- filter_occs bndrs occs
- = filterOut is_in_scope occs
- where
- is_in_scope locc = locc `elemRdr` bndrs
-
-{- Note [bindHsQTyVars examples]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Suppose we have
- data T k (a::k1) (b::k) :: k2 -> k1 -> *
-
-Then:
- hs_tv_bndrs = [k, a::k1, b::k], the explicitly-bound variables
- bndrs = [k,a,b]
-
- bndr_kv_occs = [k,k1], kind variables free in kind signatures
- of hs_tv_bndrs
-
- body_kv_occs = [k2,k1], kind variables free in the
- result kind signature
-
- implicit_kvs = [k1,k2], kind variables free in kind signatures
- of hs_tv_bndrs, and not bound by bndrs
-
-* We want to quantify add implicit bindings for implicit_kvs
-
-* If implicit_body_kvs is non-empty, then there is a kind variable
- mentioned in the kind signature that is not bound "on the left".
- That's one of the rules for a CUSK, so we pass that info on
- as the second argument to thing_inside.
-
-* Order is not important in these lists. All we are doing is
- bring Names into scope.
-
-Finally, you may wonder why filter_occs removes in-scope variables
-from bndr/body_kv_occs. How can anything be in scope? Answer:
-HsQTyVars is /also/ used (slightly oddly) for Haskell-98 syntax
-ConDecls
- data T a = forall (b::k). MkT a b
-The ConDecl has a LHsQTyVars in it; but 'a' scopes over the entire
-ConDecl. Hence the local RdrEnv may be non-empty and we must filter
-out 'a' from the free vars. (Mind you, in this situation all the
-implicit kind variables are bound at the data type level, so there
-are none to bind in the ConDecl, so there are no implicitly bound
-variables at all.
-
-Note [Kind variable scoping]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If we have
- data T (a :: k) k = ...
-we report "k is out of scope" for (a::k). Reason: k is not brought
-into scope until the explicit k-binding that follows. It would be
-terribly confusing to bring into scope an /implicit/ k for a's kind
-and a distinct, shadowing explicit k that follows, something like
- data T {k1} (a :: k1) k = ...
-
-So the rule is:
-
- the implicit binders never include any
- of the explicit binders in the group
-
-Note that in the denerate case
- data T (a :: a) = blah
-we get a complaint the second 'a' is not in scope.
-
-That applies to foralls too: e.g.
- forall (a :: k) k . blah
-
-But if the foralls are split, we treat the two groups separately:
- forall (a :: k). forall k. blah
-Here we bring into scope an implicit k, which is later shadowed
-by the explicit k.
-
-In implementation terms
-
-* In bindHsQTyVars 'k' is free in bndr_kv_occs; then we delete
- the binders {a,k}, and so end with no implicit binders. Then we
- rename the binders left-to-right, and hence see that 'k' is out of
- scope in the kind of 'a'.
-
-* Similarly in extract_hs_tv_bndrs
-
-Note [Variables used as both types and kinds]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We bind the type variables tvs, and kvs is the set of free variables of the
-kinds in the scope of the binding. Here is one typical example:
-
- forall a b. a -> (b::k) -> (c::a)
-
-Here, tvs will be {a,b}, and kvs {k,a}.
-
-We must make sure that kvs includes all of variables in the kinds of type
-variable bindings. For instance:
-
- forall k (a :: k). Proxy a
-
-If we only look in the body of the `forall` type, we will mistakenly conclude
-that kvs is {}. But in fact, the type variable `k` is also used as a kind
-variable in (a :: k), later in the binding. (This mistake lead to #14710.)
-So tvs is {k,a} and kvs is {k}.
-
-NB: we do this only at the binding site of 'tvs'.
--}
-
-bindLHsTyVarBndrs :: HsDocContext
- -> Maybe SDoc -- Just d => check for unused tvs
- -- d is a phrase like "in the type ..."
- -> Maybe a -- Just _ => an associated type decl
- -> [LHsTyVarBndr GhcPs] -- User-written tyvars
- -> ([LHsTyVarBndr GhcRn] -> RnM (b, FreeVars))
- -> RnM (b, FreeVars)
-bindLHsTyVarBndrs doc mb_in_doc mb_assoc tv_bndrs thing_inside
- = do { when (isNothing mb_assoc) (checkShadowedRdrNames tv_names_w_loc)
- ; checkDupRdrNames tv_names_w_loc
- ; go tv_bndrs thing_inside }
- where
- tv_names_w_loc = map hsLTyVarLocName tv_bndrs
-
- go [] thing_inside = thing_inside []
- go (b:bs) thing_inside = bindLHsTyVarBndr doc mb_assoc b $ \ b' ->
- do { (res, fvs) <- go bs $ \ bs' ->
- thing_inside (b' : bs')
- ; warn_unused b' fvs
- ; return (res, fvs) }
-
- warn_unused tv_bndr fvs = case mb_in_doc of
- Just in_doc -> warnUnusedForAll in_doc tv_bndr fvs
- Nothing -> return ()
-
-bindLHsTyVarBndr :: HsDocContext
- -> Maybe a -- associated class
- -> LHsTyVarBndr GhcPs
- -> (LHsTyVarBndr GhcRn -> RnM (b, FreeVars))
- -> RnM (b, FreeVars)
-bindLHsTyVarBndr _doc mb_assoc (L loc
- (UserTyVar x
- lrdr@(L lv _))) thing_inside
- = do { nm <- newTyVarNameRn mb_assoc lrdr
- ; bindLocalNamesFV [nm] $
- thing_inside (L loc (UserTyVar x (L lv nm))) }
-
-bindLHsTyVarBndr doc mb_assoc (L loc (KindedTyVar x lrdr@(L lv _) kind))
- thing_inside
- = do { sig_ok <- xoptM LangExt.KindSignatures
- ; unless sig_ok (badKindSigErr doc kind)
- ; (kind', fvs1) <- rnLHsKind doc kind
- ; tv_nm <- newTyVarNameRn mb_assoc lrdr
- ; (b, fvs2) <- bindLocalNamesFV [tv_nm]
- $ thing_inside (L loc (KindedTyVar x (L lv tv_nm) kind'))
- ; return (b, fvs1 `plusFV` fvs2) }
-
-bindLHsTyVarBndr _ _ (L _ (XTyVarBndr nec)) _ = noExtCon nec
-
-newTyVarNameRn :: Maybe a -> Located RdrName -> RnM Name
-newTyVarNameRn mb_assoc (L loc rdr)
- = do { rdr_env <- getLocalRdrEnv
- ; case (mb_assoc, lookupLocalRdrEnv rdr_env rdr) of
- (Just _, Just n) -> return n
- -- Use the same Name as the parent class decl
-
- _ -> newLocalBndrRn (L loc rdr) }
-{-
-*********************************************************
-* *
- ConDeclField
-* *
-*********************************************************
-
-When renaming a ConDeclField, we have to find the FieldLabel
-associated with each field. But we already have all the FieldLabels
-available (since they were brought into scope by
-RnNames.getLocalNonValBinders), so we just take the list as an
-argument, build a map and look them up.
--}
-
-rnConDeclFields :: HsDocContext -> [FieldLabel] -> [LConDeclField GhcPs]
- -> RnM ([LConDeclField GhcRn], FreeVars)
--- Also called from RnSource
--- No wildcards can appear in record fields
-rnConDeclFields ctxt fls fields
- = mapFvRn (rnField fl_env env) fields
- where
- env = mkTyKiEnv ctxt TypeLevel RnTypeBody
- fl_env = mkFsEnv [ (flLabel fl, fl) | fl <- fls ]
-
-rnField :: FastStringEnv FieldLabel -> RnTyKiEnv -> LConDeclField GhcPs
- -> RnM (LConDeclField GhcRn, FreeVars)
-rnField fl_env env (L l (ConDeclField _ names ty haddock_doc))
- = do { let new_names = map (fmap lookupField) names
- ; (new_ty, fvs) <- rnLHsTyKi env ty
- ; new_haddock_doc <- rnMbLHsDoc haddock_doc
- ; return (L l (ConDeclField noExtField new_names new_ty new_haddock_doc)
- , fvs) }
- where
- lookupField :: FieldOcc GhcPs -> FieldOcc GhcRn
- lookupField (FieldOcc _ (L lr rdr)) =
- FieldOcc (flSelector fl) (L lr rdr)
- where
- lbl = occNameFS $ rdrNameOcc rdr
- fl = expectJust "rnField" $ lookupFsEnv fl_env lbl
- lookupField (XFieldOcc nec) = noExtCon nec
-rnField _ _ (L _ (XConDeclField nec)) = noExtCon nec
-
-{-
-************************************************************************
-* *
- Fixities and precedence parsing
-* *
-************************************************************************
-
-@mkOpAppRn@ deals with operator fixities. The argument expressions
-are assumed to be already correctly arranged. It needs the fixities
-recorded in the OpApp nodes, because fixity info applies to the things
-the programmer actually wrote, so you can't find it out from the Name.
-
-Furthermore, the second argument is guaranteed not to be another
-operator application. Why? Because the parser parses all
-operator applications left-associatively, EXCEPT negation, which
-we need to handle specially.
-Infix types are read in a *right-associative* way, so that
- a `op` b `op` c
-is always read in as
- a `op` (b `op` c)
-
-mkHsOpTyRn rearranges where necessary. The two arguments
-have already been renamed and rearranged. It's made rather tiresome
-by the presence of ->, which is a separate syntactic construct.
--}
-
----------------
--- Building (ty1 `op1` (ty21 `op2` ty22))
-mkHsOpTyRn :: (LHsType GhcRn -> LHsType GhcRn -> HsType GhcRn)
- -> Name -> Fixity -> LHsType GhcRn -> LHsType GhcRn
- -> RnM (HsType GhcRn)
-
-mkHsOpTyRn mk1 pp_op1 fix1 ty1 (L loc2 (HsOpTy noExtField ty21 op2 ty22))
- = do { fix2 <- lookupTyFixityRn op2
- ; mk_hs_op_ty mk1 pp_op1 fix1 ty1
- (\t1 t2 -> HsOpTy noExtField t1 op2 t2)
- (unLoc op2) fix2 ty21 ty22 loc2 }
-
-mkHsOpTyRn mk1 pp_op1 fix1 ty1 (L loc2 (HsFunTy _ ty21 ty22))
- = mk_hs_op_ty mk1 pp_op1 fix1 ty1
- (HsFunTy noExtField) funTyConName funTyFixity ty21 ty22 loc2
-
-mkHsOpTyRn mk1 _ _ ty1 ty2 -- Default case, no rearrangment
- = return (mk1 ty1 ty2)
-
----------------
-mk_hs_op_ty :: (LHsType GhcRn -> LHsType GhcRn -> HsType GhcRn)
- -> Name -> Fixity -> LHsType GhcRn
- -> (LHsType GhcRn -> LHsType GhcRn -> HsType GhcRn)
- -> Name -> Fixity -> LHsType GhcRn -> LHsType GhcRn -> SrcSpan
- -> RnM (HsType GhcRn)
-mk_hs_op_ty mk1 op1 fix1 ty1
- mk2 op2 fix2 ty21 ty22 loc2
- | nofix_error = do { precParseErr (NormalOp op1,fix1) (NormalOp op2,fix2)
- ; return (mk1 ty1 (L loc2 (mk2 ty21 ty22))) }
- | associate_right = return (mk1 ty1 (L loc2 (mk2 ty21 ty22)))
- | otherwise = do { -- Rearrange to ((ty1 `op1` ty21) `op2` ty22)
- new_ty <- mkHsOpTyRn mk1 op1 fix1 ty1 ty21
- ; return (mk2 (noLoc new_ty) ty22) }
- where
- (nofix_error, associate_right) = compareFixity fix1 fix2
-
-
----------------------------
-mkOpAppRn :: LHsExpr GhcRn -- Left operand; already rearranged
- -> LHsExpr GhcRn -> Fixity -- Operator and fixity
- -> LHsExpr GhcRn -- Right operand (not an OpApp, but might
- -- be a NegApp)
- -> RnM (HsExpr GhcRn)
-
--- (e11 `op1` e12) `op2` e2
-mkOpAppRn e1@(L _ (OpApp fix1 e11 op1 e12)) op2 fix2 e2
- | nofix_error
- = do precParseErr (get_op op1,fix1) (get_op op2,fix2)
- return (OpApp fix2 e1 op2 e2)
-
- | associate_right = do
- new_e <- mkOpAppRn e12 op2 fix2 e2
- return (OpApp fix1 e11 op1 (L loc' new_e))
- where
- loc'= combineLocs e12 e2
- (nofix_error, associate_right) = compareFixity fix1 fix2
-
----------------------------
--- (- neg_arg) `op` e2
-mkOpAppRn e1@(L _ (NegApp _ neg_arg neg_name)) op2 fix2 e2
- | nofix_error
- = do precParseErr (NegateOp,negateFixity) (get_op op2,fix2)
- return (OpApp fix2 e1 op2 e2)
-
- | associate_right
- = do new_e <- mkOpAppRn neg_arg op2 fix2 e2
- return (NegApp noExtField (L loc' new_e) neg_name)
- where
- loc' = combineLocs neg_arg e2
- (nofix_error, associate_right) = compareFixity negateFixity fix2
-
----------------------------
--- e1 `op` - neg_arg
-mkOpAppRn e1 op1 fix1 e2@(L _ (NegApp {})) -- NegApp can occur on the right
- | not associate_right -- We *want* right association
- = do precParseErr (get_op op1, fix1) (NegateOp, negateFixity)
- return (OpApp fix1 e1 op1 e2)
- where
- (_, associate_right) = compareFixity fix1 negateFixity
-
----------------------------
--- Default case
-mkOpAppRn e1 op fix e2 -- Default case, no rearrangment
- = ASSERT2( right_op_ok fix (unLoc e2),
- ppr e1 $$ text "---" $$ ppr op $$ text "---" $$ ppr fix $$ text "---" $$ ppr e2
- )
- return (OpApp fix e1 op e2)
-
-----------------------------
-
--- | Name of an operator in an operator application or section
-data OpName = NormalOp Name -- ^ A normal identifier
- | NegateOp -- ^ Prefix negation
- | UnboundOp OccName -- ^ An unbound indentifier
- | RecFldOp (AmbiguousFieldOcc GhcRn)
- -- ^ A (possibly ambiguous) record field occurrence
-
-instance Outputable OpName where
- ppr (NormalOp n) = ppr n
- ppr NegateOp = ppr negateName
- ppr (UnboundOp uv) = ppr uv
- ppr (RecFldOp fld) = ppr fld
-
-get_op :: LHsExpr GhcRn -> OpName
--- An unbound name could be either HsVar or HsUnboundVar
--- See RnExpr.rnUnboundVar
-get_op (L _ (HsVar _ n)) = NormalOp (unLoc n)
-get_op (L _ (HsUnboundVar _ uv)) = UnboundOp uv
-get_op (L _ (HsRecFld _ fld)) = RecFldOp fld
-get_op other = pprPanic "get_op" (ppr other)
-
--- Parser left-associates everything, but
--- derived instances may have correctly-associated things to
--- in the right operand. So we just check that the right operand is OK
-right_op_ok :: Fixity -> HsExpr GhcRn -> Bool
-right_op_ok fix1 (OpApp fix2 _ _ _)
- = not error_please && associate_right
- where
- (error_please, associate_right) = compareFixity fix1 fix2
-right_op_ok _ _
- = True
-
--- Parser initially makes negation bind more tightly than any other operator
--- And "deriving" code should respect this (use HsPar if not)
-mkNegAppRn :: LHsExpr (GhcPass id) -> SyntaxExpr (GhcPass id)
- -> RnM (HsExpr (GhcPass id))
-mkNegAppRn neg_arg neg_name
- = ASSERT( not_op_app (unLoc neg_arg) )
- return (NegApp noExtField neg_arg neg_name)
-
-not_op_app :: HsExpr id -> Bool
-not_op_app (OpApp {}) = False
-not_op_app _ = True
-
----------------------------
-mkOpFormRn :: LHsCmdTop GhcRn -- Left operand; already rearranged
- -> LHsExpr GhcRn -> Fixity -- Operator and fixity
- -> LHsCmdTop GhcRn -- Right operand (not an infix)
- -> RnM (HsCmd GhcRn)
-
--- (e11 `op1` e12) `op2` e2
-mkOpFormRn a1@(L loc
- (HsCmdTop _
- (L _ (HsCmdArrForm x op1 f (Just fix1)
- [a11,a12]))))
- op2 fix2 a2
- | nofix_error
- = do precParseErr (get_op op1,fix1) (get_op op2,fix2)
- return (HsCmdArrForm x op2 f (Just fix2) [a1, a2])
-
- | associate_right
- = do new_c <- mkOpFormRn a12 op2 fix2 a2
- return (HsCmdArrForm noExtField op1 f (Just fix1)
- [a11, L loc (HsCmdTop [] (L loc new_c))])
- -- TODO: locs are wrong
- where
- (nofix_error, associate_right) = compareFixity fix1 fix2
-
--- Default case
-mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment
- = return (HsCmdArrForm noExtField op Infix (Just fix) [arg1, arg2])
-
-
---------------------------------------
-mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn
- -> RnM (Pat GhcRn)
-
-mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2
- = do { fix1 <- lookupFixityRn (unLoc op1)
- ; let (nofix_error, associate_right) = compareFixity fix1 fix2
-
- ; if nofix_error then do
- { precParseErr (NormalOp (unLoc op1),fix1)
- (NormalOp (unLoc op2),fix2)
- ; return (ConPatIn op2 (InfixCon p1 p2)) }
-
- else if associate_right then do
- { new_p <- mkConOpPatRn op2 fix2 p12 p2
- ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) }
- -- XXX loc right?
- else return (ConPatIn op2 (InfixCon p1 p2)) }
-
-mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment
- = ASSERT( not_op_pat (unLoc p2) )
- return (ConPatIn op (InfixCon p1 p2))
-
-not_op_pat :: Pat GhcRn -> Bool
-not_op_pat (ConPatIn _ (InfixCon _ _)) = False
-not_op_pat _ = True
-
---------------------------------------
-checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM ()
- -- Check precedence of a function binding written infix
- -- eg a `op` b `C` c = ...
- -- See comments with rnExpr (OpApp ...) about "deriving"
-
-checkPrecMatch op (MG { mg_alts = (L _ ms) })
- = mapM_ check ms
- where
- check (L _ (Match { m_pats = (L l1 p1)
- : (L l2 p2)
- : _ }))
- = setSrcSpan (combineSrcSpans l1 l2) $
- do checkPrec op p1 False
- checkPrec op p2 True
-
- check _ = return ()
- -- This can happen. Consider
- -- a `op` True = ...
- -- op = ...
- -- The infix flag comes from the first binding of the group
- -- but the second eqn has no args (an error, but not discovered
- -- until the type checker). So we don't want to crash on the
- -- second eqn.
-checkPrecMatch _ (XMatchGroup nec) = noExtCon nec
-
-checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) ()
-checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do
- op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op
- op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1)
- let
- inf_ok = op1_prec > op_prec ||
- (op1_prec == op_prec &&
- (op1_dir == InfixR && op_dir == InfixR && right ||
- op1_dir == InfixL && op_dir == InfixL && not right))
-
- info = (NormalOp op, op_fix)
- info1 = (NormalOp (unLoc op1), op1_fix)
- (infol, infor) = if right then (info, info1) else (info1, info)
- unless inf_ok (precParseErr infol infor)
-
-checkPrec _ _ _
- = return ()
-
--- Check precedence of (arg op) or (op arg) respectively
--- If arg is itself an operator application, then either
--- (a) its precedence must be higher than that of op
--- (b) its precedency & associativity must be the same as that of op
-checkSectionPrec :: FixityDirection -> HsExpr GhcPs
- -> LHsExpr GhcRn -> LHsExpr GhcRn -> RnM ()
-checkSectionPrec direction section op arg
- = case unLoc arg of
- OpApp fix _ op' _ -> go_for_it (get_op op') fix
- NegApp _ _ _ -> go_for_it NegateOp negateFixity
- _ -> return ()
- where
- op_name = get_op op
- go_for_it arg_op arg_fix@(Fixity _ arg_prec assoc) = do
- op_fix@(Fixity _ op_prec _) <- lookupFixityOp op_name
- unless (op_prec < arg_prec
- || (op_prec == arg_prec && direction == assoc))
- (sectionPrecErr (get_op op, op_fix)
- (arg_op, arg_fix) section)
-
--- | Look up the fixity for an operator name. Be careful to use
--- 'lookupFieldFixityRn' for (possibly ambiguous) record fields
--- (see #13132).
-lookupFixityOp :: OpName -> RnM Fixity
-lookupFixityOp (NormalOp n) = lookupFixityRn n
-lookupFixityOp NegateOp = lookupFixityRn negateName
-lookupFixityOp (UnboundOp u) = lookupFixityRn (mkUnboundName u)
-lookupFixityOp (RecFldOp f) = lookupFieldFixityRn f
-
-
--- Precedence-related error messages
-
-precParseErr :: (OpName,Fixity) -> (OpName,Fixity) -> RnM ()
-precParseErr op1@(n1,_) op2@(n2,_)
- | is_unbound n1 || is_unbound n2
- = return () -- Avoid error cascade
- | otherwise
- = addErr $ hang (text "Precedence parsing error")
- 4 (hsep [text "cannot mix", ppr_opfix op1, ptext (sLit "and"),
- ppr_opfix op2,
- text "in the same infix expression"])
-
-sectionPrecErr :: (OpName,Fixity) -> (OpName,Fixity) -> HsExpr GhcPs -> RnM ()
-sectionPrecErr op@(n1,_) arg_op@(n2,_) section
- | is_unbound n1 || is_unbound n2
- = return () -- Avoid error cascade
- | otherwise
- = addErr $ vcat [text "The operator" <+> ppr_opfix op <+> ptext (sLit "of a section"),
- nest 4 (sep [text "must have lower precedence than that of the operand,",
- nest 2 (text "namely" <+> ppr_opfix arg_op)]),
- nest 4 (text "in the section:" <+> quotes (ppr section))]
-
-is_unbound :: OpName -> Bool
-is_unbound (NormalOp n) = isUnboundName n
-is_unbound UnboundOp{} = True
-is_unbound _ = False
-
-ppr_opfix :: (OpName, Fixity) -> SDoc
-ppr_opfix (op, fixity) = pp_op <+> brackets (ppr fixity)
- where
- pp_op | NegateOp <- op = text "prefix `-'"
- | otherwise = quotes (ppr op)
-
-
-{- *****************************************************
-* *
- Errors
-* *
-***************************************************** -}
-
-unexpectedTypeSigErr :: LHsSigWcType GhcPs -> SDoc
-unexpectedTypeSigErr ty
- = hang (text "Illegal type signature:" <+> quotes (ppr ty))
- 2 (text "Type signatures are only allowed in patterns with ScopedTypeVariables")
-
-badKindSigErr :: HsDocContext -> LHsType GhcPs -> TcM ()
-badKindSigErr doc (L loc ty)
- = setSrcSpan loc $ addErr $
- withHsDocContext doc $
- hang (text "Illegal kind signature:" <+> quotes (ppr ty))
- 2 (text "Perhaps you intended to use KindSignatures")
-
-dataKindsErr :: RnTyKiEnv -> HsType GhcPs -> SDoc
-dataKindsErr env thing
- = hang (text "Illegal" <+> pp_what <> colon <+> quotes (ppr thing))
- 2 (text "Perhaps you intended to use DataKinds")
- where
- pp_what | isRnKindLevel env = text "kind"
- | otherwise = text "type"
-
-inTypeDoc :: HsType GhcPs -> SDoc
-inTypeDoc ty = text "In the type" <+> quotes (ppr ty)
-
-warnUnusedForAll :: SDoc -> LHsTyVarBndr GhcRn -> FreeVars -> TcM ()
-warnUnusedForAll in_doc (L loc tv) used_names
- = whenWOptM Opt_WarnUnusedForalls $
- unless (hsTyVarName tv `elemNameSet` used_names) $
- addWarnAt (Reason Opt_WarnUnusedForalls) loc $
- vcat [ text "Unused quantified type variable" <+> quotes (ppr tv)
- , in_doc ]
-
-opTyErr :: Outputable a => RdrName -> a -> SDoc
-opTyErr op overall_ty
- = hang (text "Illegal operator" <+> quotes (ppr op) <+> ptext (sLit "in type") <+> quotes (ppr overall_ty))
- 2 (text "Use TypeOperators to allow operators in types")
-
-{-
-************************************************************************
-* *
- Finding the free type variables of a (HsType RdrName)
-* *
-************************************************************************
-
-
-Note [Kind and type-variable binders]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-In a type signature we may implicitly bind type/kind variables. For example:
- * f :: a -> a
- f = ...
- Here we need to find the free type variables of (a -> a),
- so that we know what to quantify
-
- * class C (a :: k) where ...
- This binds 'k' in ..., as well as 'a'
-
- * f (x :: a -> [a]) = ....
- Here we bind 'a' in ....
-
- * f (x :: T a -> T (b :: k)) = ...
- Here we bind both 'a' and the kind variable 'k'
-
- * type instance F (T (a :: Maybe k)) = ...a...k...
- Here we want to constrain the kind of 'a', and bind 'k'.
-
-To do that, we need to walk over a type and find its free type/kind variables.
-We preserve the left-to-right order of each variable occurrence.
-See Note [Ordering of implicit variables].
-
-Clients of this code can remove duplicates with nubL.
-
-Note [Ordering of implicit variables]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Since the advent of -XTypeApplications, GHC makes promises about the ordering
-of implicit variable quantification. Specifically, we offer that implicitly
-quantified variables (such as those in const :: a -> b -> a, without a `forall`)
-will occur in left-to-right order of first occurrence. Here are a few examples:
-
- const :: a -> b -> a -- forall a b. ...
- f :: Eq a => b -> a -> a -- forall a b. ... contexts are included
-
- type a <-< b = b -> a
- g :: a <-< b -- forall a b. ... type synonyms matter
-
- class Functor f where
- fmap :: (a -> b) -> f a -> f b -- forall f a b. ...
- -- The f is quantified by the class, so only a and b are considered in fmap
-
-This simple story is complicated by the possibility of dependency: all variables
-must come after any variables mentioned in their kinds.
-
- typeRep :: Typeable a => TypeRep (a :: k) -- forall k a. ...
-
-The k comes first because a depends on k, even though the k appears later than
-the a in the code. Thus, GHC does ScopedSort on the variables.
-See Note [ScopedSort] in Type.
-
-Implicitly bound variables are collected by any function which returns a
-FreeKiTyVars, FreeKiTyVarsWithDups, or FreeKiTyVarsNoDups, which notably
-includes the `extract-` family of functions (extractHsTysRdrTyVarsDups,
-extractHsTyVarBndrsKVs, etc.).
-These functions thus promise to keep left-to-right ordering.
-
-Note [Implicit quantification in type synonyms]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We typically bind type/kind variables implicitly when they are in a kind
-annotation on the LHS, for example:
-
- data Proxy (a :: k) = Proxy
- type KindOf (a :: k) = k
-
-Here 'k' is in the kind annotation of a type variable binding, KindedTyVar, and
-we want to implicitly quantify over it. This is easy: just extract all free
-variables from the kind signature. That's what we do in extract_hs_tv_bndrs_kvs
-
-By contrast, on the RHS we can't simply collect *all* free variables. Which of
-the following are allowed?
-
- type TySyn1 = a :: Type
- type TySyn2 = 'Nothing :: Maybe a
- type TySyn3 = 'Just ('Nothing :: Maybe a)
- type TySyn4 = 'Left a :: Either Type a
-
-After some design deliberations (see non-taken alternatives below), the answer
-is to reject TySyn1 and TySyn3, but allow TySyn2 and TySyn4, at least for now.
-We implicitly quantify over free variables of the outermost kind signature, if
-one exists:
-
- * In TySyn1, the outermost kind signature is (:: Type), and it does not have
- any free variables.
- * In TySyn2, the outermost kind signature is (:: Maybe a), it contains a
- free variable 'a', which we implicitly quantify over.
- * In TySyn3, there is no outermost kind signature. The (:: Maybe a) signature
- is hidden inside 'Just.
- * In TySyn4, the outermost kind signature is (:: Either Type a), it contains
- a free variable 'a', which we implicitly quantify over. That is why we can
- also use it to the left of the double colon: 'Left a
-
-The logic resides in extractHsTyRdrTyVarsKindVars. We use it both for type
-synonyms and type family instances.
-
-This is something of a stopgap solution until we can explicitly bind invisible
-type/kind variables:
-
- type TySyn3 :: forall a. Maybe a
- type TySyn3 @a = 'Just ('Nothing :: Maybe a)
-
-Note [Implicit quantification in type synonyms: non-taken alternatives]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Alternative I: No quantification
---------------------------------
-We could offer no implicit quantification on the RHS, accepting none of the
-TySyn<N> examples. The user would have to bind the variables explicitly:
-
- type TySyn1 a = a :: Type
- type TySyn2 a = 'Nothing :: Maybe a
- type TySyn3 a = 'Just ('Nothing :: Maybe a)
- type TySyn4 a = 'Left a :: Either Type a
-
-However, this would mean that one would have to specify 'a' at call sites every
-time, which could be undesired.
-
-Alternative II: Indiscriminate quantification
----------------------------------------------
-We could implicitly quantify over all free variables on the RHS just like we do
-on the LHS. Then we would infer the following kinds:
-
- TySyn1 :: forall {a}. Type
- TySyn2 :: forall {a}. Maybe a
- TySyn3 :: forall {a}. Maybe (Maybe a)
- TySyn4 :: forall {a}. Either Type a
-
-This would work fine for TySyn<2,3,4>, but TySyn1 is clearly bogus: the variable
-is free-floating, not fixed by anything.
-
-Alternative III: reportFloatingKvs
-----------------------------------
-We could augment Alternative II by hunting down free-floating variables during
-type checking. While viable, this would mean we'd end up accepting this:
-
- data Prox k (a :: k)
- type T = Prox k
-
--}
-
--- See Note [Kind and type-variable binders]
--- These lists are guaranteed to preserve left-to-right ordering of
--- the types the variables were extracted from. See also
--- Note [Ordering of implicit variables].
-type FreeKiTyVars = [Located RdrName]
-
--- | A 'FreeKiTyVars' list that is allowed to have duplicate variables.
-type FreeKiTyVarsWithDups = FreeKiTyVars
-
--- | A 'FreeKiTyVars' list that contains no duplicate variables.
-type FreeKiTyVarsNoDups = FreeKiTyVars
-
-filterInScope :: LocalRdrEnv -> FreeKiTyVars -> FreeKiTyVars
-filterInScope rdr_env = filterOut (inScope rdr_env . unLoc)
-
-filterInScopeM :: FreeKiTyVars -> RnM FreeKiTyVars
-filterInScopeM vars
- = do { rdr_env <- getLocalRdrEnv
- ; return (filterInScope rdr_env vars) }
-
-inScope :: LocalRdrEnv -> RdrName -> Bool
-inScope rdr_env rdr = rdr `elemLocalRdrEnv` rdr_env
-
-extract_tyarg :: LHsTypeArg GhcPs -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups
-extract_tyarg (HsValArg ty) acc = extract_lty ty acc
-extract_tyarg (HsTypeArg _ ki) acc = extract_lty ki acc
-extract_tyarg (HsArgPar _) acc = acc
-
-extract_tyargs :: [LHsTypeArg GhcPs] -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups
-extract_tyargs args acc = foldr extract_tyarg acc args
-
-extractHsTyArgRdrKiTyVarsDup :: [LHsTypeArg GhcPs] -> FreeKiTyVarsWithDups
-extractHsTyArgRdrKiTyVarsDup args
- = extract_tyargs args []
-
--- | 'extractHsTyRdrTyVars' finds the type/kind variables
--- of a HsType/HsKind.
--- It's used when making the @forall@s explicit.
--- When the same name occurs multiple times in the types, only the first
--- occurrence is returned.
--- See Note [Kind and type-variable binders]
-extractHsTyRdrTyVars :: LHsType GhcPs -> FreeKiTyVarsNoDups
-extractHsTyRdrTyVars ty
- = nubL (extractHsTyRdrTyVarsDups ty)
-
--- | 'extractHsTyRdrTyVarsDups' finds the type/kind variables
--- of a HsType/HsKind.
--- It's used when making the @forall@s explicit.
--- When the same name occurs multiple times in the types, all occurrences
--- are returned.
-extractHsTyRdrTyVarsDups :: LHsType GhcPs -> FreeKiTyVarsWithDups
-extractHsTyRdrTyVarsDups ty
- = extract_lty ty []
-
--- | Extracts the free type/kind variables from the kind signature of a HsType.
--- This is used to implicitly quantify over @k@ in @type T = Nothing :: Maybe k@.
--- When the same name occurs multiple times in the type, only the first
--- occurrence is returned, and the left-to-right order of variables is
--- preserved.
--- See Note [Kind and type-variable binders] and
--- Note [Ordering of implicit variables] and
--- Note [Implicit quantification in type synonyms].
-extractHsTyRdrTyVarsKindVars :: LHsType GhcPs -> FreeKiTyVarsNoDups
-extractHsTyRdrTyVarsKindVars (unLoc -> ty) =
- case ty of
- HsParTy _ ty -> extractHsTyRdrTyVarsKindVars ty
- HsKindSig _ _ ki -> extractHsTyRdrTyVars ki
- _ -> []
-
--- | Extracts free type and kind variables from types in a list.
--- When the same name occurs multiple times in the types, all occurrences
--- are returned.
-extractHsTysRdrTyVarsDups :: [LHsType GhcPs] -> FreeKiTyVarsWithDups
-extractHsTysRdrTyVarsDups tys
- = extract_ltys tys []
-
--- Returns the free kind variables of any explicitly-kinded binders, returning
--- variable occurrences in left-to-right order.
--- See Note [Ordering of implicit variables].
--- NB: Does /not/ delete the binders themselves.
--- However duplicates are removed
--- E.g. given [k1, a:k1, b:k2]
--- the function returns [k1,k2], even though k1 is bound here
-extractHsTyVarBndrsKVs :: [LHsTyVarBndr GhcPs] -> FreeKiTyVarsNoDups
-extractHsTyVarBndrsKVs tv_bndrs
- = nubL (extract_hs_tv_bndrs_kvs tv_bndrs)
-
--- Returns the free kind variables in a type family result signature, returning
--- variable occurrences in left-to-right order.
--- See Note [Ordering of implicit variables].
-extractRdrKindSigVars :: LFamilyResultSig GhcPs -> [Located RdrName]
-extractRdrKindSigVars (L _ resultSig)
- | KindSig _ k <- resultSig = extractHsTyRdrTyVars k
- | TyVarSig _ (L _ (KindedTyVar _ _ k)) <- resultSig = extractHsTyRdrTyVars k
- | otherwise = []
-
--- Get type/kind variables mentioned in the kind signature, preserving
--- left-to-right order and without duplicates:
---
--- * data T a (b :: k1) :: k2 -> k1 -> k2 -> Type -- result: [k2,k1]
--- * data T a (b :: k1) -- result: []
---
--- See Note [Ordering of implicit variables].
-extractDataDefnKindVars :: HsDataDefn GhcPs -> FreeKiTyVarsNoDups
-extractDataDefnKindVars (HsDataDefn { dd_kindSig = ksig })
- = maybe [] extractHsTyRdrTyVars ksig
-extractDataDefnKindVars (XHsDataDefn nec) = noExtCon nec
-
-extract_lctxt :: LHsContext GhcPs
- -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups
-extract_lctxt ctxt = extract_ltys (unLoc ctxt)
-
-extract_ltys :: [LHsType GhcPs]
- -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups
-extract_ltys tys acc = foldr extract_lty acc tys
-
-extract_lty :: LHsType GhcPs
- -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups
-extract_lty (L _ ty) acc
- = case ty of
- HsTyVar _ _ ltv -> extract_tv ltv acc
- HsBangTy _ _ ty -> extract_lty ty acc
- HsRecTy _ flds -> foldr (extract_lty
- . cd_fld_type . unLoc) acc
- flds
- HsAppTy _ ty1 ty2 -> extract_lty ty1 $
- extract_lty ty2 acc
- HsAppKindTy _ ty k -> extract_lty ty $
- extract_lty k acc
- HsListTy _ ty -> extract_lty ty acc
- HsTupleTy _ _ tys -> extract_ltys tys acc
- HsSumTy _ tys -> extract_ltys tys acc
- HsFunTy _ ty1 ty2 -> extract_lty ty1 $
- extract_lty ty2 acc
- HsIParamTy _ _ ty -> extract_lty ty acc
- HsOpTy _ ty1 tv ty2 -> extract_tv tv $
- extract_lty ty1 $
- extract_lty ty2 acc
- HsParTy _ ty -> extract_lty ty acc
- HsSpliceTy {} -> acc -- Type splices mention no tvs
- HsDocTy _ ty _ -> extract_lty ty acc
- HsExplicitListTy _ _ tys -> extract_ltys tys acc
- HsExplicitTupleTy _ tys -> extract_ltys tys acc
- HsTyLit _ _ -> acc
- HsStarTy _ _ -> acc
- HsKindSig _ ty ki -> extract_lty ty $
- extract_lty ki acc
- HsForAllTy { hst_bndrs = tvs, hst_body = ty }
- -> extract_hs_tv_bndrs tvs acc $
- extract_lty ty []
- HsQualTy { hst_ctxt = ctxt, hst_body = ty }
- -> extract_lctxt ctxt $
- extract_lty ty acc
- XHsType {} -> acc
- -- We deal with these separately in rnLHsTypeWithWildCards
- HsWildCardTy {} -> acc
-
-extractHsTvBndrs :: [LHsTyVarBndr GhcPs]
- -> FreeKiTyVarsWithDups -- Free in body
- -> FreeKiTyVarsWithDups -- Free in result
-extractHsTvBndrs tv_bndrs body_fvs
- = extract_hs_tv_bndrs tv_bndrs [] body_fvs
-
-extract_hs_tv_bndrs :: [LHsTyVarBndr GhcPs]
- -> FreeKiTyVarsWithDups -- Accumulator
- -> FreeKiTyVarsWithDups -- Free in body
- -> FreeKiTyVarsWithDups
--- In (forall (a :: Maybe e). a -> b) we have
--- 'a' is bound by the forall
--- 'b' is a free type variable
--- 'e' is a free kind variable
-extract_hs_tv_bndrs tv_bndrs acc_vars body_vars
- | null tv_bndrs = body_vars ++ acc_vars
- | otherwise = filterOut (`elemRdr` tv_bndr_rdrs) (bndr_vars ++ body_vars) ++ acc_vars
- -- NB: delete all tv_bndr_rdrs from bndr_vars as well as body_vars.
- -- See Note [Kind variable scoping]
- where
- bndr_vars = extract_hs_tv_bndrs_kvs tv_bndrs
- tv_bndr_rdrs = map hsLTyVarLocName tv_bndrs
-
-extract_hs_tv_bndrs_kvs :: [LHsTyVarBndr GhcPs] -> [Located RdrName]
--- Returns the free kind variables of any explicitly-kinded binders, returning
--- variable occurrences in left-to-right order.
--- See Note [Ordering of implicit variables].
--- NB: Does /not/ delete the binders themselves.
--- Duplicates are /not/ removed
--- E.g. given [k1, a:k1, b:k2]
--- the function returns [k1,k2], even though k1 is bound here
-extract_hs_tv_bndrs_kvs tv_bndrs =
- foldr extract_lty []
- [k | L _ (KindedTyVar _ _ k) <- tv_bndrs]
-
-extract_tv :: Located RdrName
- -> [Located RdrName] -> [Located RdrName]
-extract_tv tv acc =
- if isRdrTyVar (unLoc tv) then tv:acc else acc
-
--- Deletes duplicates in a list of Located things.
---
--- Importantly, this function is stable with respect to the original ordering
--- of things in the list. This is important, as it is a property that GHC
--- relies on to maintain the left-to-right ordering of implicitly quantified
--- type variables.
--- See Note [Ordering of implicit variables].
-nubL :: Eq a => [Located a] -> [Located a]
-nubL = nubBy eqLocated
-
-elemRdr :: Located RdrName -> [Located RdrName] -> Bool
-elemRdr x = any (eqLocated x)
diff --git a/compiler/rename/RnUnbound.hs b/compiler/rename/RnUnbound.hs
deleted file mode 100644
index 2de2fc1f0c..0000000000
--- a/compiler/rename/RnUnbound.hs
+++ /dev/null
@@ -1,381 +0,0 @@
-{-
-
-This module contains helper functions for reporting and creating
-unbound variables.
-
--}
-module RnUnbound ( mkUnboundName
- , mkUnboundNameRdr
- , isUnboundName
- , reportUnboundName
- , unknownNameSuggestions
- , WhereLooking(..)
- , unboundName
- , unboundNameX
- , notInScopeErr ) where
-
-import GhcPrelude
-
-import RdrName
-import HscTypes
-import TcRnMonad
-import Name
-import Module
-import SrcLoc
-import Outputable
-import PrelNames ( mkUnboundName, isUnboundName, getUnique)
-import Util
-import Maybes
-import DynFlags
-import FastString
-import Data.List
-import Data.Function ( on )
-import UniqDFM (udfmToList)
-
-{-
-************************************************************************
-* *
- What to do when a lookup fails
-* *
-************************************************************************
--}
-
-data WhereLooking = WL_Any -- Any binding
- | WL_Global -- Any top-level binding (local or imported)
- | WL_LocalTop -- Any top-level binding in this module
- | WL_LocalOnly
- -- Only local bindings
- -- (pattern synonyms declaractions,
- -- see Note [Renaming pattern synonym variables])
-
-mkUnboundNameRdr :: RdrName -> Name
-mkUnboundNameRdr rdr = mkUnboundName (rdrNameOcc rdr)
-
-reportUnboundName :: RdrName -> RnM Name
-reportUnboundName rdr = unboundName WL_Any rdr
-
-unboundName :: WhereLooking -> RdrName -> RnM Name
-unboundName wl rdr = unboundNameX wl rdr Outputable.empty
-
-unboundNameX :: WhereLooking -> RdrName -> SDoc -> RnM Name
-unboundNameX where_look rdr_name extra
- = do { dflags <- getDynFlags
- ; let show_helpful_errors = gopt Opt_HelpfulErrors dflags
- err = notInScopeErr rdr_name $$ extra
- ; if not show_helpful_errors
- then addErr err
- else do { local_env <- getLocalRdrEnv
- ; global_env <- getGlobalRdrEnv
- ; impInfo <- getImports
- ; currmod <- getModule
- ; hpt <- getHpt
- ; let suggestions = unknownNameSuggestions_ where_look
- dflags hpt currmod global_env local_env impInfo
- rdr_name
- ; addErr (err $$ suggestions) }
- ; return (mkUnboundNameRdr rdr_name) }
-
-notInScopeErr :: RdrName -> SDoc
-notInScopeErr rdr_name
- = hang (text "Not in scope:")
- 2 (what <+> quotes (ppr rdr_name))
- where
- what = pprNonVarNameSpace (occNameSpace (rdrNameOcc rdr_name))
-
-type HowInScope = Either SrcSpan ImpDeclSpec
- -- Left loc => locally bound at loc
- -- Right ispec => imported as specified by ispec
-
-
--- | Called from the typechecker (TcErrors) when we find an unbound variable
-unknownNameSuggestions :: DynFlags
- -> HomePackageTable -> Module
- -> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails
- -> RdrName -> SDoc
-unknownNameSuggestions = unknownNameSuggestions_ WL_Any
-
-unknownNameSuggestions_ :: WhereLooking -> DynFlags
- -> HomePackageTable -> Module
- -> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails
- -> RdrName -> SDoc
-unknownNameSuggestions_ where_look dflags hpt curr_mod global_env local_env
- imports tried_rdr_name =
- similarNameSuggestions where_look dflags global_env local_env tried_rdr_name $$
- importSuggestions where_look global_env hpt
- curr_mod imports tried_rdr_name $$
- extensionSuggestions tried_rdr_name
-
-
-similarNameSuggestions :: WhereLooking -> DynFlags
- -> GlobalRdrEnv -> LocalRdrEnv
- -> RdrName -> SDoc
-similarNameSuggestions where_look dflags global_env
- local_env tried_rdr_name
- = case suggest of
- [] -> Outputable.empty
- [p] -> perhaps <+> pp_item p
- ps -> sep [ perhaps <+> text "one of these:"
- , nest 2 (pprWithCommas pp_item ps) ]
- where
- all_possibilities :: [(String, (RdrName, HowInScope))]
- all_possibilities
- = [ (showPpr dflags r, (r, Left loc))
- | (r,loc) <- local_possibilities local_env ]
- ++ [ (showPpr dflags r, rp) | (r, rp) <- global_possibilities global_env ]
-
- suggest = fuzzyLookup (showPpr dflags tried_rdr_name) all_possibilities
- perhaps = text "Perhaps you meant"
-
- pp_item :: (RdrName, HowInScope) -> SDoc
- pp_item (rdr, Left loc) = pp_ns rdr <+> quotes (ppr rdr) <+> loc' -- Locally defined
- where loc' = case loc of
- UnhelpfulSpan l -> parens (ppr l)
- RealSrcSpan l -> parens (text "line" <+> int (srcSpanStartLine l))
- pp_item (rdr, Right is) = pp_ns rdr <+> quotes (ppr rdr) <+> -- Imported
- parens (text "imported from" <+> ppr (is_mod is))
-
- pp_ns :: RdrName -> SDoc
- pp_ns rdr | ns /= tried_ns = pprNameSpace ns
- | otherwise = Outputable.empty
- where ns = rdrNameSpace rdr
-
- tried_occ = rdrNameOcc tried_rdr_name
- tried_is_sym = isSymOcc tried_occ
- tried_ns = occNameSpace tried_occ
- tried_is_qual = isQual tried_rdr_name
-
- correct_name_space occ = nameSpacesRelated (occNameSpace occ) tried_ns
- && isSymOcc occ == tried_is_sym
- -- Treat operator and non-operators as non-matching
- -- This heuristic avoids things like
- -- Not in scope 'f'; perhaps you meant '+' (from Prelude)
-
- local_ok = case where_look of { WL_Any -> True
- ; WL_LocalOnly -> True
- ; _ -> False }
- local_possibilities :: LocalRdrEnv -> [(RdrName, SrcSpan)]
- local_possibilities env
- | tried_is_qual = []
- | not local_ok = []
- | otherwise = [ (mkRdrUnqual occ, nameSrcSpan name)
- | name <- localRdrEnvElts env
- , let occ = nameOccName name
- , correct_name_space occ]
-
- global_possibilities :: GlobalRdrEnv -> [(RdrName, (RdrName, HowInScope))]
- global_possibilities global_env
- | tried_is_qual = [ (rdr_qual, (rdr_qual, how))
- | gre <- globalRdrEnvElts global_env
- , isGreOk where_look gre
- , let name = gre_name gre
- occ = nameOccName name
- , correct_name_space occ
- , (mod, how) <- qualsInScope gre
- , let rdr_qual = mkRdrQual mod occ ]
-
- | otherwise = [ (rdr_unqual, pair)
- | gre <- globalRdrEnvElts global_env
- , isGreOk where_look gre
- , let name = gre_name gre
- occ = nameOccName name
- rdr_unqual = mkRdrUnqual occ
- , correct_name_space occ
- , pair <- case (unquals_in_scope gre, quals_only gre) of
- (how:_, _) -> [ (rdr_unqual, how) ]
- ([], pr:_) -> [ pr ] -- See Note [Only-quals]
- ([], []) -> [] ]
-
- -- Note [Only-quals]
- -- The second alternative returns those names with the same
- -- OccName as the one we tried, but live in *qualified* imports
- -- e.g. if you have:
- --
- -- > import qualified Data.Map as Map
- -- > foo :: Map
- --
- -- then we suggest @Map.Map@.
-
- --------------------
- unquals_in_scope :: GlobalRdrElt -> [HowInScope]
- unquals_in_scope (GRE { gre_name = n, gre_lcl = lcl, gre_imp = is })
- | lcl = [ Left (nameSrcSpan n) ]
- | otherwise = [ Right ispec
- | i <- is, let ispec = is_decl i
- , not (is_qual ispec) ]
-
-
- --------------------
- quals_only :: GlobalRdrElt -> [(RdrName, HowInScope)]
- -- Ones for which *only* the qualified version is in scope
- quals_only (GRE { gre_name = n, gre_imp = is })
- = [ (mkRdrQual (is_as ispec) (nameOccName n), Right ispec)
- | i <- is, let ispec = is_decl i, is_qual ispec ]
-
--- | Generate helpful suggestions if a qualified name Mod.foo is not in scope.
-importSuggestions :: WhereLooking
- -> GlobalRdrEnv
- -> HomePackageTable -> Module
- -> ImportAvails -> RdrName -> SDoc
-importSuggestions where_look global_env hpt currMod imports rdr_name
- | WL_LocalOnly <- where_look = Outputable.empty
- | not (isQual rdr_name || isUnqual rdr_name) = Outputable.empty
- | null interesting_imports
- , Just name <- mod_name
- , show_not_imported_line name
- = hsep
- [ text "No module named"
- , quotes (ppr name)
- , text "is imported."
- ]
- | is_qualified
- , null helpful_imports
- , [(mod,_)] <- interesting_imports
- = hsep
- [ text "Module"
- , quotes (ppr mod)
- , text "does not export"
- , quotes (ppr occ_name) <> dot
- ]
- | is_qualified
- , null helpful_imports
- , not (null interesting_imports)
- , mods <- map fst interesting_imports
- = hsep
- [ text "Neither"
- , quotedListWithNor (map ppr mods)
- , text "exports"
- , quotes (ppr occ_name) <> dot
- ]
- | [(mod,imv)] <- helpful_imports_non_hiding
- = fsep
- [ text "Perhaps you want to add"
- , quotes (ppr occ_name)
- , text "to the import list"
- , text "in the import of"
- , quotes (ppr mod)
- , parens (ppr (imv_span imv)) <> dot
- ]
- | not (null helpful_imports_non_hiding)
- = fsep
- [ text "Perhaps you want to add"
- , quotes (ppr occ_name)
- , text "to one of these import lists:"
- ]
- $$
- nest 2 (vcat
- [ quotes (ppr mod) <+> parens (ppr (imv_span imv))
- | (mod,imv) <- helpful_imports_non_hiding
- ])
- | [(mod,imv)] <- helpful_imports_hiding
- = fsep
- [ text "Perhaps you want to remove"
- , quotes (ppr occ_name)
- , text "from the explicit hiding list"
- , text "in the import of"
- , quotes (ppr mod)
- , parens (ppr (imv_span imv)) <> dot
- ]
- | not (null helpful_imports_hiding)
- = fsep
- [ text "Perhaps you want to remove"
- , quotes (ppr occ_name)
- , text "from the hiding clauses"
- , text "in one of these imports:"
- ]
- $$
- nest 2 (vcat
- [ quotes (ppr mod) <+> parens (ppr (imv_span imv))
- | (mod,imv) <- helpful_imports_hiding
- ])
- | otherwise
- = Outputable.empty
- where
- is_qualified = isQual rdr_name
- (mod_name, occ_name) = case rdr_name of
- Unqual occ_name -> (Nothing, occ_name)
- Qual mod_name occ_name -> (Just mod_name, occ_name)
- _ -> error "importSuggestions: dead code"
-
-
- -- What import statements provide "Mod" at all
- -- or, if this is an unqualified name, are not qualified imports
- interesting_imports = [ (mod, imp)
- | (mod, mod_imports) <- moduleEnvToList (imp_mods imports)
- , Just imp <- return $ pick (importedByUser mod_imports)
- ]
-
- -- We want to keep only one for each original module; preferably one with an
- -- explicit import list (for no particularly good reason)
- pick :: [ImportedModsVal] -> Maybe ImportedModsVal
- pick = listToMaybe . sortBy (compare `on` prefer) . filter select
- where select imv = case mod_name of Just name -> imv_name imv == name
- Nothing -> not (imv_qualified imv)
- prefer imv = (imv_is_hiding imv, imv_span imv)
-
- -- Which of these would export a 'foo'
- -- (all of these are restricted imports, because if they were not, we
- -- wouldn't have an out-of-scope error in the first place)
- helpful_imports = filter helpful interesting_imports
- where helpful (_,imv)
- = not . null $ lookupGlobalRdrEnv (imv_all_exports imv) occ_name
-
- -- Which of these do that because of an explicit hiding list resp. an
- -- explicit import list
- (helpful_imports_hiding, helpful_imports_non_hiding)
- = partition (imv_is_hiding . snd) helpful_imports
-
- -- See note [When to show/hide the module-not-imported line]
- show_not_imported_line :: ModuleName -> Bool -- #15611
- show_not_imported_line modnam
- | modnam `elem` globMods = False -- #14225 -- 1
- | moduleName currMod == modnam = False -- 2.1
- | is_last_loaded_mod modnam hpt_uniques = False -- 2.2
- | otherwise = True
- where
- hpt_uniques = map fst (udfmToList hpt)
- is_last_loaded_mod _ [] = False
- is_last_loaded_mod modnam uniqs = last uniqs == getUnique modnam
- globMods = nub [ mod
- | gre <- globalRdrEnvElts global_env
- , isGreOk where_look gre
- , (mod, _) <- qualsInScope gre
- ]
-
-extensionSuggestions :: RdrName -> SDoc
-extensionSuggestions rdrName
- | rdrName == mkUnqual varName (fsLit "mdo") ||
- rdrName == mkUnqual varName (fsLit "rec")
- = text "Perhaps you meant to use RecursiveDo"
- | otherwise = Outputable.empty
-
-qualsInScope :: GlobalRdrElt -> [(ModuleName, HowInScope)]
--- Ones for which the qualified version is in scope
-qualsInScope GRE { gre_name = n, gre_lcl = lcl, gre_imp = is }
- | lcl = case nameModule_maybe n of
- Nothing -> []
- Just m -> [(moduleName m, Left (nameSrcSpan n))]
- | otherwise = [ (is_as ispec, Right ispec)
- | i <- is, let ispec = is_decl i ]
-
-isGreOk :: WhereLooking -> GlobalRdrElt -> Bool
-isGreOk where_look = case where_look of
- WL_LocalTop -> isLocalGRE
- WL_LocalOnly -> const False
- _ -> const True
-
-{- Note [When to show/hide the module-not-imported line] -- #15611
-For the error message:
- Not in scope X.Y
- Module X does not export Y
- No module named ‘X’ is imported:
-there are 2 cases, where we hide the last "no module is imported" line:
-1. If the module X has been imported.
-2. If the module X is the current module. There are 2 subcases:
- 2.1 If the unknown module name is in a input source file,
- then we can use the getModule function to get the current module name.
- (See test T15611a)
- 2.2 If the unknown module name has been entered by the user in GHCi,
- then the getModule function returns something like "interactive:Ghci1",
- and we have to check the current module in the last added entry of
- the HomePackageTable. (See test T15611b)
--}
diff --git a/compiler/rename/RnUtils.hs b/compiler/rename/RnUtils.hs
deleted file mode 100644
index 88996e31b1..0000000000
--- a/compiler/rename/RnUtils.hs
+++ /dev/null
@@ -1,514 +0,0 @@
-{-
-
-This module contains miscellaneous functions related to renaming.
-
--}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE ViewPatterns #-}
-{-# LANGUAGE TypeFamilies #-}
-
-module RnUtils (
- checkDupRdrNames, checkShadowedRdrNames,
- checkDupNames, checkDupAndShadowedNames, dupNamesErr,
- checkTupSize,
- addFvRn, mapFvRn, mapMaybeFvRn,
- warnUnusedMatches, warnUnusedTypePatterns,
- warnUnusedTopBinds, warnUnusedLocalBinds,
- checkUnusedRecordWildcard,
- mkFieldEnv,
- unknownSubordinateErr, badQualBndrErr, typeAppErr,
- HsDocContext(..), pprHsDocContext,
- inHsDocContext, withHsDocContext,
-
- newLocalBndrRn, newLocalBndrsRn,
-
- bindLocalNames, bindLocalNamesFV,
-
- addNameClashErrRn, extendTyVarEnvFVRn
-
-)
-
-where
-
-
-import GhcPrelude
-
-import GHC.Hs
-import RdrName
-import HscTypes
-import TcEnv
-import TcRnMonad
-import Name
-import NameSet
-import NameEnv
-import DataCon
-import SrcLoc
-import Outputable
-import Util
-import BasicTypes ( TopLevelFlag(..) )
-import ListSetOps ( removeDups )
-import DynFlags
-import FastString
-import Control.Monad
-import Data.List
-import Constants ( mAX_TUPLE_SIZE )
-import qualified Data.List.NonEmpty as NE
-import qualified GHC.LanguageExtensions as LangExt
-
-{-
-*********************************************************
-* *
-\subsection{Binding}
-* *
-*********************************************************
--}
-
-newLocalBndrRn :: Located RdrName -> RnM Name
--- Used for non-top-level binders. These should
--- never be qualified.
-newLocalBndrRn (L loc rdr_name)
- | Just name <- isExact_maybe rdr_name
- = return name -- This happens in code generated by Template Haskell
- -- See Note [Binders in Template Haskell] in Convert.hs
- | otherwise
- = do { unless (isUnqual rdr_name)
- (addErrAt loc (badQualBndrErr rdr_name))
- ; uniq <- newUnique
- ; return (mkInternalName uniq (rdrNameOcc rdr_name) loc) }
-
-newLocalBndrsRn :: [Located RdrName] -> RnM [Name]
-newLocalBndrsRn = mapM newLocalBndrRn
-
-bindLocalNames :: [Name] -> RnM a -> RnM a
-bindLocalNames names enclosed_scope
- = do { lcl_env <- getLclEnv
- ; let th_level = thLevel (tcl_th_ctxt lcl_env)
- th_bndrs' = extendNameEnvList (tcl_th_bndrs lcl_env)
- [ (n, (NotTopLevel, th_level)) | n <- names ]
- rdr_env' = extendLocalRdrEnvList (tcl_rdr lcl_env) names
- ; setLclEnv (lcl_env { tcl_th_bndrs = th_bndrs'
- , tcl_rdr = rdr_env' })
- enclosed_scope }
-
-bindLocalNamesFV :: [Name] -> RnM (a, FreeVars) -> RnM (a, FreeVars)
-bindLocalNamesFV names enclosed_scope
- = do { (result, fvs) <- bindLocalNames names enclosed_scope
- ; return (result, delFVs names fvs) }
-
--------------------------------------
-
-extendTyVarEnvFVRn :: [Name] -> RnM (a, FreeVars) -> RnM (a, FreeVars)
-extendTyVarEnvFVRn tyvars thing_inside = bindLocalNamesFV tyvars thing_inside
-
--------------------------------------
-checkDupRdrNames :: [Located RdrName] -> RnM ()
--- Check for duplicated names in a binding group
-checkDupRdrNames rdr_names_w_loc
- = mapM_ (dupNamesErr getLoc) dups
- where
- (_, dups) = removeDups (\n1 n2 -> unLoc n1 `compare` unLoc n2) rdr_names_w_loc
-
-checkDupNames :: [Name] -> RnM ()
--- Check for duplicated names in a binding group
-checkDupNames names = check_dup_names (filterOut isSystemName names)
- -- See Note [Binders in Template Haskell] in Convert
-
-check_dup_names :: [Name] -> RnM ()
-check_dup_names names
- = mapM_ (dupNamesErr nameSrcSpan) dups
- where
- (_, dups) = removeDups (\n1 n2 -> nameOccName n1 `compare` nameOccName n2) names
-
----------------------
-checkShadowedRdrNames :: [Located RdrName] -> RnM ()
-checkShadowedRdrNames loc_rdr_names
- = do { envs <- getRdrEnvs
- ; checkShadowedOccs envs get_loc_occ filtered_rdrs }
- where
- filtered_rdrs = filterOut (isExact . unLoc) loc_rdr_names
- -- See Note [Binders in Template Haskell] in Convert
- get_loc_occ (L loc rdr) = (loc,rdrNameOcc rdr)
-
-checkDupAndShadowedNames :: (GlobalRdrEnv, LocalRdrEnv) -> [Name] -> RnM ()
-checkDupAndShadowedNames envs names
- = do { check_dup_names filtered_names
- ; checkShadowedOccs envs get_loc_occ filtered_names }
- where
- filtered_names = filterOut isSystemName names
- -- See Note [Binders in Template Haskell] in Convert
- get_loc_occ name = (nameSrcSpan name, nameOccName name)
-
--------------------------------------
-checkShadowedOccs :: (GlobalRdrEnv, LocalRdrEnv)
- -> (a -> (SrcSpan, OccName))
- -> [a] -> RnM ()
-checkShadowedOccs (global_env,local_env) get_loc_occ ns
- = whenWOptM Opt_WarnNameShadowing $
- do { traceRn "checkShadowedOccs:shadow" (ppr (map get_loc_occ ns))
- ; mapM_ check_shadow ns }
- where
- check_shadow n
- | startsWithUnderscore occ = return () -- Do not report shadowing for "_x"
- -- See #3262
- | Just n <- mb_local = complain [text "bound at" <+> ppr (nameSrcLoc n)]
- | otherwise = do { gres' <- filterM is_shadowed_gre gres
- ; complain (map pprNameProvenance gres') }
- where
- (loc,occ) = get_loc_occ n
- mb_local = lookupLocalRdrOcc local_env occ
- gres = lookupGRE_RdrName (mkRdrUnqual occ) global_env
- -- Make an Unqualified RdrName and look that up, so that
- -- we don't find any GREs that are in scope qualified-only
-
- complain [] = return ()
- complain pp_locs = addWarnAt (Reason Opt_WarnNameShadowing)
- loc
- (shadowedNameWarn occ pp_locs)
-
- is_shadowed_gre :: GlobalRdrElt -> RnM Bool
- -- Returns False for record selectors that are shadowed, when
- -- punning or wild-cards are on (cf #2723)
- is_shadowed_gre gre | isRecFldGRE gre
- = do { dflags <- getDynFlags
- ; return $ not (xopt LangExt.RecordPuns dflags
- || xopt LangExt.RecordWildCards dflags) }
- is_shadowed_gre _other = return True
-
-
-{-
-************************************************************************
-* *
-\subsection{Free variable manipulation}
-* *
-************************************************************************
--}
-
--- A useful utility
-addFvRn :: FreeVars -> RnM (thing, FreeVars) -> RnM (thing, FreeVars)
-addFvRn fvs1 thing_inside = do { (res, fvs2) <- thing_inside
- ; return (res, fvs1 `plusFV` fvs2) }
-
-mapFvRn :: (a -> RnM (b, FreeVars)) -> [a] -> RnM ([b], FreeVars)
-mapFvRn f xs = do stuff <- mapM f xs
- case unzip stuff of
- (ys, fvs_s) -> return (ys, plusFVs fvs_s)
-
-mapMaybeFvRn :: (a -> RnM (b, FreeVars)) -> Maybe a -> RnM (Maybe b, FreeVars)
-mapMaybeFvRn _ Nothing = return (Nothing, emptyFVs)
-mapMaybeFvRn f (Just x) = do { (y, fvs) <- f x; return (Just y, fvs) }
-
-{-
-************************************************************************
-* *
-\subsection{Envt utility functions}
-* *
-************************************************************************
--}
-
-warnUnusedTopBinds :: [GlobalRdrElt] -> RnM ()
-warnUnusedTopBinds gres
- = whenWOptM Opt_WarnUnusedTopBinds
- $ do env <- getGblEnv
- let isBoot = tcg_src env == HsBootFile
- let noParent gre = case gre_par gre of
- NoParent -> True
- _ -> False
- -- Don't warn about unused bindings with parents in
- -- .hs-boot files, as you are sometimes required to give
- -- unused bindings (trac #3449).
- -- HOWEVER, in a signature file, you are never obligated to put a
- -- definition in the main text. Thus, if you define something
- -- and forget to export it, we really DO want to warn.
- gres' = if isBoot then filter noParent gres
- else gres
- warnUnusedGREs gres'
-
-
--- | Checks to see if we need to warn for -Wunused-record-wildcards or
--- -Wredundant-record-wildcards
-checkUnusedRecordWildcard :: SrcSpan
- -> FreeVars
- -> Maybe [Name]
- -> RnM ()
-checkUnusedRecordWildcard _ _ Nothing = return ()
-checkUnusedRecordWildcard loc _ (Just []) = do
- -- Add a new warning if the .. pattern binds no variables
- setSrcSpan loc $ warnRedundantRecordWildcard
-checkUnusedRecordWildcard loc fvs (Just dotdot_names) =
- setSrcSpan loc $ warnUnusedRecordWildcard dotdot_names fvs
-
-
--- | Produce a warning when the `..` pattern binds no new
--- variables.
---
--- @
--- data P = P { x :: Int }
---
--- foo (P{x, ..}) = x
--- @
---
--- The `..` here doesn't bind any variables as `x` is already bound.
-warnRedundantRecordWildcard :: RnM ()
-warnRedundantRecordWildcard =
- whenWOptM Opt_WarnRedundantRecordWildcards
- (addWarn (Reason Opt_WarnRedundantRecordWildcards)
- redundantWildcardWarning)
-
-
--- | Produce a warning when no variables bound by a `..` pattern are used.
---
--- @
--- data P = P { x :: Int }
---
--- foo (P{..}) = ()
--- @
---
--- The `..` pattern binds `x` but it is not used in the RHS so we issue
--- a warning.
-warnUnusedRecordWildcard :: [Name] -> FreeVars -> RnM ()
-warnUnusedRecordWildcard ns used_names = do
- let used = filter (`elemNameSet` used_names) ns
- traceRn "warnUnused" (ppr ns $$ ppr used_names $$ ppr used)
- warnIfFlag Opt_WarnUnusedRecordWildcards (null used)
- unusedRecordWildcardWarning
-
-
-
-warnUnusedLocalBinds, warnUnusedMatches, warnUnusedTypePatterns
- :: [Name] -> FreeVars -> RnM ()
-warnUnusedLocalBinds = check_unused Opt_WarnUnusedLocalBinds
-warnUnusedMatches = check_unused Opt_WarnUnusedMatches
-warnUnusedTypePatterns = check_unused Opt_WarnUnusedTypePatterns
-
-check_unused :: WarningFlag -> [Name] -> FreeVars -> RnM ()
-check_unused flag bound_names used_names
- = whenWOptM flag (warnUnused flag (filterOut (`elemNameSet` used_names)
- bound_names))
-
--------------------------
--- Helpers
-warnUnusedGREs :: [GlobalRdrElt] -> RnM ()
-warnUnusedGREs gres = mapM_ warnUnusedGRE gres
-
-warnUnused :: WarningFlag -> [Name] -> RnM ()
-warnUnused flag names = do
- fld_env <- mkFieldEnv <$> getGlobalRdrEnv
- mapM_ (warnUnused1 flag fld_env) names
-
-warnUnused1 :: WarningFlag -> NameEnv (FieldLabelString, Name) -> Name -> RnM ()
-warnUnused1 flag fld_env name
- = when (reportable name occ) $
- addUnusedWarning flag
- occ (nameSrcSpan name)
- (text $ "Defined but not used" ++ opt_str)
- where
- occ = case lookupNameEnv fld_env name of
- Just (fl, _) -> mkVarOccFS fl
- Nothing -> nameOccName name
- opt_str = case flag of
- Opt_WarnUnusedTypePatterns -> " on the right hand side"
- _ -> ""
-
-warnUnusedGRE :: GlobalRdrElt -> RnM ()
-warnUnusedGRE gre@(GRE { gre_name = name, gre_lcl = lcl, gre_imp = is })
- | lcl = do fld_env <- mkFieldEnv <$> getGlobalRdrEnv
- warnUnused1 Opt_WarnUnusedTopBinds fld_env name
- | otherwise = when (reportable name occ) (mapM_ warn is)
- where
- occ = greOccName gre
- warn spec = addUnusedWarning Opt_WarnUnusedTopBinds occ span msg
- where
- span = importSpecLoc spec
- pp_mod = quotes (ppr (importSpecModule spec))
- msg = text "Imported from" <+> pp_mod <+> ptext (sLit "but not used")
-
--- | Make a map from selector names to field labels and parent tycon
--- names, to be used when reporting unused record fields.
-mkFieldEnv :: GlobalRdrEnv -> NameEnv (FieldLabelString, Name)
-mkFieldEnv rdr_env = mkNameEnv [ (gre_name gre, (lbl, par_is (gre_par gre)))
- | gres <- occEnvElts rdr_env
- , gre <- gres
- , Just lbl <- [greLabel gre]
- ]
-
--- | Should we report the fact that this 'Name' is unused? The
--- 'OccName' may differ from 'nameOccName' due to
--- DuplicateRecordFields.
-reportable :: Name -> OccName -> Bool
-reportable name occ
- | isWiredInName name = False -- Don't report unused wired-in names
- -- Otherwise we get a zillion warnings
- -- from Data.Tuple
- | otherwise = not (startsWithUnderscore occ)
-
-addUnusedWarning :: WarningFlag -> OccName -> SrcSpan -> SDoc -> RnM ()
-addUnusedWarning flag occ span msg
- = addWarnAt (Reason flag) span $
- sep [msg <> colon,
- nest 2 $ pprNonVarNameSpace (occNameSpace occ)
- <+> quotes (ppr occ)]
-
-unusedRecordWildcardWarning :: SDoc
-unusedRecordWildcardWarning =
- wildcardDoc $ text "No variables bound in the record wildcard match are used"
-
-redundantWildcardWarning :: SDoc
-redundantWildcardWarning =
- wildcardDoc $ text "Record wildcard does not bind any new variables"
-
-wildcardDoc :: SDoc -> SDoc
-wildcardDoc herald =
- herald
- $$ nest 2 (text "Possible fix" <> colon <+> text "omit the"
- <+> quotes (text ".."))
-
-addNameClashErrRn :: RdrName -> [GlobalRdrElt] -> RnM ()
-addNameClashErrRn rdr_name gres
- | all isLocalGRE gres && not (all isRecFldGRE gres)
- -- If there are two or more *local* defns, we'll have reported
- = return () -- that already, and we don't want an error cascade
- | otherwise
- = addErr (vcat [ text "Ambiguous occurrence" <+> quotes (ppr rdr_name)
- , text "It could refer to"
- , nest 3 (vcat (msg1 : msgs)) ])
- where
- (np1:nps) = gres
- msg1 = text "either" <+> ppr_gre np1
- msgs = [text " or" <+> ppr_gre np | np <- nps]
- ppr_gre gre = sep [ pp_gre_name gre <> comma
- , pprNameProvenance gre]
-
- -- When printing the name, take care to qualify it in the same
- -- way as the provenance reported by pprNameProvenance, namely
- -- the head of 'gre_imp'. Otherwise we get confusing reports like
- -- Ambiguous occurrence ‘null’
- -- It could refer to either ‘T15487a.null’,
- -- imported from ‘Prelude’ at T15487.hs:1:8-13
- -- or ...
- -- See #15487
- pp_gre_name gre@(GRE { gre_name = name, gre_par = parent
- , gre_lcl = lcl, gre_imp = iss })
- | FldParent { par_lbl = Just lbl } <- parent
- = text "the field" <+> quotes (ppr lbl)
- | otherwise
- = quotes (pp_qual <> dot <> ppr (nameOccName name))
- where
- pp_qual | lcl
- = ppr (nameModule name)
- | imp : _ <- iss -- This 'imp' is the one that
- -- pprNameProvenance chooses
- , ImpDeclSpec { is_as = mod } <- is_decl imp
- = ppr mod
- | otherwise
- = pprPanic "addNameClassErrRn" (ppr gre $$ ppr iss)
- -- Invariant: either 'lcl' is True or 'iss' is non-empty
-
-shadowedNameWarn :: OccName -> [SDoc] -> SDoc
-shadowedNameWarn occ shadowed_locs
- = sep [text "This binding for" <+> quotes (ppr occ)
- <+> text "shadows the existing binding" <> plural shadowed_locs,
- nest 2 (vcat shadowed_locs)]
-
-
-unknownSubordinateErr :: SDoc -> RdrName -> SDoc
-unknownSubordinateErr doc op -- Doc is "method of class" or
- -- "field of constructor"
- = quotes (ppr op) <+> text "is not a (visible)" <+> doc
-
-
-dupNamesErr :: Outputable n => (n -> SrcSpan) -> NE.NonEmpty n -> RnM ()
-dupNamesErr get_loc names
- = addErrAt big_loc $
- vcat [text "Conflicting definitions for" <+> quotes (ppr (NE.head names)),
- locations]
- where
- locs = map get_loc (NE.toList names)
- big_loc = foldr1 combineSrcSpans locs
- locations = text "Bound at:" <+> vcat (map ppr (sort locs))
-
-badQualBndrErr :: RdrName -> SDoc
-badQualBndrErr rdr_name
- = text "Qualified name in binding position:" <+> ppr rdr_name
-
-typeAppErr :: String -> LHsType GhcPs -> SDoc
-typeAppErr what (L _ k)
- = hang (text "Illegal visible" <+> text what <+> text "application"
- <+> quotes (char '@' <> ppr k))
- 2 (text "Perhaps you intended to use TypeApplications")
-
-checkTupSize :: Int -> RnM ()
-checkTupSize tup_size
- | tup_size <= mAX_TUPLE_SIZE
- = return ()
- | otherwise
- = addErr (sep [text "A" <+> int tup_size <> ptext (sLit "-tuple is too large for GHC"),
- nest 2 (parens (text "max size is" <+> int mAX_TUPLE_SIZE)),
- nest 2 (text "Workaround: use nested tuples or define a data type")])
-
-
-{-
-************************************************************************
-* *
-\subsection{Contexts for renaming errors}
-* *
-************************************************************************
--}
-
--- AZ:TODO: Change these all to be Name instead of RdrName.
--- Merge TcType.UserTypeContext in to it.
-data HsDocContext
- = TypeSigCtx SDoc
- | StandaloneKindSigCtx SDoc
- | PatCtx
- | SpecInstSigCtx
- | DefaultDeclCtx
- | ForeignDeclCtx (Located RdrName)
- | DerivDeclCtx
- | RuleCtx FastString
- | TyDataCtx (Located RdrName)
- | TySynCtx (Located RdrName)
- | TyFamilyCtx (Located RdrName)
- | FamPatCtx (Located RdrName) -- The patterns of a type/data family instance
- | ConDeclCtx [Located Name]
- | ClassDeclCtx (Located RdrName)
- | ExprWithTySigCtx
- | TypBrCtx
- | HsTypeCtx
- | GHCiCtx
- | SpliceTypeCtx (LHsType GhcPs)
- | ClassInstanceCtx
- | GenericCtx SDoc -- Maybe we want to use this more!
-
-withHsDocContext :: HsDocContext -> SDoc -> SDoc
-withHsDocContext ctxt doc = doc $$ inHsDocContext ctxt
-
-inHsDocContext :: HsDocContext -> SDoc
-inHsDocContext ctxt = text "In" <+> pprHsDocContext ctxt
-
-pprHsDocContext :: HsDocContext -> SDoc
-pprHsDocContext (GenericCtx doc) = doc
-pprHsDocContext (TypeSigCtx doc) = text "the type signature for" <+> doc
-pprHsDocContext (StandaloneKindSigCtx doc) = text "the standalone kind signature for" <+> doc
-pprHsDocContext PatCtx = text "a pattern type-signature"
-pprHsDocContext SpecInstSigCtx = text "a SPECIALISE instance pragma"
-pprHsDocContext DefaultDeclCtx = text "a `default' declaration"
-pprHsDocContext DerivDeclCtx = text "a deriving declaration"
-pprHsDocContext (RuleCtx name) = text "the transformation rule" <+> ftext name
-pprHsDocContext (TyDataCtx tycon) = text "the data type declaration for" <+> quotes (ppr tycon)
-pprHsDocContext (FamPatCtx tycon) = text "a type pattern of family instance for" <+> quotes (ppr tycon)
-pprHsDocContext (TySynCtx name) = text "the declaration for type synonym" <+> quotes (ppr name)
-pprHsDocContext (TyFamilyCtx name) = text "the declaration for type family" <+> quotes (ppr name)
-pprHsDocContext (ClassDeclCtx name) = text "the declaration for class" <+> quotes (ppr name)
-pprHsDocContext ExprWithTySigCtx = text "an expression type signature"
-pprHsDocContext TypBrCtx = text "a Template-Haskell quoted type"
-pprHsDocContext HsTypeCtx = text "a type argument"
-pprHsDocContext GHCiCtx = text "GHCi input"
-pprHsDocContext (SpliceTypeCtx hs_ty) = text "the spliced type" <+> quotes (ppr hs_ty)
-pprHsDocContext ClassInstanceCtx = text "TcSplice.reifyInstances"
-
-pprHsDocContext (ForeignDeclCtx name)
- = text "the foreign declaration for" <+> quotes (ppr name)
-pprHsDocContext (ConDeclCtx [name])
- = text "the definition of data constructor" <+> quotes (ppr name)
-pprHsDocContext (ConDeclCtx names)
- = text "the definition of data constructors" <+> interpp'SP names
diff --git a/compiler/rename/rename.tex b/compiler/rename/rename.tex
deleted file mode 100644
index b3f8e1d770..0000000000
--- a/compiler/rename/rename.tex
+++ /dev/null
@@ -1,18 +0,0 @@
-\documentstyle{report}
-\input{lit-style}
-
-\begin{document}
-\centerline{{\Large{rename}}}
-\tableofcontents
-
-\input{Rename} % {Renaming and dependency analysis passes}
-\input{RnSource} % {Main pass of renamer}
-\input{RnMonad} % {The monad used by the renamer}
-\input{RnEnv} % {Environment manipulation for the renamer monad}
-\input{RnHsSyn} % {Specialisations of the @HsSyn@ syntax for the renamer}
-\input{RnNames} % {Extracting imported and top-level names in scope}
-\input{RnExpr} % {Renaming of expressions}
-\input{RnBinds} % {Renaming and dependency analysis of bindings}
-\input{RnIfaces} % {Cacheing and Renaming of Interfaces}
-
-\end{document}