summaryrefslogtreecommitdiff
path: root/compiler/GHC/Rename/HsType.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Rename/HsType.hs')
-rw-r--r--compiler/GHC/Rename/HsType.hs193
1 files changed, 78 insertions, 115 deletions
diff --git a/compiler/GHC/Rename/HsType.hs b/compiler/GHC/Rename/HsType.hs
index ac92e300b5..cd5d431ee1 100644
--- a/compiler/GHC/Rename/HsType.hs
+++ b/compiler/GHC/Rename/HsType.hs
@@ -12,7 +12,7 @@ module GHC.Rename.HsType (
rnHsType, rnLHsType, rnLHsTypes, rnContext,
rnHsKind, rnLHsKind, rnLHsTypeArgs,
rnHsSigType, rnHsWcType,
- HsSigWcTypeScoping(..), rnHsSigWcType, rnHsPatSigType,
+ HsPatSigTypeScoping(..), rnHsSigWcType, rnHsPatSigType,
newTyVarNameRn,
rnConDeclFields,
rnLTyVar,
@@ -24,15 +24,15 @@ module GHC.Rename.HsType (
checkPrecMatch, checkSectionPrec,
-- Binding related stuff
- bindHsForAllTelescope,
+ bindHsOuterTyVarBndrs, bindHsForAllTelescope,
bindLHsTyVarBndr, bindLHsTyVarBndrs, WarnUnusedForalls(..),
rnImplicitBndrs, bindSigTyVarsFV, bindHsQTyVars,
FreeKiTyVars,
extractHsTyRdrTyVars, extractHsTyRdrTyVarsKindVars,
extractHsTysRdrTyVars, extractRdrKindSigVars,
extractConDeclGADTDetailsTyVars, extractDataDefnKindVars,
- extractHsTvBndrs, extractHsTyArgRdrKiTyVars,
- forAllOrNothing, nubL
+ extractHsOuterTvBndrs, extractHsTyArgRdrKiTyVars,
+ nubL
) where
import GHC.Prelude
@@ -82,7 +82,7 @@ to break several loops.
*********************************************************
-}
-data HsSigWcTypeScoping
+data HsPatSigTypeScoping
= AlwaysBind
-- ^ Always bind any free tyvars of the given type, regardless of whether we
-- have a forall at the top.
@@ -103,10 +103,6 @@ data HsSigWcTypeScoping
-- variables. If a RULE explicitly quantifies its type variables, then
-- 'NeverBind' is used instead. See also
-- @Note [Pattern signature binders and scoping]@ in "GHC.Hs.Type".
- | BindUnlessForall
- -- ^ Unless there's forall at the top, do the same thing as 'AlwaysBind'.
- -- This is only ever used in places where the \"@forall@-or-nothing\" rule
- -- is in effect. See @Note [forall-or-nothing rule]@.
| NeverBind
-- ^ Never bind any free tyvars. This is used for RULES that have both
-- explicit type and term variable binders, e.g.:
@@ -124,13 +120,19 @@ data HsSigWcTypeScoping
rnHsSigWcType :: HsDocContext
-> LHsSigWcType GhcPs
-> RnM (LHsSigWcType GhcRn, FreeVars)
-rnHsSigWcType doc (HsWC { hswc_body = HsIB { hsib_body = hs_ty }})
- = rn_hs_sig_wc_type BindUnlessForall doc hs_ty $ \nwcs imp_tvs body ->
- let ib_ty = HsIB { hsib_ext = imp_tvs, hsib_body = body }
- wc_ty = HsWC { hswc_ext = nwcs, hswc_body = ib_ty } in
- pure (wc_ty, emptyFVs)
-
-rnHsPatSigType :: HsSigWcTypeScoping
+rnHsSigWcType doc (HsWC { hswc_body =
+ sig_ty@(L loc (HsSig{sig_bndrs = outer_bndrs, sig_body = body_ty })) })
+ = do { free_vars <- filterInScopeM (extract_lhs_sig_ty sig_ty)
+ ; (nwc_rdrs', imp_tv_nms) <- partition_nwcs free_vars
+ ; let nwc_rdrs = nubL nwc_rdrs'
+ ; bindHsOuterTyVarBndrs doc Nothing imp_tv_nms outer_bndrs $ \outer_bndrs' ->
+ do { (wcs, body_ty', fvs) <- rnWcBody doc nwc_rdrs body_ty
+ ; pure ( HsWC { hswc_ext = wcs, hswc_body = L loc $
+ HsSig { sig_ext = noExtField
+ , sig_bndrs = outer_bndrs', sig_body = body_ty' }}
+ , fvs) } }
+
+rnHsPatSigType :: HsPatSigTypeScoping
-> HsDocContext
-> HsPatSigType GhcPs
-> (HsPatSigType GhcRn -> RnM (a, FreeVars))
@@ -145,33 +147,20 @@ rnHsPatSigType :: HsSigWcTypeScoping
rnHsPatSigType scoping ctx sig_ty thing_inside
= do { ty_sig_okay <- xoptM LangExt.ScopedTypeVariables
; checkErr ty_sig_okay (unexpectedPatSigTypeErr sig_ty)
- ; rn_hs_sig_wc_type scoping ctx (hsPatSigType sig_ty) $
- \nwcs imp_tvs body ->
- do { let sig_names = HsPSRn { hsps_nwcs = nwcs, hsps_imp_tvs = imp_tvs }
- sig_ty' = HsPS { hsps_ext = sig_names, hsps_body = body }
- ; thing_inside sig_ty'
- } }
-
--- The workhorse for rnHsSigWcType and rnHsPatSigType.
-rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext
- -> LHsType GhcPs
- -> ([Name] -- Wildcard names
- -> [Name] -- Implicitly bound type variable names
- -> LHsType GhcRn
- -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
-rn_hs_sig_wc_type scoping ctxt hs_ty thing_inside
- = do { free_vars <- filterInScopeM (extractHsTyRdrTyVars hs_ty)
+ ; free_vars <- filterInScopeM (extractHsTyRdrTyVars pat_sig_ty)
; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars
; let nwc_rdrs = nubL nwc_rdrs'
- ; implicit_bndrs <- case scoping of
- AlwaysBind -> pure tv_rdrs
- BindUnlessForall -> forAllOrNothing (isLHsInvisForAllTy hs_ty) tv_rdrs
- NeverBind -> pure []
- ; rnImplicitBndrs Nothing implicit_bndrs $ \ vars ->
- do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty
- ; (res, fvs2) <- thing_inside wcs vars hs_ty'
+ implicit_bndrs = case scoping of
+ AlwaysBind -> tv_rdrs
+ NeverBind -> []
+ ; rnImplicitBndrs Nothing implicit_bndrs $ \ imp_tvs ->
+ do { (nwcs, pat_sig_ty', fvs1) <- rnWcBody ctx nwc_rdrs pat_sig_ty
+ ; let sig_names = HsPSRn { hsps_nwcs = nwcs, hsps_imp_tvs = imp_tvs }
+ sig_ty' = HsPS { hsps_ext = sig_names, hsps_body = pat_sig_ty' }
+ ; (res, fvs2) <- thing_inside sig_ty'
; return (res, fvs1 `plusFV` fvs2) } }
+ where
+ pat_sig_ty = hsPatSigType sig_ty
rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars)
rnHsWcType ctxt (HsWC { hswc_body = hs_ty })
@@ -306,7 +295,7 @@ of the HsWildCardBndrs structure, and we are done.
*********************************************************
* *
- HsSigtype (i.e. no wildcards)
+ HsSigType (i.e. no wildcards)
* *
****************************************************** -}
@@ -316,76 +305,22 @@ rnHsSigType :: HsDocContext
-> 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)
- ; rdr_env <- getLocalRdrEnv
- ; vars0 <- forAllOrNothing (isLHsInvisForAllTy hs_ty)
- $ filterInScope rdr_env
- $ extractHsTyRdrTyVars hs_ty
- ; rnImplicitBndrs Nothing vars0 $ \ vars ->
- do { (body', fvs) <- rnLHsTyKi (mkTyKiEnv ctx level RnTypeBody) hs_ty
-
- ; return ( HsIB { hsib_ext = vars
- , hsib_body = body' }
+rnHsSigType ctx level
+ (L loc sig_ty@(HsSig { sig_bndrs = outer_bndrs, sig_body = body }))
+ = setSrcSpan loc $
+ do { traceRn "rnHsSigType" (ppr sig_ty)
+ ; case outer_bndrs of
+ HsOuterExplicit{} -> checkPolyKinds env sig_ty
+ HsOuterImplicit{} -> pure ()
+ ; imp_vars <- filterInScopeM $ extractHsTyRdrTyVars body
+ ; bindHsOuterTyVarBndrs ctx Nothing imp_vars outer_bndrs $ \outer_bndrs' ->
+ do { (body', fvs) <- rnLHsTyKi env body
+
+ ; return ( L loc $ HsSig { sig_ext = noExtField
+ , sig_bndrs = outer_bndrs', sig_body = body' }
, fvs ) } }
-
-{-
-Note [forall-or-nothing rule]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Free variables in signatures are usually bound in an implicit 'forall' at the
-beginning of user-written signatures. However, if the signature has an
-explicit, invisible forall at the beginning, this is disabled.
-
-The idea is nested foralls express something which is only expressible
-explicitly, while a top level forall could (usually) be replaced with an
-implicit binding. Top-level foralls alone ("forall.") are therefore an
-indication that the user is trying to be fastidious, so we don't implicitly
-bind any variables.
-
-Note that this rule only applies to outermost /in/visible 'forall's, and not
-outermost visible 'forall's. See #18660 for more on this point.
-
-Here are some concrete examples to demonstrate the forall-or-nothing rule in
-action:
-
- type F1 :: a -> b -> b -- Legal; a,b are implicitly quantified.
- -- Equivalently: forall a b. a -> b -> b
-
- type F2 :: forall a b. a -> b -> b -- Legal; explicitly quantified
-
- type F3 :: forall a. a -> b -> b -- Illegal; the forall-or-nothing rule says that
- -- if you quantify a, you must also quantify b
-
- type F4 :: forall a -> b -> b -- Legal; the top quantifier (forall a) is a /visible/
- -- quantifer, so the "nothing" part of the forall-or-nothing
- -- rule applies, and b is therefore implicitly quantified.
- -- Equivalently: forall b. forall a -> b -> b
-
- type F5 :: forall b. forall a -> b -> c -- Illegal; the forall-or-nothing rule says that
- -- if you quantify b, you must also quantify c
-
- type F6 :: forall a -> forall b. b -> c -- Legal: just like F4.
--}
-
--- | See @Note [forall-or-nothing rule]@. This tiny little function is used
--- (rather than its small body inlined) to indicate that we are implementing
--- that rule.
-forAllOrNothing :: Bool
- -- ^ True <=> explicit forall
- -- E.g. f :: forall a. a->b
- -- we do not want to bring 'b' into scope, hence True
- -- But f :: a -> b
- -- we want to bring both 'a' and 'b' into scope, hence False
- -> FreeKiTyVars
- -- ^ Free vars of the type
- -> RnM FreeKiTyVars
-forAllOrNothing has_outer_forall fvs = case has_outer_forall of
- True -> do
- traceRn "forAllOrNothing" $ text "has explicit outer forall"
- pure []
- False -> do
- traceRn "forAllOrNothing" $ text "no explicit forall. implicit binders:" <+> ppr fvs
- pure fvs
+ where
+ env = mkTyKiEnv ctx level RnTypeBody
rnImplicitBndrs :: Maybe assoc
-- ^ @'Just' _@ => an associated type decl
@@ -1053,6 +988,28 @@ an LHsQTyVars can be semantically significant. As a result, we suppress
-Wunused-foralls warnings in exactly one place: in bindHsQTyVars.
-}
+bindHsOuterTyVarBndrs :: OutputableBndrFlag flag
+ => HsDocContext
+ -> Maybe assoc
+ -- ^ @'Just' _@ => an associated type decl
+ -> FreeKiTyVars
+ -> HsOuterTyVarBndrs flag GhcPs
+ -> (HsOuterTyVarBndrs flag GhcRn -> RnM (a, FreeVars))
+ -> RnM (a, FreeVars)
+bindHsOuterTyVarBndrs doc mb_cls implicit_vars outer_bndrs thing_inside =
+ case outer_bndrs of
+ HsOuterImplicit{} ->
+ rnImplicitBndrs mb_cls implicit_vars $ \implicit_vars' ->
+ thing_inside $ HsOuterImplicit { hso_ximplicit = implicit_vars' }
+ HsOuterExplicit{hso_bndrs = exp_bndrs} ->
+ -- Note: If we pass mb_cls instead of Nothing below, 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.
+ bindLHsTyVarBndrs doc WarnUnusedForalls Nothing exp_bndrs $ \exp_bndrs' ->
+ thing_inside $ HsOuterExplicit { hso_xexplicit = noExtField
+ , hso_bndrs = exp_bndrs' }
+
bindHsForAllTelescope :: HsDocContext
-> HsForAllTelescope GhcPs
-> (HsForAllTelescope GhcRn -> RnM (a, FreeVars))
@@ -1859,6 +1816,10 @@ extract_lty (L _ ty) acc
-- We deal with these separately in rnLHsTypeWithWildCards
HsWildCardTy {} -> acc
+extract_lhs_sig_ty :: LHsSigType GhcPs -> FreeKiTyVars
+extract_lhs_sig_ty (L _ (HsSig{sig_bndrs = outer_bndrs, sig_body = body})) =
+ extractHsOuterTvBndrs outer_bndrs $ extract_lty body []
+
extract_hs_arrow :: HsArrow GhcPs -> FreeKiTyVars ->
FreeKiTyVars
extract_hs_arrow (HsExplicitMult _ p) acc = extract_lty p acc
@@ -1875,11 +1836,13 @@ extract_hs_for_all_telescope tele acc_vars body_fvs =
HsForAllInvis { hsf_invis_bndrs = bndrs } ->
extract_hs_tv_bndrs bndrs acc_vars body_fvs
-extractHsTvBndrs :: [LHsTyVarBndr flag GhcPs]
- -> FreeKiTyVars -- Free in body
- -> FreeKiTyVars -- Free in result
-extractHsTvBndrs tv_bndrs body_fvs
- = extract_hs_tv_bndrs tv_bndrs [] body_fvs
+extractHsOuterTvBndrs :: HsOuterTyVarBndrs flag GhcPs
+ -> FreeKiTyVars -- Free in body
+ -> FreeKiTyVars -- Free in result
+extractHsOuterTvBndrs outer_bndrs body_fvs =
+ case outer_bndrs of
+ HsOuterImplicit{} -> body_fvs
+ HsOuterExplicit{hso_bndrs = bndrs} -> extract_hs_tv_bndrs bndrs [] body_fvs
extract_hs_tv_bndrs :: [LHsTyVarBndr flag GhcPs]
-> FreeKiTyVars -- Accumulator