Commit a47e6442 authored by Ryan Scott's avatar Ryan Scott Committed by Marge Bot
Browse files

Always use rnImplicitBndrs to bring implicit tyvars into scope

This implements a first step towards #16762 by changing the renamer
to always use `rnImplicitBndrs` to bring implicitly bound type
variables into scope. The main change is in `rnFamInstEqn` and
`bindHsQTyVars`, which previously used _ad hoc_ methods of binding
their implicit tyvars.

There are a number of knock-on consequences:

* One of the reasons that `rnFamInstEqn` used an _ad hoc_ binding
  mechanism was to give more precise source locations in
  `-Wunused-type-patterns` warnings. (See
  ghc/ghc#16762 (comment 273343) for an
  example of this.) However, these warnings are actually a little
  _too_ precise, since implicitly bound type variables don't have
  exact binding sites like explicitly bound type variables do.
  A similar problem existed for
  "`Different names for the same type variable`" errors involving
  implicit tyvars bound by `bindHsQTyVars`.
  Therefore, we simply accept the less precise (but more accurate)
  source locations from `rnImplicitBndrs` in `rnFamInstEqn` and
  `bindHsQTyVars`. See
  `Note [Source locations for implicitly bound type variables]` in
  `GHC.Rename.HsType` for the full story.
* In order for `rnImplicitBndrs` to work in `rnFamInstEqn`, it needs
  to be able to look up names from the parent class (in the event
  that we are renaming an associated type family instance). As a
  result, `rnImplicitBndrs` now takes an argument of type
  `Maybe assoc`, which is `Just` in the event that a type family
  instance is associated with a class.
* Previously, GHC kept track of three type synonyms for free type
  variables in the renamer: `FreeKiTyVars`, `FreeKiTyVarsDups`
  (which are allowed to contain duplicates), and
  `FreeKiTyVarsNoDups` (which contain no duplicates). However, making
  is a distinction between `-Dups` and `-NoDups` is now pointless, as
  all code that returns `FreeKiTyVars{,Dups,NoDups}` will eventually
  end up being passed to `rnImplicitBndrs`, which removes duplicates.
  As a result, I decided to just get rid of `FreeKiTyVarsDups` and
  `FreeKiTyVarsNoDups`, leaving only `FreeKiTyVars`.
* The `bindLRdrNames` and `deleteBys` functions are now dead code, so
  I took the liberty of removing them.
