summaryrefslogtreecommitdiff
path: root/testsuite/tests/parser/should_fail
diff options
context:
space:
mode:
authorVladislav Zavialov <vlad.z.4096@gmail.com>2020-07-22 16:24:28 +0300
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-08-06 13:34:05 -0400
commit686e06c59c3aa6b66895e8a501c7afb019b09e36 (patch)
treebe3e7cf27fceacaddd39fcb2fbea05dd5c444b55 /testsuite/tests/parser/should_fail
parentfbcb886d503dd7aaebc4c40e59615068b3fd0bd7 (diff)
downloadhaskell-686e06c59c3aa6b66895e8a501c7afb019b09e36.tar.gz
Grammar for types and data/newtype constructors
Before this patch, we parsed types into a reversed sequence of operators and operands. For example, (F x y + G a b * X) would be parsed as [X, *, b, a, G, +, y, x, F], using a simple grammar: tyapps : tyapp | tyapps tyapp tyapp : atype | PREFIX_AT atype | tyop | unpackedness Then we used a hand-written state machine to assemble this either into a type, using 'mergeOps', or into a constructor, using 'mergeDataCon'. This is due to a syntactic ambiguity: data T1 a = MkT1 a data T2 a = Ord a => MkT2 a In T1, what follows after the = sign is a data/newtype constructor declaration. However, in T2, what follows is a type (of kind Constraint). We don't know which of the two we are parsing until we encounter =>, and we cannot check for => without unlimited lookahead. This poses a few issues when it comes to e.g. infix operators: data I1 = Int :+ Bool :+ Char -- bad data I2 = Int :+ Bool :+ Char => MkI2 -- fine By this issue alone we are forced into parsing into an intermediate representation and doing a separate validation pass. However, should that intermediate representation be as low-level as a flat sequence of operators and operands? Before GHC Proposal #229, the answer was Yes, due to some particularly nasty corner cases: data T = ! A :+ ! B -- used to be fine, hard to parse data T = ! A :+ ! B => MkT -- bad However, now the answer is No, as this corner case is gone: data T = ! A :+ ! B -- bad data T = ! A :+ ! B => MkT -- bad This means we can write a proper grammar for types, overloading it in the DisambECP style, see Note [Ambiguous syntactic categories]. With this patch, we introduce a new class, DisambTD. Just like DisambECP is used to disambiguate between expressions, commands, and patterns, DisambTD is used to disambiguate between types and data/newtype constructors. This way, we get a proper, declarative grammar for constructors and types: infixtype : ftype | ftype tyop infixtype | unpackedness infixtype ftype : atype | tyop | ftype tyarg | ftype PREFIX_AT tyarg tyarg : atype | unpackedness atype And having a grammar for types means we are a step closer to using a single grammar for types and expressions.
Diffstat (limited to 'testsuite/tests/parser/should_fail')
-rw-r--r--testsuite/tests/parser/should_fail/T12045d.stderr3
-rw-r--r--testsuite/tests/parser/should_fail/strictnessDataCon_B.stderr3
-rw-r--r--testsuite/tests/parser/should_fail/typeops_A.stderr3
-rw-r--r--testsuite/tests/parser/should_fail/typeops_C.stderr2
-rw-r--r--testsuite/tests/parser/should_fail/unpack_empty_type.stderr3
-rw-r--r--testsuite/tests/parser/should_fail/unpack_inside_type.stderr6
6 files changed, 11 insertions, 9 deletions
diff --git a/testsuite/tests/parser/should_fail/T12045d.stderr b/testsuite/tests/parser/should_fail/T12045d.stderr
index 128cf58d86..a731352f10 100644
--- a/testsuite/tests/parser/should_fail/T12045d.stderr
+++ b/testsuite/tests/parser/should_fail/T12045d.stderr
@@ -1,4 +1,3 @@
T12045d.hs:11:16: error:
- Unexpected kind application in a data/newtype declaration:
- MkD @Nat Bool
+ Unexpected kind application in a data/newtype declaration: MkD @Nat
diff --git a/testsuite/tests/parser/should_fail/strictnessDataCon_B.stderr b/testsuite/tests/parser/should_fail/strictnessDataCon_B.stderr
index 47f85eae8c..04ea0c8b18 100644
--- a/testsuite/tests/parser/should_fail/strictnessDataCon_B.stderr
+++ b/testsuite/tests/parser/should_fail/strictnessDataCon_B.stderr
@@ -1,3 +1,2 @@
-strictnessDataCon_B.hs:1:27: error:
- {-# UNPACK #-} cannot appear inside a type.
+strictnessDataCon_B.hs:1:42: error: parse error on input ‘}’
diff --git a/testsuite/tests/parser/should_fail/typeops_A.stderr b/testsuite/tests/parser/should_fail/typeops_A.stderr
index 69f7aac6be..8558729f2f 100644
--- a/testsuite/tests/parser/should_fail/typeops_A.stderr
+++ b/testsuite/tests/parser/should_fail/typeops_A.stderr
@@ -1,2 +1,3 @@
-typeops_A.hs:1:12: error: Operator applied to too few arguments: +
+typeops_A.hs:2:1: error:
+ parse error (possibly incorrect indentation or mismatched brackets)
diff --git a/testsuite/tests/parser/should_fail/typeops_C.stderr b/testsuite/tests/parser/should_fail/typeops_C.stderr
index 280323bb67..75372a8a2a 100644
--- a/testsuite/tests/parser/should_fail/typeops_C.stderr
+++ b/testsuite/tests/parser/should_fail/typeops_C.stderr
@@ -1,2 +1,2 @@
-typeops_C.hs:1:12: error: Operator applied to too few arguments: +
+typeops_C.hs:1:14: error: Operator applied to too few arguments: +
diff --git a/testsuite/tests/parser/should_fail/unpack_empty_type.stderr b/testsuite/tests/parser/should_fail/unpack_empty_type.stderr
index fe520c9317..dbc73c87ff 100644
--- a/testsuite/tests/parser/should_fail/unpack_empty_type.stderr
+++ b/testsuite/tests/parser/should_fail/unpack_empty_type.stderr
@@ -1,3 +1,2 @@
-unpack_empty_type.hs:3:19: error:
- {-# UNPACK #-} must be applied to a type.
+unpack_empty_type.hs:3:34: error: parse error on input ‘}’
diff --git a/testsuite/tests/parser/should_fail/unpack_inside_type.stderr b/testsuite/tests/parser/should_fail/unpack_inside_type.stderr
index 0c09e63b71..60d7ba87a3 100644
--- a/testsuite/tests/parser/should_fail/unpack_inside_type.stderr
+++ b/testsuite/tests/parser/should_fail/unpack_inside_type.stderr
@@ -1,3 +1,7 @@
unpack_inside_type.hs:3:25: error:
- {-# UNPACK #-} cannot appear inside a type.
+ • Unexpected UNPACK annotation: {-# UNPACK #-}Int
+ UNPACK annotation cannot appear nested inside a type
+ • In the first argument of ‘Maybe’, namely ‘({-# UNPACK #-}Int)’
+ In the type ‘Maybe ({-# UNPACK #-}Int)’
+ In the definition of data constructor ‘T’