diff options
author | sheaf <sam.derbyshire@gmail.com> | 2022-02-25 12:11:01 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-02-25 21:10:22 -0500 |
commit | 4ad8ce0b5c741862e2f94fd362077068b9b669d3 (patch) | |
tree | 9cae0fdf40b957e9b39b07ebedf48e7cb4b27ed6 /compiler/GHC/Tc/Module.hs | |
parent | 8387dfbe6e468083c472ea019be8af79d489cbc8 (diff) | |
download | haskell-4ad8ce0b5c741862e2f94fd362077068b9b669d3.tar.gz |
GHCi: don't normalise partially instantiated types
This patch skips performing type normalisation when we haven't
fully instantiated the type. That is, in tcRnExpr
(used only for :type in GHCi), skip normalisation if
the result type responds True to isSigmaTy.
Fixes #20974
Diffstat (limited to 'compiler/GHC/Tc/Module.hs')
-rw-r--r-- | compiler/GHC/Tc/Module.hs | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/compiler/GHC/Tc/Module.hs b/compiler/GHC/Tc/Module.hs index 40bc5188f6..11278d6bc7 100644 --- a/compiler/GHC/Tc/Module.hs +++ b/compiler/GHC/Tc/Module.hs @@ -2576,14 +2576,12 @@ tcRnExpr hsc_env mode rdr_expr mkPhiTy (map idType dicts) res_ty } ; ty <- zonkTcType all_expr_ty ; - -- We normalise type families, so that the type of an expression is the - -- same as of a bound expression (GHC.Tc.Gen.Bind.mkInferredPolyId). See Trac - -- #10321 for further discussion. + -- See Note [Normalising the type in :type] fam_envs <- tcGetFamInstEnvs ; - -- normaliseType returns a coercion which we discard, so the Role is - -- irrelevant - return (reductionReducedType (normaliseType fam_envs Nominal ty)) - } + let { normalised_type = reductionReducedType $ normaliseType fam_envs Nominal ty + -- normaliseType returns a coercion which we discard, so the Role is irrelevant. + ; final_type = if isSigmaTy res_ty then ty else normalised_type } ; + return final_type } where -- Optionally instantiate the type of the expression -- See Note [TcRnExprMode] @@ -2608,6 +2606,31 @@ and not forall {b}. Int -> b -> Int Solution: use tcInferSigma, which in turn uses tcInferApp, which has a special case for application chains. + +Note [Normalising the type in :type] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In :t <expr> we usually normalise the type (to simplify type functions) +before displaying the result. Reason (see #10321): otherwise we may show +types like + <expr> :: Vec (1+2) Int +rather than the simpler + <expr> :: Vec 3 Int +In GHC.Tc.Gen.Bind.mkInferredPolyId we normalise for a very similar reason. + +However this normalisation is less helpful when <expr> is just +an identifier, whose user-written type happens to contain type-function +applications. E.g. (#20974) + test :: F [Monad, A, B] m => m () +where F is a type family. If we say `:t test`, we'd prefer to see +the type family un-expanded. + +We adopt the following ad-hoc solution: if the type inferred for <expr> +(before generalisation, namely res_ty) is a SigmaType (i.e. is not +fully instantiated) then do not normalise; otherwise normalise. +This is not ideal; for example, suppose x :: F Int. Then + :t x +would be normalised because `F Int` is not a SigmaType. But +anything here is ad-hoc, and it's a user-sought improvement. -} -------------------------- |