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

Commits:

13 changed files:

Changes:

  • changelog.d/allow-gadt-prefx-con-parens
    1
    +section: language
    
    2
    +synopsis: Allow parentheses in prefix GADT constructor declarations, as specified
    
    3
    +  by GHC Proposal #402 "Stable GADT constructor syntax".
    
    4
    +issues: #27423
    
    5
    +mrs: !16321
    
    6
    +
    
    7
    +description: {
    
    8
    +  Parenthesized types are now accepted in prefix GADT constructor declarations,
    
    9
    +  even when they contain explicit ``forall`` quantifiers. For example:
    
    10
    +
    
    11
    +    data T where
    
    12
    +      MkT :: (forall a. a -> b -> T)
    
    13
    +
    
    14
    +  This is equivalent to ``MkT :: forall {b}. (forall a. a -> b -> T)``, so the
    
    15
    +  forall-or-nothing rule continues to be respected.
    
    16
    +}

  • compiler/GHC/Hs/Decls.hs
    ... ... @@ -910,13 +910,28 @@ pprConDecl (ConDeclGADT { con_names = cons
    910 910
                             , con_res_ty = res_ty, con_modifiers = mods, con_doc = doc })
    
    911 911
       = pprMaybeWithDoc doc $ pprLHsModifiers mods <+> ppr_con_names (toList cons) <+> dcolon
    
    912 912
         <+> (sep [pprHsOuterSigTyVarBndrs outer_bndrs
    
    913
    +                <+> inner_bndrs_lguard
    
    913 914
                     <+> hsep (map pprHsForAllTelescope inner_bndrs)
    
    914 915
                     <+> pprLHsContext mcxt,
    
    915
    -              sep (ppr_args args ++ [ppr res_ty]) ])
    
    916
    +              sep (ppr_args args ++ [ppr res_ty]),
    
    917
    +              inner_bndrs_rguard ])
    
    916 918
       where
    
    917 919
         ppr_args (PrefixConGADT _ args) = map (pprHsConDeclFieldWith (\arr tyDoc -> tyDoc <+> pprHsModifiedFunArr arr)) args
    
    918 920
         ppr_args (RecConGADT _ fields) = [pprHsConDeclRecFields (unLoc fields) <+> arrow]
    
    919 921
     
    
    922
    +    -- We may have inner binders without outer ones, for example:
    
    923
    +    --   data D a where MkD :: forall. forall a. D a
    
    924
    +    -- and
    
    925
    +    --   data D a where MkD :: (forall a. D a)
    
    926
    +    -- These cases have different outer_bndrs: explicit or implicit.
    
    927
    +    -- We want to add an empty `forall.` or wrap type into parentheses
    
    928
    +    -- to highlight the fact that binds in the question are indeed inner.
    
    929
    +    (inner_bndrs_lguard, inner_bndrs_rguard)
    
    930
    +      | null inner_bndrs = (empty, empty)
    
    931
    +      | HsOuterImplicit{} <- outer_bndrs = (lparen, rparen)
    
    932
    +      | HsOuterExplicit{hso_bndrs=[]} <- outer_bndrs = (text "forall" <+> text ".", empty)
    
    933
    +      | otherwise = (empty, empty)
    
    934
    +
    
    920 935
     ppr_con_names :: (OutputableBndr a) => [GenLocated l a] -> SDoc
    
    921 936
     ppr_con_names = pprWithCommas (pprPrefixOcc . unLoc)
    
    922 937
     
    

  • compiler/GHC/Hs/Type.hs
    ... ... @@ -898,12 +898,11 @@ splitLHsGadtTy (L _ sig_ty)
    898 898
       | (outer_bndrs, sigma_ty) <- split_outer_bndrs sig_ty
    
    899 899
       , (inner_bndrs, phi_ty)   <- split_inner_bndrs sigma_ty
    
    900 900
       , (mb_ctxt, rho_ty)       <- splitLHsQualTy_KP phi_ty
    
    901
    -  = case rho_ty of
    
    902
    -      L _ (HsFunTy _ _ (L _ (XHsType HsRecTy{})) _) | not (null inner_bndrs)
    
    901
    +  = if is_gadt_rec_ty rho_ty && not (null inner_bndrs)
    
    903 902
             -- Bad! Record GADTs are not allowed to have inner_bndrs,
    
    904 903
             -- undo the split to get a proper error message later
    
    905
    -        -> (outer_bndrs, [], Nothing, sigma_ty)
    
    906
    -      _ -> (outer_bndrs, inner_bndrs, mb_ctxt, rho_ty)
    
    904
    +      then (outer_bndrs, [], Nothing, sigma_ty)
    
    905
    +      else (outer_bndrs, inner_bndrs, mb_ctxt, rho_ty)
    
    907 906
       where
    
    908 907
         split_outer_bndrs :: HsSigType GhcPs -> (HsOuterSigTyVarBndrs GhcPs, LHsType GhcPs)
    
    909 908
         split_outer_bndrs (HsSig{sig_bndrs = outer_bndrs, sig_body = body_ty}) =
    
    ... ... @@ -914,8 +913,17 @@ splitLHsGadtTy (L _ sig_ty)
    914 913
                                           , hst_body = body })
    
    915 914
           = let ~(teles, t) = split_inner_bndrs body
    
    916 915
             in (tele:teles, t)
    
    916
    +    split_inner_bndrs t@(L _ (HsParTy _ ty))
    
    917
    +      | not (is_gadt_rec_ty ty)
    
    918
    +      = split_inner_bndrs ty
    
    919
    +      | otherwise
    
    920
    +      = ([], t)
    
    917 921
         split_inner_bndrs t = ([], t)
    
    918 922
     
    
    923
    +    -- type of form {fld :: ty, ...} -> ResTy
    
    924
    +    is_gadt_rec_ty (L _ (HsFunTy _ _ (L _ (XHsType HsRecTy{})) _)) = True
    
    925
    +    is_gadt_rec_ty _ = False
    
    926
    +
    
    919 927
     -- | Decompose a type of the form @forall <tvs>. body@ into its constituent
    
    920 928
     -- parts. Only splits type variable binders that
    
    921 929
     -- were quantified invisibly (e.g., @forall a.@, with a dot).
    

  • testsuite/tests/gadt/T14320.stderr deleted
    1
    -
    
    2
    -T14320.hs:17:14: error: [GHC-71492]
    
    3
    -    GADT constructor type signature cannot contain nested ‘forall’s or contexts
    
    4
    -    In the definition of data constructor ‘TEBad’

  • testsuite/tests/gadt/T18191.hs
    ... ... @@ -2,15 +2,6 @@
    2 2
     {-# LANGUAGE RankNTypes #-}
    
    3 3
     module T18191 where
    
    4 4
     
    
    5
    -data T where
    
    6
    -  MkT :: (forall a. a -> b -> T)
    
    7
    -
    
    8
    -data S a where
    
    9
    -  MkS :: (forall a. S a)
    
    10
    -
    
    11
    -data U a where
    
    12
    -  MkU :: (Show a => U a)
    
    13
    -
    
    14 5
     data Z a where
    
    15 6
       MkZ1 :: forall a. forall b. { unZ1 :: (a, b) } -> Z (a, b)
    
    16 7
       MkZ2 :: Eq a => Eq b => { unZ1 :: (a, b) } -> Z (a, b)

  • testsuite/tests/gadt/T18191.stderr
    1
    -
    
    2
    -T18191.hs:6:11: error: [GHC-71492]
    
    3
    -    • GADT constructor type signature cannot contain nested ‘forall’s or contexts
    
    4
    -    • In the definition of data constructor ‘MkT’
    
    5
    -
    
    6
    -T18191.hs:9:11: error: [GHC-71492]
    
    7
    -    • GADT constructor type signature cannot contain nested ‘forall’s or contexts
    
    8
    -    • In the definition of data constructor ‘MkS’
    
    9
    -
    
    10
    -T18191.hs:12:11: error: [GHC-71492]
    
    11
    -    • GADT constructor type signature cannot contain nested ‘forall’s or contexts
    
    12
    -    • In the definition of data constructor ‘MkU’
    
    13
    -
    
    14
    -T18191.hs:15:21: error: [GHC-71492]
    
    1
    +T18191.hs:6:21: error: [GHC-71492]
    
    15 2
         • GADT constructor type signature cannot contain nested ‘forall’s or contexts
    
    16 3
         • In the definition of data constructor ‘MkZ1’
    
    17 4
     
    
    18
    -T18191.hs:15:31: error: [GHC-89246]
    
    5
    +T18191.hs:6:31: error: [GHC-89246]
    
    19 6
         • Record syntax is illegal here: {unZ1 :: (a, b)}
    
    20 7
         • In the definition of data constructor ‘MkZ1’
    
    21 8
     
    
    22
    -T18191.hs:16:19: error: [GHC-71492]
    
    9
    +T18191.hs:7:19: error: [GHC-71492]
    
    23 10
         • GADT constructor type signature cannot contain nested ‘forall’s or contexts
    
    24 11
         • In the definition of data constructor ‘MkZ2’
    
    25 12
     
    
    26
    -T18191.hs:16:27: error: [GHC-89246]
    
    13
    +T18191.hs:7:27: error: [GHC-89246]
    
    27 14
         • Record syntax is illegal here: {unZ1 :: (a, b)}
    
    28 15
         • In the definition of data constructor ‘MkZ2’
    
    16
    +

  • testsuite/tests/gadt/T27423a.hs
    1
    +{-# LANGUAGE GADTs #-}
    
    2
    +module T27423a where
    
    3
    +
    
    4
    +data G a where
    
    5
    +  MkG1 :: a -> G a
    
    6
    +  MkG2 :: (a -> G a)
    
    7
    +  MkG3 :: forall a. a -> G a
    
    8
    +  MkG4 :: forall a. (a -> G a)
    
    9
    +
    
    10
    +-- this is equivalent to `forall {b}. (forall a. a -> b -> T)`.
    
    11
    +data T where
    
    12
    +  MkT2 :: (forall a. a -> b -> T)
    
    13
    +
    
    14
    +-- this is equivalent to `forall. (forall a. S a)`.
    
    15
    +data S a where
    
    16
    +  MkS :: (forall a. S a)
    
    17
    +
    
    18
    +-- A forall and a context combined inside the same parentheses, with no
    
    19
    +-- outer forall at all.
    
    20
    +data Y a where
    
    21
    +  MkY :: (forall a. Show a => a -> Y a)
    
    22
    +
    
    23
    +-- Multiple, redundant nested parentheses around the whole type should
    
    24
    +-- be accepted.
    
    25
    +data H a where
    
    26
    +  MkH :: ((a -> H a))
    
    27
    +
    
    28
    +-- An unparenthesised outer forall together with an independent,
    
    29
    +-- parenthesised inner forall.
    
    30
    +data I a where
    
    31
    +  MkI :: forall a. (forall b. I (b, a))

  • testsuite/tests/gadt/T27423b.hs
    1
    +{-# LANGUAGE GADTs #-}
    
    2
    +module T27423b where
    
    3
    +
    
    4
    +-- Record-style GADT constructors must remain unparenthesisable, per
    
    5
    +-- GHC Proposal #402: this is out of scope for #27423 and should
    
    6
    +-- continue to be rejected.
    
    7
    +data T1 a where
    
    8
    +  MkT1 :: ({ fld :: a } -> T1 a)
    
    9
    +
    
    10
    +data T2 a where
    
    11
    +  MkT2 :: (forall a. { fld :: a } -> T2 a)
    
    12
    +
    
    13
    +-- Without parentheses, forall-or-nothing applies to the whole type, so
    
    14
    +-- `b` is not implicitly quantified and this must be rejected.
    
    15
    +data T3 where
    
    16
    +  MkT3 :: forall a. a -> b -> T3

  • testsuite/tests/gadt/T27423b.stderr
    1
    +T27423b.hs:8:12: error: [GHC-89246]
    
    2
    +    • Record syntax is illegal here: {fld :: a}
    
    3
    +    • In the definition of data constructor ‘MkT1’
    
    4
    +
    
    5
    +T27423b.hs:11:12: error: [GHC-71492]
    
    6
    +    • GADT constructor type signature cannot contain nested ‘forall’s or contexts
    
    7
    +    • In the definition of data constructor ‘MkT2’
    
    8
    +
    
    9
    +T27423b.hs:11:22: error: [GHC-89246]
    
    10
    +    • Record syntax is illegal here: {fld :: a}
    
    11
    +    • In the definition of data constructor ‘MkT2’
    
    12
    +
    
    13
    +T27423b.hs:16:26: error: [GHC-76037]
    
    14
    +    Not in scope: type variable ‘b’
    
    15
    +

  • testsuite/tests/gadt/all.T
    ... ... @@ -114,7 +114,7 @@ test('T7558', normal, compile, [''])
    114 114
     test('T9380', normal, compile_and_run, [''])
    
    115 115
     test('T12087', normal, compile_fail, [''])
    
    116 116
     test('T12468', normal, compile_fail, [''])
    
    117
    -test('T14320', normal, compile_fail, [''])
    
    117
    +test('T14320', normal, compile, [''])
    
    118 118
     test('T14719', normal, compile_fail, ['-fdiagnostics-show-caret'])
    
    119 119
     test('T14808', normal, compile, [''])
    
    120 120
     test('T15009', normal, compile, [''])
    
    ... ... @@ -132,3 +132,6 @@ test('T19847b', normal, compile, [''])
    132 132
     test('T23022', normal, compile, ['-dcore-lint'])
    
    133 133
     test('T23023', normal, compile_fail, ['-O -dcore-lint']) # todo: move this test?
    
    134 134
     test('T23298', normal, compile_fail, [''])
    
    135
    +
    
    136
    +test('T27423a', normal, compile, [''])
    
    137
    +test('T27423b', normal, compile_fail, [''])

  • testsuite/tests/printer/Makefile
    ... ... @@ -932,3 +932,8 @@ PprModifiers:
    932 932
     PprQualifiedStrings:
    
    933 933
     	$(CHECK_PPR)   $(LIBDIR) PprQualifiedStrings.hs
    
    934 934
     	$(CHECK_EXACT) $(LIBDIR) PprQualifiedStrings.hs
    
    935
    +
    
    936
    +.PHONY: T27423c
    
    937
    +T27423c:
    
    938
    +	$(CHECK_PPR)   $(LIBDIR) T27423c.hs
    
    939
    +	$(CHECK_EXACT) $(LIBDIR) T27423c.hs

  • testsuite/tests/printer/T27423c.hs
    1
    +{-# LANGUAGE GADTs #-}
    
    2
    +module T27423c where
    
    3
    +
    
    4
    +-- Exact-printing regression test
    
    5
    +-- Not every declaration there would pass renamer without errors
    
    6
    +data G a where
    
    7
    +  MkG1 :: a -> G a
    
    8
    +  MkG2 :: (a -> G a)
    
    9
    +  MkG3 :: forall a. a -> G a
    
    10
    +  MkG4 :: forall a. (a -> G a)
    
    11
    +
    
    12
    +data T where
    
    13
    +  MkT1 :: forall a. a -> b -> T
    
    14
    +  MkT2 :: (forall a. a -> b -> T)
    
    15
    +
    
    16
    +data S a where
    
    17
    +  MkS :: (forall a. S a)
    
    18
    +
    
    19
    +data U a where
    
    20
    +  MkU :: (Show a => U a)
    
    21
    +
    
    22
    +data V a where
    
    23
    +  MkV1 :: ((a -> V a))
    
    24
    +  MkV2 :: forall a. (forall b. V (b, a))
    
    25
    +  MkV3 :: (forall a. Show a => a -> V a)
    
    26
    +  MkV4 :: forall a. ((forall b. (Show a => a -> (b -> V a))))

  • testsuite/tests/printer/all.T
    ... ... @@ -223,3 +223,5 @@ test('TestLevelImports', [ignore_stderr, req_ppr_deps], makefile_test, ['TestLev
    223 223
     test('TestNamedDefaults', [ignore_stderr, req_ppr_deps], makefile_test, ['TestNamedDefaults'])
    
    224 224
     test('PprModifiers', [ignore_stderr,req_ppr_deps], makefile_test, ['PprModifiers'])
    
    225 225
     test('PprQualifiedStrings', [ignore_stderr,req_ppr_deps], makefile_test, ['PprQualifiedStrings'])
    
    226
    +
    
    227
    +test('T27423c', [ignore_stderr,req_ppr_deps], makefile_test, ['T27423c'])