summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/GHC/HsToCore/Arrows.hs15
-rw-r--r--testsuite/tests/arrows/should_compile/T18950.hs87
-rw-r--r--testsuite/tests/arrows/should_compile/all.T1
3 files changed, 100 insertions, 3 deletions
diff --git a/compiler/GHC/HsToCore/Arrows.hs b/compiler/GHC/HsToCore/Arrows.hs
index 52de5f6fb5..60e3346ee7 100644
--- a/compiler/GHC/HsToCore/Arrows.hs
+++ b/compiler/GHC/HsToCore/Arrows.hs
@@ -25,7 +25,6 @@ import GHC.Hs hiding (collectPatBinders, collectPatsBinders,
collectLStmtsBinders, collectLStmtBinders,
collectStmtBinders )
import GHC.Tc.Utils.Zonk
-import qualified GHC.Hs.Utils as HsUtils
-- NB: The desugarer, which straddles the source and Core worlds, sometimes
-- needs to see source types (newtypes etc), and sometimes not
@@ -1280,5 +1279,15 @@ collectLStmtBinders :: LStmt GhcTc body -> [Id]
collectLStmtBinders = collectStmtBinders . unLoc
collectStmtBinders :: Stmt GhcTc body -> [Id]
-collectStmtBinders (RecStmt { recS_later_ids = later_ids }) = later_ids
-collectStmtBinders stmt = HsUtils.collectStmtBinders stmt
+collectStmtBinders (BindStmt _ pat _) = collectPatBinders pat
+collectStmtBinders (LetStmt _ binds) = collectLocalBinders (unLoc binds)
+collectStmtBinders (BodyStmt {}) = []
+collectStmtBinders (LastStmt {}) = []
+collectStmtBinders (ParStmt _ xs _ _) = collectLStmtsBinders
+ $ [s | ParStmtBlock _ ss _ _ <- xs, s <- ss]
+collectStmtBinders (TransStmt { trS_stmts = stmts }) = collectLStmtsBinders stmts
+collectStmtBinders (RecStmt { recS_stmts = ss }) = collectLStmtsBinders ss
+collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args
+ where
+ collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat
+ collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat
diff --git a/testsuite/tests/arrows/should_compile/T18950.hs b/testsuite/tests/arrows/should_compile/T18950.hs
new file mode 100644
index 0000000000..326022207d
--- /dev/null
+++ b/testsuite/tests/arrows/should_compile/T18950.hs
@@ -0,0 +1,87 @@
+{-# LANGUAGE Arrows #-}
+{-# LANGUAGE GADTs #-}
+-- NOTE: use ExistentialQuantification for non-GADT 'data Point' declaration
+-- {-# LANGUAGE ExistentialQuantification #-}
+{--
+Issue: Compiling `Example.hs` causes ghc to panic (happens in 8.8.x, 8.10.x, and 9.0.x)
+
+Reproduce:
+```bash
+nix-shell -I nixpkgs=https://nixos.org/channels/nixos-unstable/nixexprs.tar.xz -p haskell.compiler.ghc901
+ghc Example.hs
+```
+
+Results:
+
+ghc: panic! (the 'impossible' happened)
+ (GHC version 9.0.0.20200925:
+ GHC.StgToCmm.Env: variable not found
+ $dRealFloat_a1tn
+ local binds for:
+ pos
+ Point
+ Obj
+ $dArrow_s1xr
+ ds_s1xs
+ ds1_s1xt
+ ds2_s1ya
+ ds3_s1yb
+ ds4_s1yc
+ ds6_s1ye
+ sat_s1yf
+ sat_s1yg
+ sat_s1yh
+ sat_s1yi
+ sat_s1yj
+ sat_s1yk
+ sat_s1yl
+ sat_s1ym
+ sat_s1yn
+ Call stack:
+ CallStack (from HasCallStack):
+ callStackDoc, called at compiler/GHC/Utils/Outputable.hs:1230:37 in ghc:GHC.Utils.Outputable
+ pprPanic, called at compiler/GHC/StgToCmm/Env.hs:152:9 in ghc:GHC.StgToCmm.Env
+
+Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug
+--}
+{--
+```bash
+ghc -dcore-lint Example.hs
+```
+--}
+module Example (
+-- NOTE: no error if `step` not exported
+ step,
+) where
+
+import Control.Arrow
+
+-- NOTE: existentially qualified declaration of Point,
+-- mirrors definition of 'Point2' in package 'simple-affine-space'
+-- import Data.Point2
+
+-- NOTE: no error without 'RealFloat a` context; both examples fail
+--data Point a = RealFloat a => Point !a
+data Point a where Point :: RealFloat a => a -> Point a
+
+type Position = Point Float
+
+ptrPos :: Arrow a => a Obj Position
+ptrPos = arr pos
+
+data Obj = Obj { pos :: !Position }
+
+step :: Arrow a => a Obj Obj
+step = proc gi -> do
+ -- NOTE: no error without this arrow line; no error if not deconstructed.
+ (Point _) <- ptrPos -< gi
+ {--
+ -- NOTE: this code does work (in place of `(Point _) <- ptrPos -< gi` above)
+ pt <- ptrPos -< gi
+ let (Point _) = pt
+ --}
+ returnA -< Obj {
+ -- NOTE: no error without this 'pos' field
+ pos = (Point 0)
+ }
+
diff --git a/testsuite/tests/arrows/should_compile/all.T b/testsuite/tests/arrows/should_compile/all.T
index b47cea0538..a399006aae 100644
--- a/testsuite/tests/arrows/should_compile/all.T
+++ b/testsuite/tests/arrows/should_compile/all.T
@@ -17,3 +17,4 @@ test('T5267', expect_broken(5267), compile, [''])
test('T5022', normalise_fun(normalise_errmsg), compile, [''])
test('T5333', normal, compile, [''])
test('T17423', normal, compile, [''])
+test('T18950', normal, compile, [''])