Preserve empty ‘forall’s

This commit is contained in:
mrkkrp 2019-11-02 14:57:56 +01:00 committed by Mark Karpov
parent fa96da7d67
commit 2517d98ba1
6 changed files with 57 additions and 9 deletions

View File

@ -18,6 +18,9 @@
inside the export list. See [issue inside the export list. See [issue
430](https://github.com/tweag/ormolu/issues/430). 430](https://github.com/tweag/ormolu/issues/430).
* Empty `forall`s are now correctly preserved. See [issue
429](https://github.com/tweag/ormolu/issues/429).
## Ormolu 0.0.1.0 ## Ormolu 0.0.1.0
* Initial release. * Initial release.

View File

@ -0,0 +1,18 @@
-- Empty foralls are handled correctly in different situations.
data D = forall. D Int
data G where
G :: forall. Int -> G
f :: forall. a -> a
f x = x
type family T x where
forall. T x = x
{-# RULES
"r"
r a =
()
#-}

View File

@ -0,0 +1,17 @@
-- Empty foralls are handled correctly in different situations.
data D = forall. D Int
data G where
G :: forall. Int -> G
f :: forall. a -> a
f x = x
type family T x where
forall. T x = x
{-# RULES
"r"
forall. r a = ()
#-}

View File

@ -104,8 +104,9 @@ p_conDecl = \case
then newline then newline
else breakpoint else breakpoint
interArgBreak interArgBreak
p_forallBndrs p_hsTyVarBndr (hsq_explicit con_qvars) when (unLoc con_forall) $ do
unless (null $ hsq_explicit con_qvars) interArgBreak p_forallBndrs p_hsTyVarBndr (hsq_explicit con_qvars)
interArgBreak
forM_ con_mb_cxt p_lhsContext forM_ con_mb_cxt p_lhsContext
case con_args of case con_args of
PrefixCon xs -> do PrefixCon xs -> do
@ -126,12 +127,14 @@ p_conDecl = \case
mapM_ (p_hsDocString Pipe True) con_doc mapM_ (p_hsDocString Pipe True) con_doc
let conDeclSpn = let conDeclSpn =
[getLoc con_name] [getLoc con_name]
<> [getLoc con_forall]
<> fmap getLoc con_ex_tvs <> fmap getLoc con_ex_tvs
<> maybeToList (fmap getLoc con_mb_cxt) <> maybeToList (fmap getLoc con_mb_cxt)
<> conArgsSpans con_args <> conArgsSpans con_args
switchLayout conDeclSpn $ do switchLayout conDeclSpn $ do
p_forallBndrs p_hsTyVarBndr con_ex_tvs when (unLoc con_forall) $ do
unless (null con_ex_tvs) breakpoint p_forallBndrs p_hsTyVarBndr con_ex_tvs
breakpoint
forM_ con_mb_cxt p_lhsContext forM_ con_mb_cxt p_lhsContext
case con_args of case con_args of
PrefixCon xs -> do PrefixCon xs -> do

View File

@ -8,7 +8,7 @@ module Ormolu.Printer.Meat.Declaration.Rule
where where
import BasicTypes import BasicTypes
import Data.Maybe (fromMaybe) import Control.Monad (unless)
import GHC import GHC
import Ormolu.Printer.Combinators import Ormolu.Printer.Combinators
import Ormolu.Printer.Meat.Common import Ormolu.Printer.Meat.Common
@ -31,9 +31,16 @@ p_ruleDecl = \case
space space
p_activation activation p_activation activation
space space
p_forallBndrs p_hsTyVarBndr (fromMaybe [] tyvars) case tyvars of
space Nothing -> return ()
p_forallBndrs p_ruleBndr ruleBndrs Just xs -> do
p_forallBndrs p_hsTyVarBndr xs
space
-- NOTE It appears that there is no way to tell if there was an empty
-- forall in the input or no forall at all. We do not want to add
-- redundant foralls, so let's just skip the empty ones.
unless (null ruleBndrs) $
p_forallBndrs p_ruleBndr ruleBndrs
breakpoint breakpoint
inci $ do inci $ do
located lhs p_hsExpr located lhs p_hsExpr

View File

@ -184,7 +184,7 @@ p_hsTyVarBndr = \case
-- | Render several @forall@-ed variables. -- | Render several @forall@-ed variables.
p_forallBndrs :: Data a => (a -> R ()) -> [Located a] -> R () p_forallBndrs :: Data a => (a -> R ()) -> [Located a] -> R ()
p_forallBndrs _ [] = return () p_forallBndrs _ [] = txt "forall."
p_forallBndrs p tyvars = p_forallBndrs p tyvars =
switchLayout (getLoc <$> tyvars) $ do switchLayout (getLoc <$> tyvars) $ do
txt "forall" txt "forall"