[Git][ghc/ghc][wip/T23070-dicts] Documentation changes only

Simon Peyton Jones (@simonpj) gitlab at gitlab.haskell.org
Thu May 18 16:46:03 UTC 2023



Simon Peyton Jones pushed to branch wip/T23070-dicts at Glasgow Haskell Compiler / GHC


Commits:
84258bdc by Simon Peyton Jones at 2023-05-18T17:47:47+01:00
Documentation changes only

- - - - -


2 changed files:

- compiler/GHC/Tc/Errors/Hole.hs
- compiler/GHC/Tc/Solver/Dict.hs


Changes:

=====================================
compiler/GHC/Tc/Errors/Hole.hs
=====================================
@@ -989,7 +989,7 @@ tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $
           -> do { traceTc "}" empty
                 ; return (True, wrap) }
 
-          | checkInsoluble wanted
+          | checkInsoluble wanted -- See Note [Fast path for tcCheckHoleFit]
           -> return (False, wrap)
 
           | otherwise
@@ -1001,7 +1001,7 @@ tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $
                   -- Note [Checking hole fits]
                 ; let wrapInImpls cts = foldl (flip (setWCAndBinds fresh_binds)) cts th_implics
                       final_wc  = wrapInImpls $ addSimples wanted $
-                                                           mapBag mkNonCanonical cloned_relevants
+                                  mapBag mkNonCanonical cloned_relevants
                   -- We add the cloned relevants to the wanteds generated
                   -- by the call to tcSubType_NC, for details, see
                   -- Note [Relevant constraints]. There's no need to clone
@@ -1022,7 +1022,26 @@ tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $
     setWCAndBinds binds imp wc
       = mkImplicWC $ unitBag $ imp { ic_wanted = wc , ic_binds = binds }
 
+{- Note [Fast path for tcCheckHoleFit]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In `tcCheckHoleFit` we compare (with `tcSubTypeSigma`) the type of the hole
+with the type of zillions of in-scope functions, to see which would "fit".
+Most of these checks fail!  They generate obviously-insoluble constraints.
+For these very-common cases we don't want to crank up the full constraint
+solver.  It's much more efficient to do a quick-and-dirty check for insolubility.
+
+Now, `tcSubTypeSigma` uses the on-the-fly unifier in GHC.Tc.Utils.Unify,
+it has already done the dirt-simple unification. So our quick-and-dirty
+check can simply look for constraints like (Int ~ Bool).  We don't need
+to worry about (Maybe Int ~ Maybe Bool).
+
+The quick-and-dirty check is in `checkInsoluble`. It can make a big
+difference: For test hard_hole_fits, compile-time allocation goes down by 37%!
+-}
+
+
 checkInsoluble :: WantedConstraints -> Bool
+-- See Note [Fast path for tcCheckHoleFit]
 checkInsoluble (WC { wc_simple = simples })
   = any is_insol simples
   where
@@ -1031,6 +1050,8 @@ checkInsoluble (WC { wc_simple = simples })
                     _              -> False
 
 definitelyNotEqual :: Role -> TcType -> TcType -> Bool
+-- See Note [Fast path for tcCheckHoleFit]
+-- Specifically, does not need to recurse under type constructors
 definitelyNotEqual r t1 t2
   = go t1 t2
   where
@@ -1048,4 +1069,4 @@ definitelyNotEqual r t1 t2
     go_tc tc1 (TyConApp tc2 _) | isGenerativeTyCon tc2 r = tc1 /= tc2
     go_tc _ (FunTy {})    = True
     go_tc _ (ForAllTy {}) = True
-    go_tc _ _ = False
\ No newline at end of file
+    go_tc _ _ = False


=====================================
compiler/GHC/Tc/Solver/Dict.hs
=====================================
@@ -298,6 +298,87 @@ I can think of two ways to fix this:
 *                                                                               *
 ****************************************************************************** -}
 
