From b9c2aa3ff9acbdb80ee61519bb6ec74b5090413f Mon Sep 17 00:00:00 2001 From: sheaf <sam.derbyshire@gmail.com> Date: Tue, 11 Jul 2023 13:40:13 +0200 Subject: [PATCH] Valid hole fits: don't panic on a Given The function GHC.Tc.Errors.validHoleFits would end up panicking when encountering a Given constraint. To fix this, it suffices to filter out the Givens before continuing. Fixes #22684 (cherry picked from commit 630e302617a4a3e00d86d0650cb86fa9e6913e44) --- compiler/GHC/Tc/Errors.hs | 19 +++++----- compiler/GHC/Tc/Errors/Types.hs | 4 ++- .../tests/typecheck/should_fail/T22684.hs | 19 ++++++++++ .../tests/typecheck/should_fail/T22684.stderr | 35 +++++++++++++++++++ testsuite/tests/typecheck/should_fail/all.T | 1 + 5 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 testsuite/tests/typecheck/should_fail/T22684.hs create mode 100644 testsuite/tests/typecheck/should_fail/T22684.stderr diff --git a/compiler/GHC/Tc/Errors.hs b/compiler/GHC/Tc/Errors.hs index ec166205155..969fade07a5 100644 --- a/compiler/GHC/Tc/Errors.hs +++ b/compiler/GHC/Tc/Errors.hs @@ -1563,16 +1563,19 @@ validHoleFits :: SolverReportErrCtxt -- ^ The context we're in, i.e. the -- the valid hole fits. validHoleFits ctxt@(CEC { cec_encl = implics , cec_tidy = lcl_env}) simps hole - = do { (tidy_env, fits) <- findValidHoleFits lcl_env implics (map mk_wanted simps) hole + = do { (tidy_env, fits) <- findValidHoleFits lcl_env implics (mapMaybe mk_wanted simps) hole ; return (ctxt {cec_tidy = tidy_env}, fits) } where - mk_wanted :: ErrorItem -> CtEvidence - mk_wanted (EI { ei_pred = pred, ei_evdest = Just dest, ei_loc = loc }) - = CtWanted { ctev_pred = pred - , ctev_dest = dest - , ctev_loc = loc - , ctev_rewriters = emptyRewriterSet } - mk_wanted item = pprPanic "validHoleFits no evdest" (ppr item) + mk_wanted :: ErrorItem -> Maybe CtEvidence + mk_wanted (EI { ei_pred = pred, ei_evdest = m_dest, ei_loc = loc }) + | Just dest <- m_dest + = Just (CtWanted { ctev_pred = pred + , ctev_dest = dest + , ctev_loc = loc + , ctev_rewriters = emptyRewriterSet }) + | otherwise + = Nothing -- The ErrorItem was a Given + -- See Note [Constraints include ...] givenConstraints :: SolverReportErrCtxt -> [(Type, RealSrcSpan)] diff --git a/compiler/GHC/Tc/Errors/Types.hs b/compiler/GHC/Tc/Errors/Types.hs index 5da28d80880..d55b13f6834 100644 --- a/compiler/GHC/Tc/Errors/Types.hs +++ b/compiler/GHC/Tc/Errors/Types.hs @@ -4863,7 +4863,9 @@ data ErrorItem = EI { ei_pred :: PredType -- report about this -- The ei_pred field will never be an unboxed equality with -- a (casted) tyvar on the right; this is guaranteed by the solver - , ei_evdest :: Maybe TcEvDest -- for Wanteds, where to put evidence + , ei_evdest :: Maybe TcEvDest + -- ^ for Wanteds, where to put the evidence + -- for Givens, Nothing , ei_flavour :: CtFlavour , ei_loc :: CtLoc , ei_m_reason :: Maybe CtIrredReason -- if this ErrorItem was made from a diff --git a/testsuite/tests/typecheck/should_fail/T22684.hs b/testsuite/tests/typecheck/should_fail/T22684.hs new file mode 100644 index 00000000000..60a95f3e14b --- /dev/null +++ b/testsuite/tests/typecheck/should_fail/T22684.hs @@ -0,0 +1,19 @@ +module T22684 where + +-- Example 1 from #22684 +p :: (Int ~ Bool => r) -> r +p _ = undefined + +q :: r +q = p _ + +-- Example 3 from #22684 +class Category k where + (.) :: k b c -> k a b -> k a c + +data Free p a b where + Prod :: Free p a (b, c) + Sum :: Free p (Either a b) c + +instance Category (Free p) where + Sum . Prod = _ diff --git a/testsuite/tests/typecheck/should_fail/T22684.stderr b/testsuite/tests/typecheck/should_fail/T22684.stderr new file mode 100644 index 00000000000..cead5f8d902 --- /dev/null +++ b/testsuite/tests/typecheck/should_fail/T22684.stderr @@ -0,0 +1,35 @@ + +T22684.hs:8:7: error: [GHC-88464] + • Found hole: _ :: r + Where: ‘r’ is a rigid type variable bound by + the type signature for: + q :: forall r. r + at T22684.hs:7:1-6 + • In the first argument of ‘p’, namely ‘_’ + In the expression: p _ + In an equation for ‘q’: q = p _ + • Relevant bindings include q :: r (bound at T22684.hs:8:1) + Constraints include Int ~ Bool (from T22684.hs:8:7) + Valid hole fits include q :: r (bound at T22684.hs:8:1) + +T22684.hs:19:16: error: [GHC-88464] + • Found hole: _ :: Free p a c + Where: ‘k’, ‘p’ are rigid type variables bound by + the instance declaration + at T22684.hs:18:10-26 + ‘a’, ‘c’ are rigid type variables bound by + the type signature for: + (T22684..) :: forall b c a. Free p b c -> Free p a b -> Free p a c + at T22684.hs:19:7 + • In an equation for ‘T22684..’: Sum T22684.. Prod = _ + In the instance declaration for ‘Category (Free p)’ + • Relevant bindings include + (.) :: Free p b c -> Free p a b -> Free p a c + (bound at T22684.hs:19:7) + Constraints include + b ~ (b2, c1) (from T22684.hs:19:9-12) + b ~ Either a1 b1 (from T22684.hs:19:3-5) + Valid hole fits include + q :: forall r. r + with q @(Free p a c) + (bound at T22684.hs:8:1) diff --git a/testsuite/tests/typecheck/should_fail/all.T b/testsuite/tests/typecheck/should_fail/all.T index a1805014c85..d1d77f90536 100644 --- a/testsuite/tests/typecheck/should_fail/all.T +++ b/testsuite/tests/typecheck/should_fail/all.T @@ -696,3 +696,4 @@ test('VisFlag2', normal, compile_fail, ['']) test('VisFlag3', normal, compile_fail, ['']) test('VisFlag4', normal, compile_fail, ['']) test('VisFlag5', normal, compile_fail, ['']) +test('T22684', normal, compile_fail, ['']) -- GitLab