summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc
diff options
context:
space:
mode:
authorSimon Peyton Jones <simon.peytonjones@gmail.com>2023-02-08 22:05:41 +0000
committersheaf <sam.derbyshire@gmail.com>2023-02-20 12:06:32 +0100
commit7080a93fd09b71aa6c94e6336eb054e9f5592932 (patch)
tree05ffb196258994f464b467c21386d51bca3fe4e6 /compiler/GHC/Tc
parenta203ad854ffee802e6bf0aca26e6c9a99bec3865 (diff)
downloadhaskell-7080a93fd09b71aa6c94e6336eb054e9f5592932.tar.gz
Improve GHC.Tc.Gen.App.tcInstFunwip/T22908
It wasn't behaving right when inst_final=False, and the function had no type variables f :: Foo => Int Rather a corner case, but we might as well do it right. Fixes #22908 Unexpectedly, three test cases (all using :type in GHCi) got slightly better output as a result: T17403, T14796, T12447
Diffstat (limited to 'compiler/GHC/Tc')
-rw-r--r--compiler/GHC/Tc/Gen/App.hs28
1 files changed, 12 insertions, 16 deletions
diff --git a/compiler/GHC/Tc/Gen/App.hs b/compiler/GHC/Tc/Gen/App.hs
index 06158cace3..c8c1730b35 100644
--- a/compiler/GHC/Tc/Gen/App.hs
+++ b/compiler/GHC/Tc/Gen/App.hs
@@ -543,25 +543,16 @@ tcInstFun do_ql inst_final (rn_fun, fun_ctxt) fun_sigma rn_args
HsUnboundVar {} -> True
_ -> False
- inst_all, inst_inferred, inst_none :: ForAllTyFlag -> Bool
- inst_all (Invisible {}) = True
- inst_all Required = False
-
- inst_inferred (Invisible InferredSpec) = True
- inst_inferred (Invisible SpecifiedSpec) = False
- inst_inferred Required = False
-
- inst_none _ = False
-
inst_fun :: [HsExprArg 'TcpRn] -> ForAllTyFlag -> Bool
- inst_fun [] | inst_final = inst_all
- | otherwise = inst_none
- -- Using `inst_none` for `:type` avoids
+ -- True <=> instantiate a tyvar with this ForAllTyFlag
+ inst_fun [] | inst_final = isInvisibleForAllTyFlag
+ | otherwise = const False
+ -- Using `const False` for `:type` avoids
-- `forall {r1} (a :: TYPE r1) {r2} (b :: TYPE r2). a -> b`
-- turning into `forall a {r2} (b :: TYPE r2). a -> b`.
-- See #21088.
- inst_fun (EValArg {} : _) = inst_all
- inst_fun _ = inst_inferred
+ inst_fun (EValArg {} : _) = isInvisibleForAllTyFlag
+ inst_fun _ = isInferredForAllTyFlag
-----------
go, go1 :: Delta
@@ -588,7 +579,12 @@ tcInstFun do_ql inst_final (rn_fun, fun_ctxt) fun_sigma rn_args
-- c.f. GHC.Tc.Utils.Instantiate.topInstantiate
go1 delta acc so_far fun_ty args
| (tvs, body1) <- tcSplitSomeForAllTyVars (inst_fun args) fun_ty
- , (theta, body2) <- tcSplitPhiTy body1
+ , (theta, body2) <- if inst_fun args Inferred
+ then tcSplitPhiTy body1
+ else ([], body1)
+ -- inst_fun args Inferred: dictionary parameters are like Inferred foralls
+ -- E.g. #22908: f :: Foo => blah
+ -- No foralls! But if inst_final=False, don't instantiate
, not (null tvs && null theta)
= do { (inst_tvs, wrap, fun_rho) <- addHeadCtxt fun_ctxt $
instantiateSigma fun_orig tvs theta body2