[Git][ghc/ghc][wip/T25029] More wibbles

Simon Peyton Jones (@simonpj) gitlab at gitlab.haskell.org
Sat Aug 3 17:00:25 UTC 2024



Simon Peyton Jones pushed to branch wip/T25029 at Glasgow Haskell Compiler / GHC


Commits:
f324f6bc by Simon Peyton Jones at 2024-08-03T18:00:02+01:00
More wibbles

- - - - -


3 changed files:

- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Dict.hs


Changes:

=====================================
compiler/GHC/Core/InstEnv.hs
=====================================
@@ -787,8 +787,11 @@ GHC's specialiser relies on the Coherence Assumption: that if
       d1 :: C tys
       d2 :: C tys
 then the dictionary d1 can be used in place of d2 and vice versa; it is as if
-(C tys) is a singleton type.  How do we guarantee this?  Let's use this
-example
+(C tys) is a singleton type.  If d1 and d2 are interchangeable, we say that
+they constitute /canonical evidence/ for (C tys).  We have a special data type,
+`CanonoicalEvidence`, for recording whether evidence is canonical.
+
+Let's use this example
   class C a where { op :: a -> Int }
   instance                     C [a]         where {...}   -- (I1)
   instance {-# OVERLAPPING #-} C [Int]       where {...}   -- (I2)
@@ -807,7 +810,7 @@ example
   programmer can contrive, with some effort), all bets are off; we really
   can't make any guarantees at all.
 
-* But what about [W] C [b], which might arise from
+* But what about [W] C [b]? This might arise from
      risky :: b -> Int
      risky x = op [x]
   We can't pick (I2) because `b` is not Int. But if we pick (I1), and later
@@ -1019,7 +1022,8 @@ data LookupInstanceErrReason =
 
 -- | `CanonicalEvidence` says whether a piece of evidence has a singleton type;
 -- For example, given (d1 :: C Int), will any other (d2 :: C Int) do equally well?
--- See Note [Desugaring non-canonical evidence] in GHC.HsToCore.Binds
+-- See Note [Coherence and specialisation: overview] above, and
+-- Note [Desugaring non-canonical evidence] in GHC.HsToCore.Binds
 data CanonicalEvidence
   = EvCanonical
   | EvNonCanonical


=====================================
compiler/GHC/Tc/Solver.hs
=====================================
@@ -740,12 +740,14 @@ tryCtDefaultingStrategy
 defaultExceptionContext :: CtDefaultingStrategy
 defaultExceptionContext ct
   | ClassPred cls tys <- classifyPredType (ctPred ct)
-  , Just {} <- isExceptionContextPred cls tys
+  , isJust (isExceptionContextPred cls tys)
   = do { warnTcS $ TcRnDefaultedExceptionContext (ctLoc ct)
        ; empty_ec_id <- lookupId emptyExceptionContextName
        ; let ev = ctEvidence ct
              ev_tm = mkEvCast (Var empty_ec_id) (wrapIP (ctEvPred ev))
-       ; setEvBindIfWanted ev EvNonCanonical ev_tm
+       ; setEvBindIfWanted ev EvCanonical ev_tm
+         -- EvCanonical: see Note [CallStack and ExecptionContext hack]
+         --              in GHC.Tc.Solver.Dict
        ; return True }
   | otherwise
   = return False


=====================================
compiler/GHC/Tc/Solver/Dict.hs
=====================================
@@ -189,11 +189,23 @@ solveCallStack ev ev_cs
   -- `IP ip CallStack`. See Note [Overview of implicit CallStacks]
   = do { cs_tm <- evCallStack ev_cs
        ; let ev_tm = mkEvCast cs_tm (wrapIP (ctEvPred ev))
-       ; setEvBindIfWanted ev EvNonCanonical ev_tm }
-
-
-{- Note [Shadowing of implicit parameters]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+       ; setEvBindIfWanted ev EvCanonical ev_tm }
+         -- EvCanonical: see Note [CallStack and ExecptionContext hack]
+
+{- Note [CallStack and ExecptionContext hack]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It isn't really right thta we treat CallStack and ExceptionContext dictionaries
+as canonical, in the sensse of Note [Coherence and specialisation: overview].
+They definitely are not!
+
+But if we use EvNonCanonical here we get lots of
+    nospec (error @Int) dict  string
+(since `error` takes a HasCallStack dict), and that isn't bottomng  (at least not
+without extra work)  So, hackily, we just say that HasCallStack and ExceptionContext
+are canonical, even though they aren't really.
+
+Note [Shadowing of implicit parameters]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 When we add a new /given/ implicit parameter to the inert set, it /replaces/
 any existing givens for the same implicit parameter.  This makes a difference
 in two places:



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f324f6bcc6980f7ef141dd6114a00c2730eb4145

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f324f6bcc6980f7ef141dd6114a00c2730eb4145
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/20240803/c6df2271/attachment-0001.html>


More information about the ghc-commits mailing list