+{- Note [Solving equality classes]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider (~), which behaves as if it was defined like this:
+  class a ~# b => a ~ b
+  instance a ~# b => a ~ b
+There are two more similar "equality classes" like this.  The full list is
+  * (~)         eqTyCon
+  * (~~)        heqTyCon
+  * Coercible   coercibleTyCon
+(See Note [The equality types story] in GHC.Builtin.Types.Prim.)
+
+(EQC1) For Givens, when expanding the superclasses of a equality class,
+  we can /replace/ the constraint with its superclasses (which, remember, are
+  equally powerful) rather than /adding/ them. This can make a huge difference.
+  Consider T17836, which has a constraint like
+      forall b,c. a ~ (b,c) =>
+        forall d,e. c ~ (d,e) =>
+          ...etc...
+  If we just /add/ the superclasses of [G] g1:a ~ (b,c), we'll put
+  [G] g1:(a~(b,c)) in the inert set and emit [G] g2:a ~# (b,c).  That will
+  kick out g1, and it'll be re-inserted as [G] g1':(b,c)~(b,c) which does
+  no good to anyone.  When the implication is deeply nested, this has
+  quadratic cost, and no benefit.  Just replace!
+
+  (This can have a /big/ effect: test T17836 involves deeply-nested GADT
+  pattern matching. Its compile-time allocation decreased by 40% when
+  I added the "replace" rather than "add" semantics.)
+
+(EQC2) Faced with [W] t1 ~ t2, it's always OK to reduce it to [W] t1 ~# t2,
+  without worrying about Note [Instance and Given overlap].  Why?  Because
+  if we had [G] s1 ~ s2, then we'd get the superclass [G] s1 ~# s2, and
+  so the reduction of the [W] constraint does not risk losing any solutions.
+
+  On the other hand, it can be fatal to /fail/ to reduce such equalities
+  on the grounds of Note [Instance and Given overlap], because many good
+  things flow from [W] t1 ~# t2.
+
+Conclusion: we have a special solver pipeline for equality-class constraints,
+`solveEqualityDict`.  It aggressively decomposes the boxed equality constraint
+into an unboxed coercion, both for Givens and Wanteds, and /replaces/ the
+boxed equality constraint with the unboxed one, so that the inert set never
+contains the boxed one.
+
+Note [Solving tuple constraints]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+I tried treating tuple constraints, such as (% Eq a, Show a %), rather like
+equality-class constraints (see Note [Solving equality classes]). That is, by
+eagerly decomposing tuple-constraints into their component (Eq a) and (Show a).
+
+But discarding the tuple Given (which "replacing" does) means that
+we may have to reconstruct it for a recursive call, and the optimiser isn't
+quite clever enough to figure that out: see #10359 and its test case; and #23398.
+This is less pressing for equality classes because they have to be unpacked
+strictly, so CSE-ing away the reconstruction works fine.
+
+
+(NC2) Because of this replacement, we don't need do the fancy footwork
+  of Note [Solving superclass constraints], so the computation of `sc_loc`
+  in `mk_strict_superclasses` can be simpler.
+
+  For tuple predicates, this matters, because their size can be large,
+  and we don't want to add a big class to the size of the dictionaries
+  in the chain. When we get down to a base predicate, we'll include
+  its size. See #10335
+
+And less obviously to:
+
+* Tuple classes.  For reasons described in GHC.Tc.Solver.Types
+  Note [Shadowing of implicit parameters], we may have a constraint
+     [W] (?x::Int, C a)
+  with an exactly-matching Given constraint.  We must decompose this
+  tuple and solve the components separately, otherwise we won't solve
+  it at all!  It is perfectly safe to decompose it, because again the
+  superclasses invert the instance;  e.g.
+      class (c1, c2) => (% c1, c2 %)
+      instance (c1, c2) => (% c1, c2 %)
+  Example in #14218
+
+Examples: T5853, T10432, T5315, T9222, T2627b, T3028b
+-}
+
 solveEqualityDict :: CtEvidence -> Class -> [Type] -> SolverStage Void
 -- Precondition: (isEqualityClass cls) True, so cls is (~), (~~), or Coercible
 solveEqualityDict ev cls tys



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

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/84258bdcc5ca417b58aaeb8dc2058b42e3ca0e65
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/20230518/3c0f5781/attachment-0001.html>


More information about the ghc-commits mailing list