diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2021-10-31 19:29:11 -0400 |
---|---|---|
committer | Ryan Scott <ryan.gl.scott@gmail.com> | 2021-10-31 19:29:18 -0400 |
commit | 461fd5dbe1395078cac3e7f97fe80d56cbdd3b08 (patch) | |
tree | c26118db22f2d3367fe304a6366da2ad8f70cec2 | |
parent | ea862ef5b3779476e0aa2d20bbae1946d07430f1 (diff) | |
download | haskell-461fd5dbe1395078cac3e7f97fe80d56cbdd3b08.tar.gz |
Fix #20590 with another application of mkHsContextMaybewip/T20590
We were always converting empty GADT contexts to `Just []` in `GHC.ThToHs`,
which caused the pretty-printer to always print them as `() => ...`. This is
easily fixed by using the `mkHsContextMaybe` function when converting GADT
contexts so that empty contexts are turned to `Nothing`. This is in the same
tradition established in commit 4c87a3d1d14f9e28c8aa0f6062e9c4201f469ad7.
In the process of fixing this, I discovered that the `Cxt` argument to
`mkHsContextMaybe` is completely unnecessary, as we can just as well check if
the `LHsContext GhcPs` argument is empty.
Fixes #20590.
-rw-r--r-- | compiler/GHC/ThToHs.hs | 32 | ||||
-rw-r--r-- | testsuite/tests/th/T20590.hs | 8 | ||||
-rw-r--r-- | testsuite/tests/th/T20590.stderr | 4 | ||||
-rw-r--r-- | testsuite/tests/th/all.T | 1 |
4 files changed, 28 insertions, 17 deletions
diff --git a/compiler/GHC/ThToHs.hs b/compiler/GHC/ThToHs.hs index eb92fe1240..6a7c5ab4ec 100644 --- a/compiler/GHC/ThToHs.hs +++ b/compiler/GHC/ThToHs.hs @@ -259,7 +259,7 @@ cvtDec (DataD ctxt tc tvs ksig constrs derivs) ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField , dd_ND = DataType, dd_cType = Nothing - , dd_ctxt = mkHsContextMaybe ctxt ctxt' + , dd_ctxt = mkHsContextMaybe ctxt' , dd_kindSig = ksig' , dd_cons = cons', dd_derivs = derivs' } ; returnJustLA $ TyClD noExtField $ @@ -275,7 +275,7 @@ cvtDec (NewtypeD ctxt tc tvs ksig constr derivs) ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField , dd_ND = NewType, dd_cType = Nothing - , dd_ctxt = mkHsContextMaybe ctxt ctxt' + , dd_ctxt = mkHsContextMaybe ctxt' , dd_kindSig = ksig' , dd_cons = [con'] , dd_derivs = derivs' } @@ -295,7 +295,7 @@ cvtDec (ClassD ctxt cl tvs fds decs) $$ (Outputable.ppr adts')) ; returnJustLA $ TyClD noExtField $ ClassDecl { tcdCExt = (noAnn, NoAnnSortKey, NoLayoutInfo) - , tcdCtxt = mkHsContextMaybe ctxt cxt', tcdLName = tc', tcdTyVars = tvs' + , tcdCtxt = mkHsContextMaybe cxt', tcdLName = tc', tcdTyVars = tvs' , tcdFixity = Prefix , tcdFDs = fds', tcdSigs = Hs.mkClassOpSigs sigs' , tcdMeths = binds' @@ -346,7 +346,7 @@ cvtDec (DataInstD ctxt bndrs tys ksig constrs derivs) ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField , dd_ND = DataType, dd_cType = Nothing - , dd_ctxt = mkHsContextMaybe ctxt ctxt' + , dd_ctxt = mkHsContextMaybe ctxt' , dd_kindSig = ksig' , dd_cons = cons', dd_derivs = derivs' } @@ -367,7 +367,7 @@ cvtDec (NewtypeInstD ctxt bndrs tys ksig constr derivs) ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField , dd_ND = NewType, dd_cType = Nothing - , dd_ctxt = mkHsContextMaybe ctxt ctxt' + , dd_ctxt = mkHsContextMaybe ctxt' , dd_kindSig = ksig' , dd_cons = [con'], dd_derivs = derivs' } ; returnJustLA $ InstD noExtField $ DataFamInstD @@ -622,7 +622,7 @@ cvtConstr (ForallC tvs ctxt con) ; L _ con' <- cvtConstr con ; returnLA $ add_forall tvs' ctxt' con' } where - add_cxt lcxt Nothing = Just lcxt + add_cxt lcxt Nothing = mkHsContextMaybe lcxt add_cxt (L loc cxt1) (Just (L _ cxt2)) = Just (L loc (cxt1 ++ cxt2)) @@ -1924,21 +1924,19 @@ mkHsQualTy ctxt loc ctxt' ty , hst_ctxt = ctxt' , hst_body = ty } --- | If passed an empty 'TH.Cxt', this returns 'Nothing'. Otherwise, this --- returns @'Just' lc@, where @lc@ is the provided @'LHsContext' 'GhcPs'@ --- argument. +-- | @'mkHsContextMaybe' lc@ returns 'Nothing' if @lc@ is empty and @'Just' lc@ +-- otherwise. -- -- This is much like 'mkHsQualTy', except that it returns a -- @'Maybe' ('LHsContext' 'GhcPs')@. This is used specifically for constructing --- superclasses and datatype contexts. We wish to avoid using 'Just' in the --- case of an empty 'TH.Cxt', as the pretty-printer for superclasses/datatype --- contexts always prints 'Just' contexts, even if they're empty. See #20011. -mkHsContextMaybe :: TH.Cxt - -> LHsContext GhcPs - -> Maybe (LHsContext GhcPs) -mkHsContextMaybe ctxt ctxt' +-- superclasses, datatype contexts (#20011), and contexts in GADT constructor +-- types (#20590). We wish to avoid using @'Just' []@ in the case of an empty +-- contexts, as the pretty-printer always prints 'Just' contexts, even if +-- they're empty. +mkHsContextMaybe :: LHsContext GhcPs -> Maybe (LHsContext GhcPs) +mkHsContextMaybe lctxt@(L _ ctxt) | null ctxt = Nothing - | otherwise = Just ctxt' + | otherwise = Just lctxt mkHsOuterFamEqnTyVarBndrs :: Maybe [LHsTyVarBndr () GhcPs] -> HsOuterFamEqnTyVarBndrs GhcPs mkHsOuterFamEqnTyVarBndrs = maybe mkHsOuterImplicit (mkHsOuterExplicit noAnn) diff --git a/testsuite/tests/th/T20590.hs b/testsuite/tests/th/T20590.hs new file mode 100644 index 0000000000..68ee97267a --- /dev/null +++ b/testsuite/tests/th/T20590.hs @@ -0,0 +1,8 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TemplateHaskell #-} +module T20590 where + +$([d| data T where + MkT :: forall a. a -> T + |]) diff --git a/testsuite/tests/th/T20590.stderr b/testsuite/tests/th/T20590.stderr new file mode 100644 index 0000000000..9d06f592a5 --- /dev/null +++ b/testsuite/tests/th/T20590.stderr @@ -0,0 +1,4 @@ +T20590.hs:(6,2)-(8,7): Splicing declarations + [d| data T where MkT :: forall a. a -> T |] + ======> + data T where MkT :: forall a. a -> T diff --git a/testsuite/tests/th/all.T b/testsuite/tests/th/all.T index a5c4610598..439e88cd9a 100644 --- a/testsuite/tests/th/all.T +++ b/testsuite/tests/th/all.T @@ -537,3 +537,4 @@ test('T17820b', normal, compile_fail, ['']) test('T17820c', normal, compile_fail, ['']) test('T17820d', normal, compile_fail, ['']) test('T17820e', normal, compile_fail, ['']) +test('T20590', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) |