Parse holes as infix operators
authorÖmer Sinan Ağacan <omeragacan@gmail.com>
Sun, 8 Jan 2017 04:52:53 +0000 (07:52 +0300)
committerÖmer Sinan Ağacan <omeragacan@gmail.com>
Sun, 8 Jan 2017 04:53:06 +0000 (07:53 +0300)
Reported as #13050. Since holes are expressions but not identifiers,
holes were not allowed in infix operator position. This patch introduces
a new production in infix operator parser to allow this.

Reviewers: simonpj, austin, bgamari

Reviewed By: simonpj

Subscribers: simonpj, RyanGlScott, thomie, mpickering

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

GHC Trac Issues: #13050

compiler/hsSyn/HsExpr.hs
compiler/parser/Parser.y
testsuite/tests/typecheck/should_compile/T13050.hs [new file with mode: 0644]
testsuite/tests/typecheck/should_compile/T13050.stderr [new file with mode: 0644]
testsuite/tests/typecheck/should_compile/all.T

index 1b6ccdc..18bf54a 100644 (file)
@@ -823,6 +823,7 @@ ppr_expr (OpApp e1 op _ e2)
   = case unLoc op of
       HsVar (L _ v) -> pp_infixly v
       HsRecFld f    -> pp_infixly f
+      HsUnboundVar h@TrueExprHole{} -> pp_infixly (unboundVarOcc h)
       _             -> pp_prefixly
   where
     pp_e1 = pprDebugParendExpr e1   -- In debug mode, add parens
index 3fc20a1..dfb6755 100644 (file)
@@ -3132,6 +3132,9 @@ varop   :: { Located RdrName }
 qop     :: { LHsExpr RdrName }   -- used in sections
         : qvarop                { sL1 $1 $ HsVar $1 }
         | qconop                { sL1 $1 $ HsVar $1 }
+        | '`' '_' '`'           {% ams (sLL $1 $> EWildPat)
+                                       [mj AnnBackquote $1,mj AnnVal $2
+                                       ,mj AnnBackquote $3] }
 
 qopm    :: { LHsExpr RdrName }   -- used in sections
         : qvaropm               { sL1 $1 $ HsVar $1 }
diff --git a/testsuite/tests/typecheck/should_compile/T13050.hs b/testsuite/tests/typecheck/should_compile/T13050.hs
new file mode 100644 (file)
index 0000000..d40c476
--- /dev/null
@@ -0,0 +1,6 @@
+module HolesInfix where
+
+f, g, q :: Int -> Int -> Int
+f x y = _ x y
+g x y = x `_` y
+q x y = x `_a` y
diff --git a/testsuite/tests/typecheck/should_compile/T13050.stderr b/testsuite/tests/typecheck/should_compile/T13050.stderr
new file mode 100644 (file)
index 0000000..b8ccd76
--- /dev/null
@@ -0,0 +1,31 @@
+
+T13050.hs:4:9: warning: [-Wtyped-holes (in -Wdefault)]
+    • Found hole: _ :: Int -> Int -> Int
+    • In the expression: _
+      In the expression: _ x y
+      In an equation for ‘f’: f x y = _ x y
+    • Relevant bindings include
+        y :: Int (bound at T13050.hs:4:5)
+        x :: Int (bound at T13050.hs:4:3)
+        f :: Int -> Int -> Int (bound at T13050.hs:4:1)
+
+T13050.hs:5:11: warning: [-Wtyped-holes (in -Wdefault)]
+    • Found hole: _ :: Int -> Int -> Int
+    • In the expression: _
+      In the expression: x `_` y
+      In an equation for ‘g’: g x y = x `_` y
+    • Relevant bindings include
+        y :: Int (bound at T13050.hs:5:5)
+        x :: Int (bound at T13050.hs:5:3)
+        g :: Int -> Int -> Int (bound at T13050.hs:5:1)
+
+T13050.hs:6:11: warning: [-Wtyped-holes (in -Wdefault)]
+    • Found hole: _a :: Int -> Int -> Int
+      Or perhaps ‘_a’ is mis-spelled, or not in scope
+    • In the expression: _a
+      In the expression: x `_a` y
+      In an equation for ‘q’: q x y = x `_a` y
+    • Relevant bindings include
+        y :: Int (bound at T13050.hs:6:5)
+        x :: Int (bound at T13050.hs:6:3)
+        q :: Int -> Int -> Int (bound at T13050.hs:6:1)
index d628366..40d31bb 100644 (file)
@@ -563,3 +563,4 @@ test('T12911', normal, compile, [''])
 test('T12925', normal, compile, [''])
 test('T12919', expect_broken(12919), compile, [''])
 test('T12936', normal, compile, [''])
+test('T13050', normal, compile, ['-fdefer-type-errors'])