parent 72c7fe9a
......@@ -10,7 +10,7 @@
--
-- Avoid using them as much as possible
module GHC.Data.List.SetOps (
unionLists, minusList, deleteBys,
unionLists, minusList,
-- Association lists
Assoc, assoc, assocMaybe, assocUsing, assocDefault, assocDefaultUsing,
......@@ -39,11 +39,6 @@ getNth :: Outputable a => [a] -> Int -> a
getNth xs n = ASSERT2( xs `lengthExceeds` n, ppr n $$ ppr xs )
xs !! n
deleteBys :: (a -> a -> Bool) -> [a] -> [a] -> [a]
-- (deleteBys eq xs ys) returns xs-ys, using the given equality function
-- Just like 'Data.List.delete' but with an equality function
deleteBys eq xs ys = foldl' (flip (L.deleteBy eq)) xs ys
{-
************************************************************************
* *
......
......@@ -30,7 +30,7 @@ module GHC.Hs.Type (
HsTyLit(..),
HsIPName(..), hsIPNameFS,
HsArg(..), numVisibleArgs,
LHsTypeArg,
LHsTypeArg, lhsTypeArgSrcSpan,
OutputableBndrFlag,
LBangType, BangType,
......@@ -1289,6 +1289,13 @@ numVisibleArgs = count is_vis
-- type level equivalent
type LHsTypeArg p = HsArg (LHsType p) (LHsKind p)
-- | Compute the 'SrcSpan' associated with an 'LHsTypeArg'.
lhsTypeArgSrcSpan :: LHsTypeArg pass -> SrcSpan
lhsTypeArgSrcSpan arg = case arg of
HsValArg tm -> getLoc tm
HsTypeArg at ty -> at `combineSrcSpans` getLoc ty
HsArgPar sp -> sp
instance (Outputable tm, Outputable ty) => Outputable (HsArg tm ty) where
ppr (HsValArg tm) = ppr tm
ppr (HsTypeArg _ ty) = char '@' <> ppr ty
......
This diff is collapsed.
......@@ -664,7 +664,7 @@ rnClsInstDecl (ClsInstDecl { cid_poly_ty = inst_ty, cid_binds = mbinds
rnFamInstEqn :: HsDocContext
-> AssocTyFamInfo
-> [Located RdrName]
-> FreeKiTyVars
-- ^ Kind variables from the equation's RHS to be implicitly bound
-- if no explicit forall.
-> FamInstEqn GhcPs rhs
......@@ -676,16 +676,7 @@ rnFamInstEqn doc atfi rhs_kvars
, 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
; let bndrs = fromMaybe [] mb_bndrs
= do { tycon' <- lookupFamInstName mb_cls tycon
-- all_imp_vars represent the implicitly bound type variables. This is
-- empty if we have an explicit `forall` (see
......@@ -713,48 +704,45 @@ rnFamInstEqn doc atfi rhs_kvars
-- No need to filter out explicit binders (the 'mb_bndrs = Just
-- explicit_bndrs' case) because there must be none if we're going
-- to implicitly bind anything, per the previous comment.
nubL $ pat_kity_vars_with_dups ++ rhs_kvars
; all_imp_var_names <- mapM (newTyVarNameRn mb_cls) all_imp_vars
-- All the free vars of the family patterns
-- with a sensible binding location
; ((bndrs', pats', payload'), fvs)
<- bindLocalNamesFV all_imp_var_names $
bindLHsTyVarBndrs doc WarnUnusedForalls
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'
pat_kity_vars_with_dups ++ rhs_kvars
; rnImplicitBndrs mb_cls all_imp_vars $ \all_imp_var_names' ->
bindLHsTyVarBndrs doc WarnUnusedForalls
Nothing (fromMaybe [] mb_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 -- The SrcSpan that rnImplicitBndrs will attach to each Name will
-- span the entire type family instance, which will be reflected in
-- -Wunused-type-patterns warnings. We can be a little more precise
-- than that by pointing to the LHS of the instance instead, which
-- is what lhs_loc corresponds to.
all_imp_var_names = map (`setNameLoc` lhs_loc) all_imp_var_names'
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
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
; return (HsIB { hsib_ext = all_imp_var_names -- Note [Wildcards in family instances]
......@@ -765,7 +753,36 @@ rnFamInstEqn doc atfi rhs_kvars
, feqn_pats = pats'
, feqn_fixity = fixity
, feqn_rhs = payload' } },
all_fvs) }
all_fvs) } }
where
-- The parent class, if we are dealing with an associated type family
-- instance.
mb_cls = case atfi of
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 -> []
AssocTyFamDeflt _ -> []
AssocTyFamInst _ inst_tvs -> inst_tvs
pat_kity_vars_with_dups = extractHsTyArgRdrKiTyVars pats
-- It is crucial that extractHsTyArgRdrKiTyVars return
-- duplicate occurrences, since they're needed to help
-- determine unused binders on the LHS.
-- The SrcSpan of the LHS of the instance. For example, lhs_loc would be
-- the highlighted part in the example below:
--
-- type instance F a b c = Either a b
-- ^^^^^
lhs_loc = case map lhsTypeArgSrcSpan pats ++ map getLoc rhs_kvars of
[] -> panic "rnFamInstEqn.lhs_loc"
[loc] -> loc
(loc:locs) -> loc `combineSrcSpans` last locs
rnTyFamInstDecl :: AssocTyFamInfo
-> TyFamInstDecl GhcPs
......@@ -2116,11 +2133,11 @@ rnConDecl decl@(ConDeclGADT { con_names = names
-- See #14808.
; implicit_bndrs <- forAllOrNothing explicit_forall
$ extractHsTvBndrs explicit_tkvs
$ extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty])
$ extractHsTysRdrTyVars (theta ++ arg_tys ++ [res_ty])
; let ctxt = ConDeclCtx new_names
; rnImplicitBndrs implicit_bndrs $ \ implicit_tkvs ->
; rnImplicitBndrs Nothing implicit_bndrs $ \ implicit_tkvs ->
bindLHsTyVarBndrs ctxt WarnUnusedForalls
Nothing explicit_tkvs $ \ explicit_tkvs ->
do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt
......
......@@ -1431,7 +1431,7 @@ reifyInstances th_nm th_tys
-- must error before proceeding to typecheck the
-- renamed type, as that will result in GHC
-- internal errors (#13837).
bindLRdrNames tv_rdrs $ \ tv_names ->
rnImplicitBndrs Nothing tv_rdrs $ \ tv_names ->
do { (rn_ty, fvs) <- rnLHsType doc rdr_ty
; return ((tv_names, rn_ty), fvs) }
; (_tvs, ty)
......
......@@ -5,7 +5,7 @@ ExplicitForAllFams2.hs:34:10: warning: [-Wunused-type-patterns]
ExplicitForAllFams2.hs:35:10: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘a’
ExplicitForAllFams2.hs:38:7: warning: [-Wunused-type-patterns]
ExplicitForAllFams2.hs:38:6: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘t’
ExplicitForAllFams2.hs:39:6: warning: [-Wunused-type-patterns]
......
T16356_Compile2.hs:10:12: warning: [-Wunused-type-patterns]
T16356_Compile2.hs:10:11: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘j’
T16356_Compile2.hs:10:17: warning: [-Wunused-type-patterns]
T16356_Compile2.hs:10:11: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘a’
T16356_Compile2.hs:13:15: warning: [-Wunused-type-patterns]
......
T16632.hs:5:22: warning: [-Wunused-type-patterns]
T16632.hs:5:17: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘b’
|
5 | type instance F Char b Int = ()
| ^
| ^^^^^^^^^^
UnusedTyVarWarnings.hs:8:7: warning: [-Wunused-type-patterns]
UnusedTyVarWarnings.hs:8:5: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘b’
UnusedTyVarWarnings.hs:11:20: warning: [-Wunused-type-patterns]
UnusedTyVarWarnings.hs:11:18: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘b’
UnusedTyVarWarnings.hs:27:5: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘a’
UnusedTyVarWarnings.hs:33:19: warning: [-Wunused-type-patterns]
UnusedTyVarWarnings.hs:33:17: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘b’
UnusedTyVarWarningsNamedWCs.hs:8:7: warning: [-Wunused-type-patterns]
UnusedTyVarWarningsNamedWCs.hs:8:5: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘b’
UnusedTyVarWarningsNamedWCs.hs:11:20: warning: [-Wunused-type-patterns]
UnusedTyVarWarningsNamedWCs.hs:11:18: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘b’
UnusedTyVarWarningsNamedWCs.hs:27:5: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘a’
UnusedTyVarWarningsNamedWCs.hs:33:19: warning: [-Wunused-type-patterns]
UnusedTyVarWarningsNamedWCs.hs:33:17: warning: [-Wunused-type-patterns]
Defined but not used on the right hand side: type variable ‘b’
T17008a.hs:11:21: error:
T17008a.hs:11:5: error:
• Type variable ‘a1’ is mentioned in the RHS,
but not bound on the LHS of the family instance
The real LHS (expanding synonyms) is: F @a2 x
......
T7536.hs:8:21: error:
T7536.hs:8:18: error:
• Type variable ‘a’ is mentioned in the RHS,
but not bound on the LHS of the family instance
The real LHS (expanding synonyms) is: TF Int
......
T11203.hs:7:24: error:
T11203.hs:7:9: error:
• Different names for the same type variable: ‘k1’ and ‘k2’
• In the data declaration for ‘Q’
T11821a.hs:4:31: error:
T11821a.hs:4:16: error:
• Different names for the same type variable: ‘k1’ and ‘k2’
• In the type declaration for ‘SameKind’
......@@ -3,7 +3,7 @@ T17841.hs:7:45: error:
• Expected a type, but ‘t’ has kind ‘k2’
‘k2’ is a rigid type variable bound by
the class declaration for ‘Foo’
at T17841.hs:7:17
at T17841.hs:7:12-17
• In the kind ‘t’
In the first argument of ‘Proxy’, namely ‘(a :: t)’
In the type signature: foo :: Proxy (a :: t)
......@@ -3,7 +3,7 @@ T7224.hs:6:19: error:
• Expected kind ‘i’, but ‘i’ has kind ‘*’
‘i’ is a rigid type variable bound by
the class declaration for ‘PMonad'’
at T7224.hs:5:21
at T7224.hs:5:16-36
• In the first argument of ‘m’, namely ‘i’
In the type signature: ret' :: a -> m i i a
In the class declaration for ‘PMonad'’
......@@ -12,7 +12,7 @@ T7224.hs:7:14: error:
• Expected kind ‘i’, but ‘i’ has kind ‘*’
‘i’ is a rigid type variable bound by
the class declaration for ‘PMonad'’
at T7224.hs:5:21
at T7224.hs:5:16-36
• In the first argument of ‘m’, namely ‘i’
In the type signature:
bind' :: m i j a -> (a -> m j k b) -> m i k b
......
......@@ -3,7 +3,7 @@ LevPolyBounded.hs:10:15: error:
• Expected a type, but ‘a’ has kind ‘TYPE r’
‘r’ is a rigid type variable bound by
the class declaration for ‘XBounded’
at LevPolyBounded.hs:9:27
at LevPolyBounded.hs:9:17-27
• In the type signature: LevPolyBounded.minBound :: a
In the class declaration for ‘XBounded’
......@@ -11,6 +11,6 @@ LevPolyBounded.hs:11:15: error:
• Expected a type, but ‘a’ has kind ‘TYPE r’
‘r’ is a rigid type variable bound by
the class declaration for ‘XBounded’
at LevPolyBounded.hs:9:27
at LevPolyBounded.hs:9:17-27
• In the type signature: LevPolyBounded.maxBound :: a
In the class declaration for ‘XBounded’
T17566b.hs:7:17: error:
T17566b.hs:7:12: error:
• Different names for the same type variable: ‘k1’ and ‘k2’
• In the class declaration for ‘C’
T17566c.hs:11:23: error:
T17566c.hs:11:12: error:
• Different names for the same type variable:
‘k’ bound at T17566c.hs:10:17
‘k’ bound at T17566c.hs:11:23
‘k’ bound at T17566c.hs:10:12
‘k’ bound at T17566c.hs:11:12
• In the class declaration for ‘C2’
......@@ -3,10 +3,10 @@ T9201.hs:6:17: error:
• Expected kind ‘x’, but ‘a’ has kind ‘y’
‘y’ is a rigid type variable bound by
the class declaration for ‘MonoidalCCC’
at T9201.hs:5:30
at T9201.hs:5:20-49
‘x’ is a rigid type variable bound by
the class declaration for ‘MonoidalCCC’
at T9201.hs:5:25
at T9201.hs:5:20-49
• In the first argument of ‘f’, namely ‘a’
In the second argument of ‘d’, namely ‘(f a)’
In the type signature: ret :: d a (f a)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment