[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