diff options
author | Simon Peyton Jones <simon.peytonjones@gmail.com> | 2023-02-08 22:05:41 +0000 |
---|---|---|
committer | sheaf <sam.derbyshire@gmail.com> | 2023-02-20 12:06:32 +0100 |
commit | 7080a93fd09b71aa6c94e6336eb054e9f5592932 (patch) | |
tree | 05ffb196258994f464b467c21386d51bca3fe4e6 /compiler/GHC/Tc/Gen | |
parent | a203ad854ffee802e6bf0aca26e6c9a99bec3865 (diff) | |
download | haskell-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/Gen')
-rw-r--r-- | compiler/GHC/Tc/Gen/App.hs | 28 |
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 |