[Git][ghc/ghc][wip/marge_bot_batch_merge_job] Add Note [Typechecking overloaded literals]
Marge Bot (@marge-bot)
gitlab at gitlab.haskell.org
Tue Dec 17 03:57:38 UTC 2024
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
03a8158b by Simon Peyton Jones at 2024-12-16T22:57:27-05:00
Add Note [Typechecking overloaded literals]
See #25494.
- - - - -
3 changed files:
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Utils/Unify.hs
Changes:
=====================================
compiler/GHC/Tc/Gen/Expr.hs
=====================================
@@ -296,13 +296,6 @@ tcExpr e@(ExprWithTySig {}) res_ty = tcApp e res_ty
tcExpr (XExpr e) res_ty = tcXExpr e res_ty
-tcExpr e@(HsOverLit _ lit) res_ty
- = do { mb_res <- tcShortCutLit lit res_ty
- -- See Note [Short cut for overloaded literals] in GHC.Tc.Zonk.Type
- ; case mb_res of
- Just lit' -> return (HsOverLit noExtField lit')
- Nothing -> tcApp e res_ty }
-
-- Typecheck an occurrence of an unbound Id
--
-- Some of these started life as a true expression hole "_".
@@ -353,6 +346,51 @@ tcExpr e@(HsLam x lam_variant matches) res_ty
= do { (wrap, matches') <- tcLambdaMatches e lam_variant matches [] res_ty
; return (mkHsWrap wrap $ HsLam x lam_variant matches') }
+{-
+************************************************************************
+* *
+ Overloaded literals
+* *
+************************************************************************
+-}
+
+tcExpr e@(HsOverLit _ lit) res_ty
+ = -- See Note [Typechecking overloaded literals]
+ do { mb_res <- tcShortCutLit lit res_ty
+ -- See Note [Short cut for overloaded literals] in GHC.Tc.Utils.TcMType
+ ; case mb_res of
+ Just lit' -> return (HsOverLit noExtField lit')
+ Nothing -> tcApp e res_ty }
+ -- Why go via tcApp? See Note [Typechecking overloaded literals]
+
+{- Note [Typechecking overloaded literals]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Generally speaking, an overloaded literal like "3" typechecks as if you
+had written (fromInteger (3 :: Integer)). But in practice it's a little
+tricky:
+
+* Rebindable syntax (see #19154 and !4981). With rebindable syntax we might have
+ fromInteger :: Integer -> forall a. Num a => a
+ and then we might hope to use a Visible Type Application (VTA) to write
+ 3 @Int
+ expecting it to expand to
+ fromInteger (3::Integer) @Int dNumInt
+ To achieve that, we need to
+ * treat the application using `tcApp` to deal with the VTA
+ * treat the overloaded literal as the "head" of an application;
+ see `GHC.Tc.Gen.Head.tcInferAppHead`.
+
+* Short-cutting. If we have
+ xs :: [Int]
+ xs = [3,4,5,6... ]
+ then it's a huge short-cut (in compile time) to just cough up the `Int` literal
+ for `3`, rather than (fromInteger @Int d), with a wanted constraint `[W] Num Int`.
+ See Note [Short cut for overloaded literals] in GHC.Tc.Utils.TcMType.
+
+ We can only take this short-cut if rebindable syntax is off; see `tcShortCutLit`.
+-}
+
+
{-
************************************************************************
* *
=====================================
compiler/GHC/Tc/Gen/Head.hs
=====================================
@@ -765,6 +765,8 @@ tcInferOverLit lit@(OverLit { ol_val = val
-- where fromInteger is gotten by looking up from_name, and
-- the (3 :: Integer) is returned by mkOverLit
-- Ditto the string literal "foo" to (fromString ("foo" :: String))
+ --
+ -- See Note [Typechecking overloaded literals] in GHC.Tc.Gen.Expr
do { hs_lit <- mkOverLit val
; from_id <- tcLookupId from_name
; (wrap1, from_ty) <- topInstantiate (LiteralOrigin lit) (idType from_id)
@@ -781,9 +783,10 @@ tcInferOverLit lit@(OverLit { ol_val = val
from_expr = mkHsWrap (wrap2 <.> wrap1) $
HsVar noExtField (L loc from_id)
witness = HsApp noExtField (L (l2l loc) from_expr) lit_expr
- lit' = lit { ol_ext = OverLitTc { ol_rebindable = rebindable
- , ol_witness = witness
- , ol_type = res_ty } }
+ lit' = OverLit { ol_val = val
+ , ol_ext = OverLitTc { ol_rebindable = rebindable
+ , ol_witness = witness
+ , ol_type = res_ty } }
; return (HsOverLit noExtField lit', res_ty) }
{- *********************************************************************
=====================================
compiler/GHC/Tc/Utils/Unify.hs
=====================================
@@ -305,7 +305,7 @@ Both ultimately handled by matchExpectedFunTys.
* For the Lambda case there are two sub-cases:
* An expression with a type signature: (\ @a x y -> blah) :: hs_ty
This is handled by `GHC.Tc.Gen.Head.tcExprWithSig`, which kind-checks
- the signature and hands off to `tcExprPolyCheck` vai `tcPolyLExprSig`
+ the signature and hands off to `tcExprPolyCheck` via `tcPolyLExprSig`.
Note that the foralls at the top of hs_ty scope over the expression.
* A higher order call: h e, where h :: poly_ty -> blah
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/03a8158bc65b0f19ad9b950c3b911c2e93ecea28
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/03a8158bc65b0f19ad9b950c3b911c2e93ecea28
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20241216/56974c2d/attachment-0001.html>
More information about the ghc-commits
mailing list