summaryrefslogtreecommitdiff
path: root/compiler/GHC/Rename/Module.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Rename/Module.hs')
-rw-r--r--compiler/GHC/Rename/Module.hs142
1 files changed, 98 insertions, 44 deletions
diff --git a/compiler/GHC/Rename/Module.hs b/compiler/GHC/Rename/Module.hs
index 15775b8cf2..b6c8a9b801 100644
--- a/compiler/GHC/Rename/Module.hs
+++ b/compiler/GHC/Rename/Module.hs
@@ -424,11 +424,11 @@ patchCCallTarget unit callTarget =
rnSrcInstDecl :: InstDecl GhcPs -> RnM (InstDecl GhcRn, FreeVars)
rnSrcInstDecl (TyFamInstD { tfid_inst = tfi })
- = do { (tfi', fvs) <- rnTyFamInstDecl NonAssocTyFamEqn tfi
+ = do { (tfi', fvs) <- rnTyFamInstDecl (NonAssocTyFamEqn NotClosedTyFam) tfi
; return (TyFamInstD { tfid_ext = noExtField, tfid_inst = tfi' }, fvs) }
rnSrcInstDecl (DataFamInstD { dfid_inst = dfi })
- = do { (dfi', fvs) <- rnDataFamInstDecl NonAssocTyFamEqn dfi
+ = do { (dfi', fvs) <- rnDataFamInstDecl (NonAssocTyFamEqn NotClosedTyFam) dfi
; return (DataFamInstD { dfid_ext = noExtField, dfid_inst = dfi' }, fvs) }
rnSrcInstDecl (ClsInstD { cid_inst = cid })
@@ -760,8 +760,12 @@ rnFamInstEqn doc atfi rhs_kvars
all_nms = all_imp_var_names ++ hsLTyVarNames bndrs'
; warnUnusedTypePatterns all_nms nms_used
- ; let all_fvs = (rhs_fvs `plusFV` pat_fvs) `addOneFV` unLoc tycon'
- -- type instance => use, hence addOneFV
+ ; let eqn_fvs = rhs_fvs `plusFV` pat_fvs
+ -- See Note [Type family equations and occurrences]
+ all_fvs = case atfi of
+ NonAssocTyFamEqn ClosedTyFam
+ -> eqn_fvs
+ _ -> eqn_fvs `addOneFV` unLoc tycon'
; return (HsIB { hsib_ext = all_imp_var_names -- Note [Wildcards in family instances]
, hsib_body
@@ -776,14 +780,14 @@ rnFamInstEqn doc atfi rhs_kvars
-- The parent class, if we are dealing with an associated type family
-- instance.
mb_cls = case atfi of
- NonAssocTyFamEqn -> Nothing
+ NonAssocTyFamEqn _ -> Nothing
AssocTyFamDeflt cls -> Just cls
AssocTyFamInst cls _ -> Just cls
-- The type variables from the instance head, if we are dealing with an
-- associated type family instance.
inst_tvs = case atfi of
- NonAssocTyFamEqn -> []
+ NonAssocTyFamEqn _ -> []
AssocTyFamDeflt _ -> []
AssocTyFamInst _ inst_tvs -> inst_tvs
@@ -806,48 +810,62 @@ rnTyFamInstDecl :: AssocTyFamInfo
-> TyFamInstDecl GhcPs
-> RnM (TyFamInstDecl GhcRn, FreeVars)
rnTyFamInstDecl atfi (TyFamInstDecl { tfid_eqn = eqn })
- = do { (eqn', fvs) <- rnTyFamInstEqn atfi NotClosedTyFam eqn
+ = do { (eqn', fvs) <- rnTyFamInstEqn atfi 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')
+-- with a parent type class ('NonAssocTyFamEqn'). Examples:
--
--- 2. An associated type family default declaration ('AssocTyFamDeflt')
+-- @
+-- type family F a
+-- type instance F Int = Bool -- NonAssocTyFamEqn NotClosed
--
--- 3. An associated type family instance declaration ('AssocTyFamInst')
+-- type family G a where
+-- G Int = Bool -- NonAssocTyFamEqn Closed
+-- @
+--
+-- 2. An associated type family default declaration ('AssocTyFamDeflt').
+-- Example:
+--
+-- @
+-- class C a where
+-- type A a
+-- type instance A a = a -> a -- AssocTyFamDeflt C
+-- @
+--
+-- 3. An associated type family instance declaration ('AssocTyFamInst').
+-- Example:
+--
+-- @
+-- instance C a => C [a] where
+-- type A [a] = Bool -- AssocTyFamInst C [a]
+-- @
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
+ ClosedTyFamInfo -- Is this a closed type family?
+ | 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
+ | ClosedTyFam
rnTyFamInstEqn :: AssocTyFamInfo
- -> ClosedTyFamInfo
-> TyFamInstEqn GhcPs
-> RnM (TyFamInstEqn GhcRn, FreeVars)
-rnTyFamInstEqn atfi ctf_info
+rnTyFamInstEqn atfi
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) }
+ = rnFamInstEqn (TySynCtx tycon) atfi rhs_kvs eqn rnTySyn
+ where
+ rhs_kvs = extractHsTyRdrTyVarsKindVars rhs
rnTyFamDefltDecl :: Name
-> TyFamDefltDecl GhcPs
@@ -995,6 +1013,51 @@ 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 GHC.Tc.Validity.checkValidFamPats.
+
+Note [Type family equations and occurrences]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In most data/type family equations, the type family name used in the equation
+is treated as an occurrence. For example:
+
+ module A where
+ type family F a
+
+ module B () where
+ import B (F)
+ type instance F Int = Bool
+
+We do not want to warn about `F` being unused in the module `B`, as the
+instance constitutes a use site for `F`. The exception to this rule is closed
+type families, whose equations constitute a definition, not occurrences. For
+example:
+
+ module C () where
+ type family CF a where
+ CF Char = Float
+
+Here, we /do/ want to warn that `CF` is unused in the module `C`, as it is
+defined but not used (#18470).
+
+GHC accomplishes this in rnFamInstEqn when determining the set of free
+variables to return at the end. If renaming a data family or open type family
+equation, we add the name of the type family constructor to the set of returned
+free variables to ensure that the name is marked as an occurrence. If renaming
+a closed type family equation, we avoid adding the type family constructor name
+to the free variables. This is quite simple, but it is not a perfect solution.
+Consider this example:
+
+ module X () where
+ type family F a where
+ F Int = Bool
+ F Double = F Int
+
+At present, GHC will treat any use of a type family constructor on the RHS of a
+type family equation as an occurrence. Since `F` is used on the RHS of the
+second equation of `F`, it is treated as an occurrence, causing `F` not to be
+warned about. This is not ideal, since `F` isn't exported—it really /should/
+cause a warning to be emitted. There is some discussion in #10089/#12920 about
+how this limitation might be overcome, but until then, we stick to the
+simplistic solution above, as it fixes the egregious bug in #18470.
-}
@@ -1947,7 +2010,7 @@ rnFamDecl mb_cls (FamilyDecl { fdLName = tycon, fdTyVars = tyvars
; injectivity' <- traverse (rnInjectivityAnn tyvars' res_sig')
injectivity
; return ( (tyvars', res_sig', injectivity') , fv_kind ) }
- ; (info', fv2) <- rn_info tycon' info
+ ; (info', fv2) <- rn_info info
; return (FamilyDecl { fdExt = noExtField
, fdLName = tycon', fdTyVars = tyvars'
, fdFixity = fixity
@@ -1959,18 +2022,16 @@ rnFamDecl mb_cls (FamilyDecl { fdLName = tycon, fdTyVars = tyvars
kvs = extractRdrKindSigVars res_sig
----------------------
- rn_info :: Located Name
- -> FamilyInfo GhcPs -> RnM (FamilyInfo GhcRn, FreeVars)
- rn_info (L _ fam_name) (ClosedTypeFamily (Just eqns))
+ rn_info :: FamilyInfo GhcPs -> RnM (FamilyInfo GhcRn, FreeVars)
+ rn_info (ClosedTypeFamily (Just eqns))
= do { (eqns', fvs)
- <- rnList (rnTyFamInstEqn NonAssocTyFamEqn (ClosedTyFam tycon fam_name))
+ <- rnList (rnTyFamInstEqn (NonAssocTyFamEqn ClosedTyFam)) eqns
-- no class context
- eqns
; return (ClosedTypeFamily (Just eqns'), fvs) }
- rn_info _ (ClosedTypeFamily Nothing)
+ rn_info (ClosedTypeFamily Nothing)
= return (ClosedTypeFamily Nothing, emptyFVs)
- rn_info _ OpenTypeFamily = return (OpenTypeFamily, emptyFVs)
- rn_info _ DataFamily = return (DataFamily, emptyFVs)
+ rn_info OpenTypeFamily = return (OpenTypeFamily, emptyFVs)
+ rn_info DataFamily = return (DataFamily, emptyFVs)
rnFamResultSig :: HsDocContext
-> FamilyResultSig GhcPs
@@ -2114,13 +2175,6 @@ are no data constructors we allow h98_style = True
* *
***************************************************** -}
----------------
-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)