summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2021-10-31 19:29:11 -0400
committerRyan Scott <ryan.gl.scott@gmail.com>2021-10-31 19:29:18 -0400
commit461fd5dbe1395078cac3e7f97fe80d56cbdd3b08 (patch)
treec26118db22f2d3367fe304a6366da2ad8f70cec2
parentea862ef5b3779476e0aa2d20bbae1946d07430f1 (diff)
downloadhaskell-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.hs32
-rw-r--r--testsuite/tests/th/T20590.hs8
-rw-r--r--testsuite/tests/th/T20590.stderr4
-rw-r--r--testsuite/tests/th/all.T1
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'])