From 2517d98ba1141ce9e1046e6942bb63de249ee164 Mon Sep 17 00:00:00 2001 From: mrkkrp Date: Sat, 2 Nov 2019 14:57:56 +0100 Subject: [PATCH] =?UTF-8?q?Preserve=20empty=20=E2=80=98forall=E2=80=99s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 +++ data/examples/other/empty-forall-out.hs | 18 ++++++++++++++++++ data/examples/other/empty-forall.hs | 17 +++++++++++++++++ src/Ormolu/Printer/Meat/Declaration/Data.hs | 11 +++++++---- src/Ormolu/Printer/Meat/Declaration/Rule.hs | 15 +++++++++++---- src/Ormolu/Printer/Meat/Type.hs | 2 +- 6 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 data/examples/other/empty-forall-out.hs create mode 100644 data/examples/other/empty-forall.hs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f2c566..6d95531 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,9 @@ inside the export list. See [issue 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 * Initial release. diff --git a/data/examples/other/empty-forall-out.hs b/data/examples/other/empty-forall-out.hs new file mode 100644 index 0000000..d41d5f4 --- /dev/null +++ b/data/examples/other/empty-forall-out.hs @@ -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 = + () + #-} diff --git a/data/examples/other/empty-forall.hs b/data/examples/other/empty-forall.hs new file mode 100644 index 0000000..1319a66 --- /dev/null +++ b/data/examples/other/empty-forall.hs @@ -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 = () +#-} diff --git a/src/Ormolu/Printer/Meat/Declaration/Data.hs b/src/Ormolu/Printer/Meat/Declaration/Data.hs index 91a8e07..049d1df 100644 --- a/src/Ormolu/Printer/Meat/Declaration/Data.hs +++ b/src/Ormolu/Printer/Meat/Declaration/Data.hs @@ -104,8 +104,9 @@ p_conDecl = \case then newline else breakpoint interArgBreak - p_forallBndrs p_hsTyVarBndr (hsq_explicit con_qvars) - unless (null $ hsq_explicit con_qvars) interArgBreak + when (unLoc con_forall) $ do + p_forallBndrs p_hsTyVarBndr (hsq_explicit con_qvars) + interArgBreak forM_ con_mb_cxt p_lhsContext case con_args of PrefixCon xs -> do @@ -126,12 +127,14 @@ p_conDecl = \case mapM_ (p_hsDocString Pipe True) con_doc let conDeclSpn = [getLoc con_name] + <> [getLoc con_forall] <> fmap getLoc con_ex_tvs <> maybeToList (fmap getLoc con_mb_cxt) <> conArgsSpans con_args switchLayout conDeclSpn $ do - p_forallBndrs p_hsTyVarBndr con_ex_tvs - unless (null con_ex_tvs) breakpoint + when (unLoc con_forall) $ do + p_forallBndrs p_hsTyVarBndr con_ex_tvs + breakpoint forM_ con_mb_cxt p_lhsContext case con_args of PrefixCon xs -> do diff --git a/src/Ormolu/Printer/Meat/Declaration/Rule.hs b/src/Ormolu/Printer/Meat/Declaration/Rule.hs index b3a7a5a..61cbb69 100644 --- a/src/Ormolu/Printer/Meat/Declaration/Rule.hs +++ b/src/Ormolu/Printer/Meat/Declaration/Rule.hs @@ -8,7 +8,7 @@ module Ormolu.Printer.Meat.Declaration.Rule where import BasicTypes -import Data.Maybe (fromMaybe) +import Control.Monad (unless) import GHC import Ormolu.Printer.Combinators import Ormolu.Printer.Meat.Common @@ -31,9 +31,16 @@ p_ruleDecl = \case space p_activation activation space - p_forallBndrs p_hsTyVarBndr (fromMaybe [] tyvars) - space - p_forallBndrs p_ruleBndr ruleBndrs + case tyvars of + Nothing -> return () + 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 inci $ do located lhs p_hsExpr diff --git a/src/Ormolu/Printer/Meat/Type.hs b/src/Ormolu/Printer/Meat/Type.hs index 1be9b5b..152b00f 100644 --- a/src/Ormolu/Printer/Meat/Type.hs +++ b/src/Ormolu/Printer/Meat/Type.hs @@ -184,7 +184,7 @@ p_hsTyVarBndr = \case -- | Render several @forall@-ed variables. p_forallBndrs :: Data a => (a -> R ()) -> [Located a] -> R () -p_forallBndrs _ [] = return () +p_forallBndrs _ [] = txt "forall." p_forallBndrs p tyvars = switchLayout (getLoc <$> tyvars) $ do txt "forall"