summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc/Module.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Tc/Module.hs')
-rw-r--r--compiler/GHC/Tc/Module.hs37
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.
-}
--------------------------