Andrei Borzenkov pushed to branch wip/sand-witch/27423-gadt-parens at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • compiler/GHC/Hs/Decls.hs
    ... ... @@ -974,19 +974,21 @@ pprConDecl (ConDeclGADT { con_names = cons
    974 974
                             , con_mb_cxt = mcxt, con_g_args = args
    
    975 975
                             , con_res_ty = res_ty, con_modifiers = mods, con_doc = doc })
    
    976 976
       = pprMaybeWithDoc doc $ pprLHsModifiers mods <+> ppr_con_names (toList cons) <+> dcolon
    
    977
    -    <+> (ppr_outer_bndrs <+> ppr_inner_bndrs (
    
    977
    +    <+> sep [ppr_outer_bndrs, ppr_inner_bndrs (
    
    978 978
                     sep [ pprLHsContext mcxt,
    
    979
    -                      sep (ppr_args args ++ [ppr res_ty])]))
    
    979
    +                      sep (ppr_args args ++ [ppr res_ty])])]
    
    980 980
       where
    
    981 981
         ppr_args (PrefixConGADT _ args) = map (pprHsConDeclFieldWith (\arr tyDoc -> tyDoc <+> pprHsModifiedFunArr arr)) args
    
    982 982
         ppr_args (RecConGADT _ fields) = [pprHsConDeclRecFields (unLoc fields) <+> arrow]
    
    983 983
     
    
    984
    -    -- pprint all parenthisis and foralls, so parse == parse . ppr . parse
    
    984
    +    -- pprint all parentheses and foralls, so parse == parse . ppr . parse
    
    985 985
         ppr_inner_bndrs :: SDoc -> SDoc
    
    986 986
         ppr_inner_bndrs tyDoc = foldr ppr_inner_bndr (tyDoc <> close_parens) inner_bndrs
    
    987 987
     
    
    988 988
         ppr_inner_bndr (L _ HsGadtPar{})           rest = lparen <> rest
    
    989
    -    ppr_inner_bndr (L _ (HsGadtForAll _ tele)) rest = pprHsForAllTelescope tele <+> rest
    
    989
    +    ppr_inner_bndr (L _ (HsGadtForAll _ tele)) rest
    
    990
    +      | HsForAllInvis {hsf_invis_bndrs=[]} <- tele = empty_forall <+> rest
    
    991
    +      | otherwise = pprHsForAllTelescope tele <+> rest
    
    990 992
     
    
    991 993
         -- for each open paren generate a closed one
    
    992 994
         close_parens = hcat [ rparen | L _ HsGadtPar{} <- inner_bndrs ]
    
    ... ... @@ -997,10 +999,12 @@ pprConDecl (ConDeclGADT { con_names = cons
    997 999
         ppr_outer_bndrs
    
    998 1000
           | HsOuterExplicit{hso_bndrs = []} <- outer_bndrs
    
    999 1001
           , not (null inner_bndrs)
    
    1000
    -      = forAllLit <> dot
    
    1002
    +      = empty_forall
    
    1001 1003
           | otherwise
    
    1002 1004
           = pprHsOuterSigTyVarBndrs outer_bndrs
    
    1003 1005
     
    
    1006
    +    empty_forall = forAllLit <> dot
    
    1007
    +
    
    1004 1008
     ppr_con_names :: (OutputableBndr a) => [GenLocated l a] -> SDoc
    
    1005 1009
     ppr_con_names = pprWithCommas (pprPrefixOcc . unLoc)
    
    1006 1010
     
    

  • compiler/Language/Haskell/Syntax/Type.hs
    ... ... @@ -393,17 +393,15 @@ data HsForAllTelescope pass
    393 393
         }
    
    394 394
       | XHsForAllTelescope !(XXHsForAllTelescope pass)
    
    395 395
     
    
    396
    --- A type for interleaved GADT foralls and prefixes, inspired by HsArg
    
    397
    ---
    
    398
    --- `HsGadtPar` is only usefull for pretty-printing/exact-printing for recovering
    
    399
    --- parenthisis interleaved with foralls.
    
    396
    +-- | A type for interleaved GADT foralls and parentheses, inspired by HsArg.
    
    400 397
     --
    
    401 398
     -- Here's an example:
    
    402 399
     --
    
    403 400
     --  data D where
    
    404
    ---    MkD :: forall a b. ( forall c. forall d. ( forall. ...
    
    405
    ---           โ†‘           โ†‘ โ†‘         โ†‘         โ†‘ โ†‘
    
    406
    ---           1           2 3         4         5 6
    
    401
    +--    MkD :: forall x y. -- these go to the `con_outer_bndrs` field
    
    402
    +--             forall a b. ( forall c. forall d. ( forall. ...
    
    403
    +--             โ†‘           โ†‘ โ†‘         โ†‘         โ†‘ โ†‘
    
    404
    +--             1           2 3         4         5 6
    
    407 405
     --
    
    408 406
     -- That would correspond to a list
    
    409 407
     --
    
    ... ... @@ -414,12 +412,15 @@ data HsForAllTelescope pass
    414 412
     --   5 โ†’ , HsGadtPar
    
    415 413
     --   6 โ†’ , HsGadtForAll
    
    416 414
     --       , ...]
    
    417
    ---
    
    418
    --- We can always recover parenthisis structure because they must close after
    
    419
    --- return type.
    
    420 415
     data HsGadtArg pass
    
    421 416
       = HsGadtForAll !(XGadtForAll pass) (HsForAllTelescope pass)
    
    422 417
       | HsGadtPar !(XGadtPar pass)
    
    418
    +    -- ^ `HsGadtPar` is only usefull for pretty-printing/exact-printing for recovering
    
    419
    +    -- parenthisis interleaved with foralls.
    
    420
    +    --
    
    421
    +    -- This approach differs from `HsPar`, which wraps the inner expression as if
    
    422
    +    -- surrounding it with parentheses. We can ditch the `HsPar` approach because
    
    423
    +    -- we know that all parentheses will be closed after the return type.
    
    423 424
       | XHsGadtArg !(XXGadtArg pass)
    
    424 425
     
    
    425 426
     type LHsGadtArg pass = XRec pass (HsGadtArg pass)
    

  • docs/users_guide/exts/gadt_syntax.rst
    ... ... @@ -201,12 +201,12 @@ syntactically allowed. Some further various observations about this grammar:
    201 201
       something like ``MkS :: Int -> (forall a. a) -> S`` is allowed, since
    
    202 202
       parentheses separate the ``forall`` from the ``->``.)
    
    203 203
     
    
    204
    -- Furthermore, GADT constructors do not permit outermost parentheses that
    
    205
    -  surround the ``foralls`` or ``opt_ctxt``, if at least one of them are
    
    206
    -  used. For example, ``MkU :: (forall a. a -> U)`` would be rejected, since
    
    207
    -  it would treat the ``forall`` as being nested.
    
    204
    +- GADT constructors permit outermost parentheses that surround the ``foralls``
    
    205
    +  or ``opt_ctxt``, as well as interleaved parentheses between multiple
    
    206
    +  ``foralls``. For example, ``MkU :: (forall a. a -> U)`` is accepted, as is
    
    207
    +  ``MkW :: forall a. (forall b. a -> b -> W)``.
    
    208 208
     
    
    209
    -  Note that it is acceptable to use parentheses in a ``prefix_gadt_body``.
    
    209
    +  Note that it is also acceptable to use parentheses in a ``prefix_gadt_body``.
    
    210 210
       For instance, ``MkV1 :: forall a. (a) -> (V1)`` is acceptable, as is
    
    211 211
       ``MkV2 :: forall a. (a -> V2)``.
    
    212 212
     
    

  • testsuite/tests/printer/T27423c.hs
    ... ... @@ -18,6 +18,7 @@ data S a where
    18 18
       MkS :: (forall a. S a)
    
    19 19
       MkS2 :: forall. (forall a. S a)
    
    20 20
       MkS3 :: forall. forall a. S a
    
    21
    +  MkS4 :: forall a. forall. forall b. forall. forall. forall c. S a
    
    21 22
     
    
    22 23
     data U a where
    
    23 24
       MkU :: (Show a => U a)