Commit 30c981e1 authored by skvadrik's avatar skvadrik Committed by Ben Gamari

Removed deprecated syntax for GADT constuctors.

Old syntax was deprecated 6 years ago in this commit
432b9c93 by simonpj:"New syntax for
GADT-style record declarations, and associated refactoring" discussed
in Trac #3306.

This patch removes 2 reduce/reduce conflicts in parser. Conflicting
productions were:

```
    gadt_constr -> con_list '::' sigtype
    gadt_constr -> oqtycon '{' fielddecls '}' '::' sigtype
```

Recursive inlining of `con_list` and `oqtycon` helped reveal the
conflict:

```
    gadt_constr -> '(' CONSYM ')' '::' sigtype
    gadt_constr -> '(' CONSYM ')' '{' fielddecls '}' '::' sigtype
```

between two types of GADT constructors (second form stands for
deprecated syntax).

Test Plan: `make fasttest`, one breakage TEST="records-fail" (parse
error instead of typecheck error due to removal of deprecated syntax).
Updated test.

Reviewers: simonmar, bgamari, austin, simonpj

Reviewed By: simonpj

Subscribers: thomie, mpickering, trofi

Differential Revision: https://phabricator.haskell.org/D1118

GHC Trac Issues: #3306
parent 64b6733e
......@@ -82,10 +82,9 @@ import Util ( looksLikePackageName )
}
{- Last updated: 29 Jul 2015
{- Last updated: 31 Jul 2015
Conflicts: 47 shift/reduce
2 reduce/reduce
If you modify this parser and add a conflict, please update this comment.
You can learn more about the conflicts by passing 'happy' the -i flag:
......@@ -293,29 +292,6 @@ state 950 contains 1 shift/reduce conflicts.
Conflict: 'by'
-------------------------------------------------------------------------------
state 1230 contains 1 reduce/reduce conflicts.
*** tyconsym -> ':' . (rule 653)
consym -> ':' . (rule 721)
Conflict: ')'
-------------------------------------------------------------------------------
state 1231 contains 1 reduce/reduce conflicts.
*** tyconsym -> CONSYM . (rule 651)
consym -> CONSYM . (rule 720)
Conflict: ')'
TODO: Why? (NB: This one has been around for a while; it's quite puzzling
because we really shouldn't get confused between tyconsym and consym.
Trace the state machine, maybe?)
TODO: Same as State 1230
-------------------------------------------------------------------------------
-- API Annotations
......@@ -1820,18 +1796,24 @@ gadt_constr_with_doc
{% return $1 }
gadt_constr :: { LConDecl RdrName }
-- Returns a list because of: C,D :: ty
-- see Note [Difference in parsing GADT and data constructors]
-- Returns a list because of: C,D :: ty
: con_list '::' sigtype
{% do { (anns,gadtDecl) <- mkGadtDecl (unLoc $1) $3
; ams (sLL $1 $> gadtDecl)
(mj AnnDcolon $2:anns) } }
-- Deprecated syntax for GADT record declarations
| oqtycon '{' fielddecls '}' '::' sigtype
{% do { cd <- mkDeprecatedGadtRecordDecl (comb2 $1 $6) $1 (noLoc $3) $6
; cd' <- checkRecordSyntax cd
; ams (L (comb2 $1 $6) (unLoc cd'))
[moc $2,mcc $4,mj AnnDcolon $5] } }
{- Note [Difference in parsing GADT and data constructors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GADT constructors have simpler syntax than usual data constructors:
in GADTs, types cannot occur to the left of '::', so they cannot be mixed
with constructor names (see Note [Parsing data constructors is hard]).
Due to simplified syntax, GADT constructor names (left-hand side of '::')
use simpler grammar production than usual data constructor names. As a
consequence, GADT constructor names are resticted (names like '(*)' are
allowed in usual data constructors, but not in GADTs).
-}
constrs :: { Located ([AddAnn],[LConDecl RdrName]) }
: maybe_docnext '=' constrs1 { L (comb2 $2 $3) ([mj AnnEqual $2]
......@@ -1862,16 +1844,21 @@ forall :: { Located ([AddAnn],[LHsTyVarBndr RdrName]) }
| {- empty -} { noLoc ([],[]) }
constr_stuff :: { Located (Located RdrName, HsConDeclDetails RdrName) }
-- We parse the constructor declaration
-- C t1 t2
-- as a btype (treating C as a type constructor) and then convert C to be
-- a data constructor. Reason: it might continue like this:
-- C t1 t2 %: D Int
-- in which case C really would be a type constructor. We can't resolve this
-- ambiguity till we come across the constructor oprerator :% (or not, more usually)
-- see Note [Parsing data constructors is hard]
: btype {% splitCon $1 >>= return.sLL $1 $> }
| btype conop btype { sLL $1 $> ($2, InfixCon $1 $3) }
{- Note [Parsing data constructors is hard]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We parse the constructor declaration
C t1 t2
as a btype (treating C as a type constructor) and then convert C to be
a data constructor. Reason: it might continue like this:
C t1 t2 %: D Int
in which case C really would be a type constructor. We can't resolve this
ambiguity till we come across the constructor oprerator :% (or not, more usually)
-}
fielddecls :: { [LConDeclField RdrName] }
: {- empty -} { [] }
| fielddecls1 { $1 }
......
......@@ -35,7 +35,6 @@ module RdrHsSyn (
mkExtName, -- RdrName -> CLabelString
mkGadtDecl, -- [Located RdrName] -> LHsType RdrName -> ConDecl RdrName
mkSimpleConDecl,
mkDeprecatedGadtRecordDecl,
mkATDefault,
-- Bunch of functions in the parser monad for
......@@ -469,25 +468,6 @@ mkPatSynMatchGroup (L _ patsyn_name) (L _ decls) =
text "pattern synonym 'where' clause must bind the pattern synonym's name" <+>
quotes (ppr patsyn_name) $$ ppr decl
mkDeprecatedGadtRecordDecl :: SrcSpan
-> Located RdrName
-> Located [LConDeclField RdrName]
-> LHsType RdrName
-> P (LConDecl RdrName)
-- This one uses the deprecated syntax
-- C { x,y ::Int } :: T a b
-- We give it a RecCon details right away
mkDeprecatedGadtRecordDecl loc (L con_loc con) flds res_ty
= do { data_con <- tyConToDataCon con_loc con
; return (L loc (ConDecl { con_old_rec = True
, con_names = [data_con]
, con_explicit = Implicit
, con_qvars = mkHsQTvs []
, con_cxt = noLoc []
, con_details = RecCon flds
, con_res = ResTyGADT loc res_ty
, con_doc = Nothing })) }
mkSimpleConDecl :: Located RdrName -> [LHsTyVarBndr RdrName]
-> LHsContext RdrName -> HsConDeclDetails RdrName
-> ConDecl RdrName
......
......@@ -2,10 +2,18 @@
-- Tests record syntax for GADTs
-- Record syntax in GADTs has been deprecated since July 2009
-- see commit 432b9c9322181a3644083e3c19b7e240d90659e7 by simonpj:
-- "New syntax for GADT-style record declarations, and associated refactoring"
-- and Trac #3306
-- It's been removed in August 2015
-- see Phab D1118
-- test should result into parse error
module ShouldFail where
data T a where
T1 { x :: a, y :: b } :: T (a,b)
T4 { x :: Int } :: T [a]
\ No newline at end of file
records-fail1.hs:7:1: error:
Constructors T1 and T4 have a common field ‘x’,
but have different result types
In the data type declaration for ‘T’
records-fail1.hs:18:6: error: parse error on input ‘{’
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment