summaryrefslogtreecommitdiff
path: root/compiler/rename
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rename')
-rw-r--r--compiler/rename/RnTypes.hs107
1 files changed, 28 insertions, 79 deletions
diff --git a/compiler/rename/RnTypes.hs b/compiler/rename/RnTypes.hs
index b75fcf2fc4..35b67a2fd1 100644
--- a/compiler/rename/RnTypes.hs
+++ b/compiler/rename/RnTypes.hs
@@ -62,7 +62,7 @@ import FastString
import Maybes
import qualified GHC.LanguageExtensions as LangExt
-import Data.List ( (\\), nubBy, partition )
+import Data.List ( nubBy, partition )
import Control.Monad ( unless, when )
#include "HsVersions.h"
@@ -215,12 +215,11 @@ extractFilteredRdrTyVars hs_ty
-- When the extension is disabled, the function returns the argument
-- and empty list. See Note [Renaming named wild cards]
partition_nwcs :: FreeKiTyVars -> RnM (FreeKiTyVars, [Located RdrName])
-partition_nwcs free_vars@(FKTV { fktv_tys = tys, fktv_all = all })
+partition_nwcs free_vars@(FKTV { fktv_tys = tys })
= do { wildcards_enabled <- fmap (xopt LangExt.NamedWildCards) getDynFlags
; let (nwcs, no_nwcs) | wildcards_enabled = partition is_wildcard tys
| otherwise = ([], tys)
- free_vars' = free_vars { fktv_tys = no_nwcs
- , fktv_all = all \\ nwcs }
+ free_vars' = free_vars { fktv_tys = no_nwcs }
; return (free_vars', nwcs) }
where
is_wildcard :: Located RdrName -> Bool
@@ -1538,20 +1537,16 @@ See also Note [HsBSig binder lists] in HsTypes
-}
data FreeKiTyVars = FKTV { fktv_kis :: [Located RdrName]
- , _fktv_k_set :: OccSet -- for efficiency,
- -- only used internally
- , fktv_tys :: [Located RdrName]
- , _fktv_t_set :: OccSet
- , fktv_all :: [Located RdrName] }
+ , fktv_tys :: [Located RdrName] }
instance Outputable FreeKiTyVars where
- ppr (FKTV kis _ tys _ _) = ppr (kis, tys)
+ ppr (FKTV kis tys) = ppr (kis, tys)
emptyFKTV :: FreeKiTyVars
-emptyFKTV = FKTV [] emptyOccSet [] emptyOccSet []
+emptyFKTV = FKTV [] []
freeKiTyVarsAllVars :: FreeKiTyVars -> [Located RdrName]
-freeKiTyVarsAllVars = fktv_all
+freeKiTyVarsAllVars (FKTV tys kvs) = tys ++ kvs
freeKiTyVarsKindVars :: FreeKiTyVars -> [Located RdrName]
freeKiTyVarsKindVars = fktv_kis
@@ -1560,15 +1555,11 @@ freeKiTyVarsTypeVars :: FreeKiTyVars -> [Located RdrName]
freeKiTyVarsTypeVars = fktv_tys
filterInScope :: LocalRdrEnv -> FreeKiTyVars -> FreeKiTyVars
-filterInScope rdr_env (FKTV kis k_set tys t_set all)
+filterInScope rdr_env (FKTV kis tys)
= FKTV (filterOut in_scope kis)
- (filterOccSet (not . in_scope_occ) k_set)
(filterOut in_scope tys)
- (filterOccSet (not . in_scope_occ) t_set)
- (filterOut in_scope all)
where
in_scope = inScope rdr_env . unLoc
- in_scope_occ occ = isJust $ lookupLocalRdrOcc rdr_env occ
inScope :: LocalRdrEnv -> RdrName -> Bool
inScope rdr_env rdr = rdr `elemLocalRdrEnv` rdr_env
@@ -1582,10 +1573,10 @@ extractHsTyRdrTyVars :: LHsType GhcPs -> RnM FreeKiTyVars
-- occurrence is returned.
-- See Note [Kind and type-variable binders]
extractHsTyRdrTyVars ty
- = do { FKTV kis k_set tys t_set all <- extract_lty TypeLevel ty emptyFKTV
- ; return (FKTV (nubL kis) k_set
- (nubL tys) t_set
- (nubL all)) }
+ = do { FKTV kis tys <- extract_lty TypeLevel ty emptyFKTV
+ ; return (FKTV (nubL kis)
+ (nubL tys)) }
+
-- | Extracts free type and kind variables from types in a list.
-- When the same name occurs multiple times in the types, only the first
@@ -1604,8 +1595,8 @@ extractHsTysRdrTyVarsDups tys
-- | Removes multiple occurrences of the same name from FreeKiTyVars.
rmDupsInRdrTyVars :: FreeKiTyVars -> FreeKiTyVars
-rmDupsInRdrTyVars (FKTV kis k_set tys t_set all)
- = FKTV (nubL kis) k_set (nubL tys) t_set (nubL all)
+rmDupsInRdrTyVars (FKTV kis tys)
+ = FKTV (nubL kis) (nubL tys)
extractRdrKindSigVars :: LFamilyResultSig GhcPs -> RnM [Located RdrName]
extractRdrKindSigVars (L _ resultSig)
@@ -1715,46 +1706,38 @@ extract_hs_tv_bndrs :: [LHsTyVarBndr GhcPs] -> FreeKiTyVars
-- 'b' is a free type variable
-- 'e' is a free kind variable
extract_hs_tv_bndrs tvs
- (FKTV acc_kvs acc_k_set acc_tvs acc_t_set acc_all)
+ (FKTV acc_kvs acc_tvs)
-- Note accumulator comes first
- (FKTV body_kvs body_k_set body_tvs body_t_set body_all)
+ (FKTV body_kvs body_tvs)
| null tvs
= return $
- FKTV (body_kvs ++ acc_kvs) (body_k_set `unionOccSets` acc_k_set)
- (body_tvs ++ acc_tvs) (body_t_set `unionOccSets` acc_t_set)
- (body_all ++ acc_all)
+ FKTV (body_kvs ++ acc_kvs) (body_tvs ++ acc_tvs)
| otherwise
- = do { FKTV bndr_kvs bndr_k_set _ _ _
+ = do { FKTV bndr_kvs _
<- foldrM extract_lkind emptyFKTV [k | L _ (KindedTyVar _ k) <- tvs]
- ; let locals = mkOccSet $ map (rdrNameOcc . hsLTyVarName) tvs
+ ; let locals = map hsLTyVarName tvs
; return $
- FKTV (filterOut ((`elemOccSet` locals) . rdrNameOcc . unLoc) (bndr_kvs ++ body_kvs) ++ acc_kvs)
- ((body_k_set `minusOccSet` locals) `unionOccSets` acc_k_set `unionOccSets` bndr_k_set)
- (filterOut ((`elemOccSet` locals) . rdrNameOcc . unLoc) body_tvs ++ acc_tvs)
- ((body_t_set `minusOccSet` locals) `unionOccSets` acc_t_set)
- (filterOut ((`elemOccSet` locals) . rdrNameOcc . unLoc) (bndr_kvs ++ body_all) ++ acc_all) }
+ FKTV (filterOut ((`elem` locals) . unLoc) (bndr_kvs ++ body_kvs)
+ ++ acc_kvs)
+ (filterOut ((`elem` locals) . unLoc) body_tvs ++ acc_tvs) }
extract_tv :: TypeOrKind -> Located RdrName -> FreeKiTyVars
-> RnM FreeKiTyVars
extract_tv t_or_k ltv@(L _ tv) acc
| isRdrTyVar tv = case acc of
- FKTV kvs k_set tvs t_set all
+ FKTV kvs tvs
| isTypeLevel t_or_k
- -> do { when (not_exact && occ `elemOccSet` k_set) $
+ -> do { when (ltv `elemRdr` kvs) $
mixedVarsErr ltv
- ; return (FKTV kvs k_set (ltv : tvs) (t_set `extendOccSet` occ)
- (ltv : all)) }
+ ; return (FKTV kvs (ltv : tvs)) }
| otherwise
- -> do { when (not_exact && occ `elemOccSet` t_set) $
+ -> do { when (ltv `elemRdr` tvs) $
mixedVarsErr ltv
- ; return (FKTV (ltv : kvs) (k_set `extendOccSet` occ) tvs t_set
- (ltv : all)) }
+ ; return (FKTV (ltv : kvs) tvs) }
| otherwise = return acc
where
- occ = rdrNameOcc tv
- -- See Note [TypeInType validity checking and Template Haskell]
- not_exact = not $ isExact tv
+ elemRdr x = any (eqLocated x)
mixedVarsErr :: Located RdrName -> RnM ()
mixedVarsErr (L loc tv)
@@ -1767,37 +1750,3 @@ mixedVarsErr (L loc tv)
-- just used in this module; seemed convenient here
nubL :: Eq a => [Located a] -> [Located a]
nubL = nubBy eqLocated
-
-{-
-Note [TypeInType validity checking and Template Haskell]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-extract_tv enforces an invariant that no variable can be used as both a kind
-and a type unless -XTypeInType is enabled. It does so by accumulating two sets
-of variables' OccNames (one for type variables and one for kind variables) that
-it has seen before. If a new type variable's OccName appears in the kind set,
-then it errors, and similarly for kind variables and the type set.
-
-This relies on the assumption that any two variables with the same OccName
-are the same. While this is always true of user-written code, it is not always
-true in the presence of Template Haskell! GHC Trac #12503 demonstrates a
-scenario where two different Exact TH-generated names can have the same
-OccName. As a result, if one of these Exact names is for a type variable
-and the other Exact name is for a kind variable, then extracting them both
-can lead to a spurious error in extract_tv.
-
-To avoid such a scenario, we simply don't check the invariant in extract_tv
-when the name is Exact. This allows Template Haskell users to write code that
-uses -XPolyKinds without needing to enable -XTypeInType.
-
-This is a somewhat arbitrary design choice, as adding this special case causes
-this code to be accepted when spliced in via Template Haskell:
-
- data T1 k e
- class C1 b
- instance C1 (T1 k (e :: k))
-
-Even if -XTypeInType is _not enabled. But accepting too many programs without
-the prerequisite GHC extensions is better than the alternative, where some
-programs would not be accepted unless enabling an extension which has nothing
-to do with the code itself.
--}