[Git][ghc/ghc][wip/T25148] Resolve ambiguous method-bound type variables in vanilla defaults and GND

Ryan Scott (@RyanGlScott) gitlab at gitlab.haskell.org
Tue Sep 24 12:21:32 UTC 2024



Ryan Scott pushed to branch wip/T25148 at Glasgow Haskell Compiler / GHC


Commits:
b0f71f0a by Ryan Scott at 2024-09-24T08:20:55-04:00
Resolve ambiguous method-bound type variables in vanilla defaults and GND

When defining an instance of a class with a "vanilla" default, such as in the
following example (from #14266):

```hs
class A t where
  f :: forall x m. Monoid x => t m -> m
  f = <blah>

instance A []
```

We have to reckon with the fact that the type of `x` (bound by the type
signature for the `f` method) is ambiguous. If we don't deal with the ambiguity
somehow, then when we generate the following code:

```hs
instance A [] where
  f = $dmf @[] -- NB: the type of `x` is still ambiguous
```

Then the generated code will not typecheck. (Issue #25148 is a more recent
example of the same problem.)

To fix this, we bind the type variables from the method's original type
signature using `TypeAbstractions` and instantiate `$dmf` with them using
`TypeApplications`:

```hs
instance A [] where
  f @x @m = $dmf @[] @x @m -- `x` is no longer ambiguous
```

Note that we only do this for vanilla defaults and not for generic defaults
(i.e., defaults using `DefaultSignatures`). For the full details, see `Note
[Default methods in instances] (Wrinkle: Ambiguous types from vanilla method
type signatures)`.

The same problem arose in the code generated by `GeneralizedNewtypeDeriving`,
as we also fix it here using the same technique. This time, we can take
advantage of the fact that `GeneralizedNewtypeDeriving`-generated code
_already_ brings method-bound type variables into scope via `TypeAbstractions`
(after !13190), so it is very straightforward to visibly apply the type
variables on the right-hand sides of equations. See `Note [GND and ambiguity]`.

Fixes #14266. Fixes #25148.

- - - - -


15 changed files:

- compiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- docs/users_guide/exts/default_signatures.rst
- testsuite/tests/deriving/should_compile/T14578.stderr
- testsuite/tests/deriving/should_compile/T14682.stderr
- testsuite/tests/deriving/should_compile/T17240.stderr
- + testsuite/tests/deriving/should_compile/T25148c.hs
- testsuite/tests/deriving/should_compile/all.T
- testsuite/tests/deriving/should_compile/deriving-inferred-ty-arg.stderr
- testsuite/tests/generics/T10604/T10604_deriving.stderr
- + testsuite/tests/generics/T14266.hs
- + testsuite/tests/generics/T25148a.hs
- + testsuite/tests/generics/T25148b.hs
- testsuite/tests/generics/all.T
- testsuite/tests/unsatisfiable/UnsatDefault.stderr


Changes:

=====================================
compiler/GHC/Tc/Deriv/Generate.hs
=====================================
@@ -1699,12 +1699,16 @@ coercing from.  So from, say,
   instance C a <rep-ty> => C a (T x) where
     op @c = coerce @(a -> [<rep-ty>] -> c -> Int)
                    @(a -> [T x]      -> c -> Int)
-                   op
+                   (op @c)
 
 In addition to the type applications, we also use a type abstraction to bring
-the method-bound variable `c` into scope over the two type applications.
-See Note [GND and QuantifiedConstraints] for more information on why this
-is important.
+the method-bound variable `c` into scope. We do this for two reasons:
+
+* We need to bring `c` into scope over the two type applications to `coerce`.
+  See Note [GND and QuantifiedConstraints] for more information on why this
+  is important.
+* We need to bring `c` into scope over the type application to `op`. See
+  Note [GND and ambiguity] for more information on why this is important.
 
 (In the surface syntax, only specified type variables can be used in type
 abstractions. Since a method signature could contain both specified and
@@ -1737,6 +1741,27 @@ However, to allow VTA with polytypes we must switch on
 -XImpredicativeTypes locally in GHC.Tc.Deriv.genInst.
 See #8503 for more discussion.
 
+The following Notes describe further nuances of GeneralizedNewtypeDeriving:
+
+-----
+-- In GHC.Tc.Deriv
+-----
+
+* Note [Newtype deriving]
+* Note [Newtype representation]
+* Note [Recursive newtypes]
+* Note [Determining whether newtype-deriving is appropriate]
+* Note [GND and associated type families]
+* Note [Bindings for Generalised Newtype Deriving]
+
+-----
+-- In GHC.Tc.Deriv.Generate
+-----
+
+* Note [Newtype-deriving trickiness]
+* Note [GND and QuantifiedConstraints]
+* Note [GND and ambiguity]
+
 Note [Inferred invisible patterns]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Consider the following:
@@ -1915,27 +1940,68 @@ coerce with a polytype, and we can only do that with VTA or QuickLook.
 Note [GND and ambiguity]
 ~~~~~~~~~~~~~~~~~~~~~~~~
 We make an effort to make the code generated through GND be robust w.r.t.
-ambiguous type variables. As one example, consider the following example
-(from #15637):
+ambiguous type variables. Here are a couple of examples to illustrate this:
+
+* In this example (from #15637), the class-bound type variable `a` is ambiguous
+  in the type of `f`:
 
-  class C a where f :: String
-  instance C () where f = "foo"
-  newtype T = T () deriving C
+    class C a where
+      f :: String    -- f :: forall a. C a => String
+    instance C ()
+      where f = "foo"
+    newtype T = T ()
+      deriving C
 
-A naïve attempt and generating a C T instance would be:
+  A naïve attempt and generating a C T instance would be:
 
-  instance C T where
-    f = coerce @String @String f
+    instance C T where
+      f = coerce @String @String f
 
-This isn't going to typecheck, however, since GHC doesn't know what to
-instantiate the type variable `a` with in the call to `f` in the method body.
-(Note that `f :: forall a. String`!) To compensate for the possibility of
-ambiguity here, we explicitly instantiate `a` like so:
+  This isn't going to typecheck, however, since GHC doesn't know what to
+  instantiate the type variable `a` with in the call to `f` in the method body.
+  (Note that `f :: forall a. String`!) To compensate for the possibility of
+  ambiguity here, we explicitly instantiate `a` like so:
 
-  instance C T where
-    f = coerce @String @String (f @())
+    instance C T where
+      f = coerce @String @String (f @())
 
-All better now.
+  All better now.
+
+* In this example (adapted from #25148), the ambiguity arises from the `n`
+  type variable bound by the type signature for `fact1`:
+
+    class Facts a where
+      fact1 :: forall n. Proxy a -> Dict (0 <= n)
+    newtype T a = MkT a
+      deriving newtype Facts
+
+  When generating code for the derived `Facts` instance, we must use a type
+  abstraction to bring `n` into scope over the type applications to `coerce`
+  (see Note [Newtype-deriving instances] for more why this is needed). A first
+  attempt at generating the instance would be:
+
+    instance Facts a => Facts (T a) where
+      fact1 @n = coerce @(Proxy    a  -> Dict (0 <= n))
+                        @(Proxy (T a) -> Dict (0 <= n))
+                        (fact1 @a)
+
+  This still won't typecheck, however, as GHC doesn't know how to instantiate
+  `n` in the call to `fact1 @a`. To compensate for the possibility of ambiguity
+  here, we also visibly apply `n` in the call to `fact1` on the RHS:
+
+    instance Facts a => Facts (T a) where
+      fact1 @n = coerce @(Proxy    a  -> Dict (0 <= n))
+                        @(Proxy (T a) -> Dict (0 <= n))
+                        (fact1 @a @n) -- Note the @n here!
+
+  This takes advantage of the fact that we *already* need to bring `n` into
+  scope using a type abstraction, and so we are able to use it both for
+  instantiating the call to `coerce` and instantiating the call to `fact1`.
+
+  Note that we use this same type abstractions-based approach for resolving
+  ambiguity in default methods, as described in Note [Default methods in
+  instances] (Wrinkle: Ambiguous types from vanilla method type signatures) in
+  GHC.Tc.TyCl.Instance.
 -}
 
 gen_Newtype_binds :: SrcSpan
@@ -2002,11 +2068,16 @@ gen_Newtype_binds loc' cls inst_tvs inst_tys rhs_ty
                                       `nlHsAppType`     to_tau
                                       `nlHsApp`         meth_app
 
-        -- The class method, applied to all of the class instance types
-        -- (including the representation type) to avoid potential ambiguity.
-        -- See Note [GND and ambiguity]
+        -- The class method, applied to the following types to avoid potential
+        -- ambiguity:
+        --
+        -- 1. All of the class instance types (including the representation type)
+        -- 2. All of `to_tvbs`
+        --
+        -- See Note [GND and ambiguity].
         meth_app = foldl' nlHsAppType (nlHsVar meth_RDR) $
-                   filterOutInferredTypes (classTyCon cls) underlying_inst_tys
+                   filterOutInferredTypes (classTyCon cls) underlying_inst_tys ++ -- (1)
+                   [mkTyVarTy tv | Bndr tv spec <- to_tvbs, spec /= InferredSpec] -- (2)
                      -- Filter out any inferred arguments, since they can't be
                      -- applied with visible type application.
 


=====================================
compiler/GHC/Tc/TyCl/Instance.hs
=====================================
@@ -1846,8 +1846,8 @@ tcMethods skol_info dfun_id clas tyvars dfun_ev_vars inst_tys
                    meth_bind = mkVarBind meth_id $ mkLHsWrap lam_wrapper meth_rhs
              ; return (meth_id, meth_bind, Nothing) }
 
-      Just (dm_name, _) ->
-        do { (meth_bind, inline_prags) <- mkDefMethBind inst_loc dfun_id clas sel_id dm_name
+      Just (dm_name, dm_spec) ->
+        do { (meth_bind, inline_prags) <- mkDefMethBind inst_loc dfun_id clas sel_id dm_name dm_spec
            ; tcMethodBody skol_info clas tyvars dfun_ev_vars inst_tys
                           dfun_ev_binds is_derived hs_sig_fn
                           spec_inst_prags inline_prags
@@ -2194,14 +2194,15 @@ mk_meth_spec_prags meth_id spec_inst_prags spec_prags_for_me
 
 
 mkDefMethBind :: SrcSpan -> DFunId -> Class -> Id -> Name
+              -> DefMethSpec Type
               -> TcM (LHsBind GhcRn, [LSig GhcRn])
 -- The is a default method (vanailla or generic) defined in the class
--- So make a binding   op = $dmop @t1 @t2
--- where $dmop is the name of the default method in the class,
--- and t1,t2 are the instance types.
--- See Note [Default methods in instances] for why we use
--- visible type application here
-mkDefMethBind loc dfun_id clas sel_id dm_name
+-- So make a binding   op @m1 @m2 @m3 = $dmop @i1 @i2 @m1 @m2 @m3
+-- where $dmop is the name of the default method in the class;
+-- i1 and t2 are the instance types; and m1, m2, and m3 are the type variables
+-- from the method's type signature. See Note [Default methods in instances] for
+-- why we use visible type application here.
+mkDefMethBind loc dfun_id clas sel_id dm_name dm_spec
   = do  { logger <- getLogger
         ; dm_id <- tcLookupId dm_name
         ; let inline_prag = idInlinePragma dm_id
@@ -2212,29 +2213,64 @@ mkDefMethBind loc dfun_id clas sel_id dm_name
                  -- Copy the inline pragma (if any) from the default method
                  -- to this version. Note [INLINE and default methods]
 
-              fn   = noLocA (idName sel_id)
-              visible_inst_tys = [ ty | (tcb, ty) <- tyConBinders (classTyCon clas) `zip` inst_tys
-                                      , tyConBinderForAllTyFlag tcb /= Inferred ]
-              rhs  = foldl' mk_vta (nlHsVar dm_name) visible_inst_tys
-              bind = L (noAnnSrcSpan loc)
-                    $ mkTopFunBind (Generated OtherExpansion SkipPmc) fn
-                        [mkSimpleMatch (mkPrefixFunRhs fn) (noLocA []) rhs]
-
         ; liftIO (putDumpFileMaybe logger Opt_D_dump_deriv "Filling in method body"
                    FormatHaskell
                    (vcat [ppr clas <+> ppr inst_tys,
-                          nest 2 (ppr sel_id <+> equals <+> ppr rhs)]))
+                          nest 2 (ppr bind)]))
 
        ; return (bind, inline_prags) }
   where
     (_, _, _, inst_tys) = tcSplitDFunTy (idType dfun_id)
+    (_, _, sel_tau) = tcSplitMethodTy (idType sel_id)
+    (sel_tvbs, _) = tcSplitForAllInvisTVBinders sel_tau
+
+    -- Compute the instance types to use in the visible type application. See
+    -- Note [Default methods in instances].
+    visible_inst_tys =
+      [ ty | (tcb, ty) <- tyConBinders (classTyCon clas) `zip` inst_tys
+           , tyConBinderForAllTyFlag tcb /= Inferred ]
+
+    visible_sel_tvbs =
+      case dm_spec of
+        -- When dealing with a vanilla default method, compute the type
+        -- variables from the method's type signature. That way, we can bind
+        -- them with TypeAbstractions (visible_sel_pats) and use them in the
+        -- visible type application (visible_sel_tys). See Note [Default methods
+        -- in instances] (Wrinkle: Ambiguous types from vanilla method type
+        -- signatures).
+        VanillaDM -> filter (\tvb -> binderFlag tvb /= InferredSpec) sel_tvbs
+        -- If we are dealing with a generic default method, on the other hand,
+        -- don't bother doing any of this. See Note [Default methods
+        -- in instances] (Wrinkle: Ambiguous types from generic default method
+        -- type signatures).
+        GenericDM {} -> []
+    visible_sel_pats = map mk_ty_pat visible_sel_tvbs
+    visible_sel_tys = map (mkTyVarTy . binderVar) visible_sel_tvbs
+
+    fn   = noLocA (idName sel_id)
+    rhs  = foldl' mk_vta (nlHsVar dm_name) $
+           visible_inst_tys ++ visible_sel_tys
+    bind = L (noAnnSrcSpan loc)
+          $ mkTopFunBind (Generated OtherExpansion SkipPmc) fn
+              [mkSimpleMatch (mkPrefixFunRhs fn) (noLocA visible_sel_pats) rhs]
+
+    mk_ty_pat :: VarBndr TyVar Specificity -> LPat GhcRn
+    mk_ty_pat (Bndr tv spec) =
+      noLocA $
+      InvisPat spec $
+      HsTP (HsTPRn [] [tyVarName tv] []) $
+      nlHsTyVar NotPromoted $
+      tyVarName tv
 
     mk_vta :: LHsExpr GhcRn -> Type -> LHsExpr GhcRn
     mk_vta fun ty = noLocA (HsAppType noExtField fun
-        (mkEmptyWildCardBndrs $ nlHsParTy $ noLocA $ XHsType ty))
+        (mkEmptyWildCardBndrs $ type_to_hs_type ty))
        -- NB: use visible type application
        -- See Note [Default methods in instances]
 
+    type_to_hs_type :: Type -> LHsType GhcRn
+    type_to_hs_type = parenthesizeHsType appPrec . noLocA . XHsType
+
 ----------------------
 derivBindCtxt :: Id -> Class -> [Type ] -> SDoc
 derivBindCtxt sel_id clas tys
@@ -2277,8 +2313,8 @@ From the class decl we get
    $dmfoo :: forall v x. Baz v x => x -> x
    $dmfoo y = <blah>
 
-Notice that the type is ambiguous.  So we use Visible Type Application
-to disambiguate:
+Notice that the type of `v` is ambiguous.  So we use Visible Type Application
+(VTA) to disambiguate:
 
    $dBazIntInt = MkBaz fooIntInt
    fooIntInt = $dmfoo @Int @Int
@@ -2291,6 +2327,151 @@ Historical note: before we had VTA we had to generate
 post-type-checked code, which took a lot more code, and didn't work for
 generic default methods.
 
+-----
+-- Wrinkle: Ambiguous types from vanilla method type signatures
+-----
+
+In the Bar example above, the ambiguity arises from `v`, a type variable
+arising from the class header. It is also possible for the ambiguity to arise
+from a type variable bound by the method's type signature itself (see #14266
+and #25148). For example:
+
+   class A t where
+      f :: forall x m. Monoid x => t m -> m
+      f = <blah>
+
+   instance A []
+
+The class declaration gives rise to the following default function:
+
+  $dmf :: forall t. A t => forall x m. Monoid x => t m -> m
+  $dmf = <blah>
+
+And the instance declaration gives rise to generated code that looks roughly
+like this:
+
+   instance A [] where
+      f = $dmf @[] ...
+
+In this example, it is not enough to use VTA to specify the type of `t`, since
+the type of `x` (bound by `f`'s type signature) is also ambiguous. We need to
+generate code that looks more like this:
+
+   instance A [] where
+      f = $dmf @[] @x @m
+
+But where should `x` and `m` be bound? It's tempting to use ScopedTypeVariables
+and InstanceSigs to accomplish this:
+
+   instance A [] where
+      f :: forall x m. Monoid x => [m] -> m
+      f = $dmf @[] @x @m
+
+GHC will reject this code, however, as the type signature for `f` will fail the
+subtype check for InstanceSigs:
+
+    • Could not deduce (Monoid x0)
+      from the context: Monoid x
+        bound by the type signature for:
+                   f :: forall x m. Monoid x => [m] -> m
+      The type variable ‘x0’ is ambiguous
+    • When checking that instance signature for ‘f’
+        is more general than its signature in the class
+        Instance sig: forall x m. Monoid x => [m] -> m
+           Class sig: forall x m. Monoid x => [m] -> m
+      In the instance declaration for ‘A []’
+
+See #17898. To avoid this problem, we instead bind `x` and `m` using
+TypeAbstractions:
+
+   instance A [] where
+      f @x @m = $dmf @[] @x @m
+
+This resolves the ambiguity and avoids the need for a subtype check. (We also
+use a similar trick for resolving ambiguity in GeneralizedNewtypeDeriving: see
+also Note [GND and ambiguity] in GHC.Tc.Deriv.Generate.)
+
+-----
+-- Wrinkle: Ambiguous types from generic default method type signatures
+-----
+
+Note that the approach described above (in Wrinkle: Ambiguous types from
+vanilla method type signatures) will only work for vanilla default methods and
+/not/ for generic default methods (i.e., methods using DefaultSignatures). This
+is because for vanilla default methods, the type of the generated $dm* function
+will always quantify the same type variables as the method's original type
+signature, in the same order and with the same specificities. For example, the
+type of the $dmf function will be:
+
+   $dmf :: forall t. A t => forall x m. Monoid x => t m -> m
+
+As such, it is guaranteed that the type variables from the method's original
+type signature will line up exactly with the type variables from the $dm*
+function (after instantiating all of the class variables):
+
+   instance A [] where
+      f @x @m = $dmf @[] @x @m
+
+We cannot guarantee this property for generic default methods, however. As
+such, we must be more conservative and generate code without instantiating any
+of the type variables bound by the method's type signature (only the type
+variables bound by the class header):
+
+   instance A [] where
+      f = $dmf @[]
+
+There are a number of reasons why we cannot reliably instantiate the type
+variables bound by a generic default method's type signature:
+
+* Default methods can quantify type variables in a different order, e.g.,
+
+    class A t where
+       f :: forall x m. Monoid x => t m -> m
+       default f :: forall m x. Monoid x => t m -> m
+       f = <blah>
+
+  Note that the default signature quantifies the type variables in the opposite
+  order from the method's original type signature. As such, the type of $dmf
+  will be:
+
+    $dmf :: forall t. A t => forall m x. Monoid x => t m -> m
+
+  Therefore, `f @x @m = $dmf @[] @x @m` would be incorrect. Nor would it be
+  straightforward to infer what the correct order of type variables should be.
+
+* Default methods can quantify a different number of type variables, e.g.,
+
+    class A t where
+       f :: forall x m. Monoid x => t m -> m
+       default f :: forall p q r m. C a t p q r => t m -> m
+       f = <blah>
+
+  This gives rise to:
+
+    $dmf :: forall t. A t => forall p q r m. C a t p q r => t m -> m
+
+  And thus generating `f @x @m = $dmf @[] @x @m` would be incorrect, for
+  similar reasons as in the example above.
+
+* Default methods can use different type variable specificities, e.g.,
+
+    class A t where
+       f :: forall x m. Monoid x => t m -> m
+       default f :: forall {x} m. Monoid x => t m -> m
+       f = <blah>
+
+  This gives rise to:
+
+    $dmf :: forall t. A t => forall {x} m. Monoid x => t m -> m
+
+  Therefore, generating `f @x @m = $dmf @[] @x @m` would be incorrect because
+  the `x` in the type of $dmf is inferred, so it is not eligible for visible
+  type application.
+
+As such, we do not bother trying to resolve the ambiguity of any method-bound
+type variables when dealing with generic defaults. This means that GHC won't be
+able to typecheck the default method examples above, but so be it.
+
 Note [INLINE and default methods]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Default methods need special case.  They are supposed to behave rather like


=====================================
docs/users_guide/exts/default_signatures.rst
=====================================
@@ -189,3 +189,15 @@ default type signatures.
 
   This works, but at the expense of changing ``p``'s behavior with respect to
   :ref:`visible-type-application`.
+
+- The default signature cannot use any ambiguous type variables. For example,
+  GHC will not permit instances of the following class: ::
+
+      class A t where
+        f :: forall x m. Monoid x => t m -> m
+        default :: forall x m. Monoid x => t m -> m
+        f = ...
+
+  Note that ``x`` is ambiguous, as none of the argument or result types
+  determine what type ``x`` should be when calling ``f``. GHC will reject
+  instances of ``A``, even if :extension:`AllowAmbiguousTypes` is enabled.


=====================================
testsuite/tests/deriving/should_compile/T14578.stderr
=====================================
@@ -28,7 +28,7 @@ Derived class instances:
             -> T14578.App (Data.Functor.Compose.Compose f g) a)
           @(b -> T14578.Wat f g a -> T14578.Wat f g a)
           (GHC.Internal.Base.stimes
-             @(T14578.App (Data.Functor.Compose.Compose f g) a))
+             @(T14578.App (Data.Functor.Compose.Compose f g) a) @b)
   
   instance GHC.Internal.Base.Functor f =>
            GHC.Internal.Base.Functor (T14578.App f) where
@@ -36,38 +36,38 @@ Derived class instances:
       = GHC.Prim.coerce
           @((a -> b) -> f a -> f b)
           @((a -> b) -> T14578.App f a -> T14578.App f b)
-          (GHC.Internal.Base.fmap @f)
+          (GHC.Internal.Base.fmap @f @a @b)
     (GHC.Internal.Base.<$) @a @b
       = GHC.Prim.coerce
           @(a -> f b -> f a) @(a -> T14578.App f b -> T14578.App f a)
-          ((GHC.Internal.Base.<$) @f)
+          ((GHC.Internal.Base.<$) @f @a @b)
   
   instance GHC.Internal.Base.Applicative f =>
            GHC.Internal.Base.Applicative (T14578.App f) where
     GHC.Internal.Base.pure @a
       = GHC.Prim.coerce
-          @(a -> f a) @(a -> T14578.App f a) (GHC.Internal.Base.pure @f)
+          @(a -> f a) @(a -> T14578.App f a) (GHC.Internal.Base.pure @f @a)
     (GHC.Internal.Base.<*>) @a @b
       = GHC.Prim.coerce
           @(f (a -> b) -> f a -> f b)
           @(T14578.App f (a -> b) -> T14578.App f a -> T14578.App f b)
-          ((GHC.Internal.Base.<*>) @f)
+          ((GHC.Internal.Base.<*>) @f @a @b)
     GHC.Internal.Base.liftA2 @a @b @c
       = GHC.Prim.coerce
           @((a -> b -> c) -> f a -> f b -> f c)
           @((a -> b -> c)
             -> T14578.App f a -> T14578.App f b -> T14578.App f c)
-          (GHC.Internal.Base.liftA2 @f)
+          (GHC.Internal.Base.liftA2 @f @a @b @c)
     (GHC.Internal.Base.*>) @a @b
       = GHC.Prim.coerce
           @(f a -> f b -> f b)
           @(T14578.App f a -> T14578.App f b -> T14578.App f b)
-          ((GHC.Internal.Base.*>) @f)
+          ((GHC.Internal.Base.*>) @f @a @b)
     (GHC.Internal.Base.<*) @a @b
       = GHC.Prim.coerce
           @(f a -> f b -> f a)
           @(T14578.App f a -> T14578.App f b -> T14578.App f a)
-          ((GHC.Internal.Base.<*) @f)
+          ((GHC.Internal.Base.<*) @f @a @b)
   
 
 Derived type family instances:
@@ -76,14 +76,14 @@ Derived type family instances:
 
 ==================== Filling in method body ====================
 GHC.Internal.Base.Semigroup [T14578.App f a]
-  GHC.Internal.Base.sconcat = GHC.Internal.Base.$dmsconcat
-                                @(T14578.App f a)
+  GHC.Internal.Base.sconcat
+    = GHC.Internal.Base.$dmsconcat @(T14578.App f a)
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Base.Semigroup [T14578.App f a]
-  GHC.Internal.Base.stimes = GHC.Internal.Base.$dmstimes
-                               @(T14578.App f a)
+  GHC.Internal.Base.stimes @b
+    = GHC.Internal.Base.$dmstimes @(T14578.App f a) @b
 
 


=====================================
testsuite/tests/deriving/should_compile/T14682.stderr
=====================================
@@ -90,121 +90,121 @@ Derived type family instances:
 
 ==================== Filling in method body ====================
 GHC.Internal.Show.Show [T14682.Foo]
-  GHC.Internal.Show.show = GHC.Internal.Show.$dmshow @(T14682.Foo)
+  GHC.Internal.Show.show = GHC.Internal.Show.$dmshow @T14682.Foo
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Show.Show [T14682.Foo]
-  GHC.Internal.Show.showList = GHC.Internal.Show.$dmshowList
-                                 @(T14682.Foo)
+  GHC.Internal.Show.showList
+    = GHC.Internal.Show.$dmshowList @T14682.Foo
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.dataCast1 = GHC.Internal.Data.Data.$dmdataCast1
-                                       @(T14682.Foo)
+  GHC.Internal.Data.Data.dataCast1 @t @c
+    = GHC.Internal.Data.Data.$dmdataCast1 @T14682.Foo @t @c
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.dataCast2 = GHC.Internal.Data.Data.$dmdataCast2
-                                       @(T14682.Foo)
+  GHC.Internal.Data.Data.dataCast2 @t @c
+    = GHC.Internal.Data.Data.$dmdataCast2 @T14682.Foo @t @c
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.gmapT = GHC.Internal.Data.Data.$dmgmapT
-                                   @(T14682.Foo)
+  GHC.Internal.Data.Data.gmapT
+    = GHC.Internal.Data.Data.$dmgmapT @T14682.Foo
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.gmapQl = GHC.Internal.Data.Data.$dmgmapQl
-                                    @(T14682.Foo)
+  GHC.Internal.Data.Data.gmapQl @r @r'
+    = GHC.Internal.Data.Data.$dmgmapQl @T14682.Foo @r @r'
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.gmapQr = GHC.Internal.Data.Data.$dmgmapQr
-                                    @(T14682.Foo)
+  GHC.Internal.Data.Data.gmapQr @r @r'
+    = GHC.Internal.Data.Data.$dmgmapQr @T14682.Foo @r @r'
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.gmapQ = GHC.Internal.Data.Data.$dmgmapQ
-                                   @(T14682.Foo)
+  GHC.Internal.Data.Data.gmapQ @u
+    = GHC.Internal.Data.Data.$dmgmapQ @T14682.Foo @u
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.gmapQi = GHC.Internal.Data.Data.$dmgmapQi
-                                    @(T14682.Foo)
+  GHC.Internal.Data.Data.gmapQi @u
+    = GHC.Internal.Data.Data.$dmgmapQi @T14682.Foo @u
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.gmapM = GHC.Internal.Data.Data.$dmgmapM
-                                   @(T14682.Foo)
+  GHC.Internal.Data.Data.gmapM @m
+    = GHC.Internal.Data.Data.$dmgmapM @T14682.Foo @m
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.gmapMp = GHC.Internal.Data.Data.$dmgmapMp
-                                    @(T14682.Foo)
+  GHC.Internal.Data.Data.gmapMp @m
+    = GHC.Internal.Data.Data.$dmgmapMp @T14682.Foo @m
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Data.Data.Data [T14682.Foo]
-  GHC.Internal.Data.Data.gmapMo = GHC.Internal.Data.Data.$dmgmapMo
-                                    @(T14682.Foo)
+  GHC.Internal.Data.Data.gmapMo @m
+    = GHC.Internal.Data.Data.$dmgmapMo @T14682.Foo @m
 
 
 
 ==================== Filling in method body ====================
 GHC.Classes.Eq [T14682.Foo]
-  GHC.Classes./= = GHC.Classes.$dm/= @(T14682.Foo)
+  (GHC.Classes./=) = GHC.Classes.$dm/= @T14682.Foo
 
 
 
 ==================== Filling in method body ====================
 GHC.Classes.Ord [T14682.Foo]
-  GHC.Classes.max = GHC.Classes.$dmmax @(T14682.Foo)
+  GHC.Classes.max = GHC.Classes.$dmmax @T14682.Foo
 
 
 
 ==================== Filling in method body ====================
 GHC.Classes.Ord [T14682.Foo]
-  GHC.Classes.min = GHC.Classes.$dmmin @(T14682.Foo)
+  GHC.Classes.min = GHC.Classes.$dmmin @T14682.Foo
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Ix.Ix [T14682.Foo]
-  GHC.Internal.Ix.index = GHC.Internal.Ix.$dmindex @(T14682.Foo)
+  GHC.Internal.Ix.index = GHC.Internal.Ix.$dmindex @T14682.Foo
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Ix.Ix [T14682.Foo]
-  GHC.Internal.Ix.rangeSize = GHC.Internal.Ix.$dmrangeSize
-                                @(T14682.Foo)
+  GHC.Internal.Ix.rangeSize
+    = GHC.Internal.Ix.$dmrangeSize @T14682.Foo
 
 
 
 ==================== Filling in method body ====================
 GHC.Internal.Ix.Ix [T14682.Foo]
-  GHC.Internal.Ix.unsafeRangeSize = GHC.Internal.Ix.$dmunsafeRangeSize
-                                      @(T14682.Foo)
+  GHC.Internal.Ix.unsafeRangeSize
+    = GHC.Internal.Ix.$dmunsafeRangeSize @T14682.Foo
 
 


=====================================
testsuite/tests/deriving/should_compile/T17240.stderr
=====================================
@@ -31,12 +31,12 @@ Derived type family instances:
 
 ==================== Filling in method body ====================
 GHC.Classes.Eq [T17240.Nullary]
-  GHC.Classes./= = GHC.Classes.$dm/= @(T17240.Nullary)
+  (GHC.Classes./=) = GHC.Classes.$dm/= @T17240.Nullary
 
 
 
 ==================== Filling in method body ====================
 GHC.Classes.Eq [T17240.T]
-  GHC.Classes./= = GHC.Classes.$dm/= @(T17240.T)
+  (GHC.Classes./=) = GHC.Classes.$dm/= @T17240.T
 
 


=====================================
testsuite/tests/deriving/should_compile/T25148c.hs
=====================================
@@ -0,0 +1,17 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DerivingStrategies #-}
+module T25148c where
+
+import Data.Kind
+import Data.Proxy
+import GHC.TypeLits
+
+data Dict :: Constraint -> Type where
+  Dict :: c => Dict c
+
+class Facts a where
+  fact1 :: forall n. Proxy a -> Dict (0 <= n)
+
+newtype T a = MkT a
+  deriving newtype Facts


=====================================
testsuite/tests/deriving/should_compile/all.T
=====================================
@@ -150,4 +150,5 @@ test('T15798c', normal, compile, [''])
 test('T24955a', normal, compile, [''])
 test('T24955b', normal, compile, [''])
 test('T24955c', normal, compile, [''])
+test('T25148c', normal, compile, [''])
 test('deriving-inferred-ty-arg', normal, compile, ['-ddump-deriv -dsuppress-uniques'])


=====================================
testsuite/tests/deriving/should_compile/deriving-inferred-ty-arg.stderr
=====================================
@@ -8,7 +8,7 @@ Derived class instances:
           @(GHC.Internal.Data.Functor.Const.Const a b)
           @(GHC.Internal.Data.Functor.Const.Const
               (DerivingInferredTyArg.T a) b)
-          (DerivingInferredTyArg.m @a)
+          (DerivingInferredTyArg.m @a @b)
   
   instance DerivingInferredTyArg.C2 a =>
            DerivingInferredTyArg.C2 (DerivingInferredTyArg.T a) where
@@ -26,7 +26,7 @@ Derived class instances:
           @(GHC.Internal.Data.Functor.Const.Const a p)
           @(GHC.Internal.Data.Functor.Const.Const
               (DerivingInferredTyArg.T a) p)
-          (DerivingInferredTyArg.m3 @a)
+          (DerivingInferredTyArg.m3 @a @b)
   
   instance DerivingInferredTyArg.C4 a =>
            DerivingInferredTyArg.C4 (DerivingInferredTyArg.T a) where
@@ -35,7 +35,7 @@ Derived class instances:
           @(GHC.Internal.Data.Functor.Const.Const a p)
           @(GHC.Internal.Data.Functor.Const.Const
               (DerivingInferredTyArg.T a) p)
-          (DerivingInferredTyArg.m4 @a)
+          (DerivingInferredTyArg.m4 @a @b)
   
   instance DerivingInferredTyArg.C5 a =>
            DerivingInferredTyArg.C5 (DerivingInferredTyArg.T a) where


=====================================
testsuite/tests/generics/T10604/T10604_deriving.stderr
=====================================
@@ -542,7 +542,7 @@ Derived type family instances:
 
 ==================== Filling in method body ====================
 GHC.Internal.Base.Functor [T10604_deriving.Proxy @(*)]
-  GHC.Internal.Base.<$ = GHC.Internal.Base.$dm<$
-                           @(T10604_deriving.Proxy @(*))
+  (GHC.Internal.Base.<$) @a @b
+    = GHC.Internal.Base.$dm<$ @(T10604_deriving.Proxy @(*)) @a @b
 
 


=====================================
testsuite/tests/generics/T14266.hs
=====================================
@@ -0,0 +1,7 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+module T14266 where
+
+class A t where
+  f :: forall x m. Monoid x => t m -> m
+  f = undefined
+instance A []


=====================================
testsuite/tests/generics/T25148a.hs
=====================================
@@ -0,0 +1,24 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE DataKinds #-}
+module T25148a where
+
+import Data.Kind
+import Data.Proxy
+import GHC.TypeLits
+import Unsafe.Coerce
+
+data Dict :: Constraint -> Type where
+  Dict :: c => Dict c
+
+fact0 :: forall n a. Proxy a -> Dict (0 <= n)
+fact0 _ = unsafeCoerce (Dict :: Dict (0 <= 0))
+
+class Facts a where
+  fact1 :: forall n. Proxy a -> Dict (0 <= n)
+  fact1 _ = unsafeCoerce (Dict :: Dict (0 <= 0))
+instance Facts ()
+
+class Facts' a where
+  fact' :: forall n. Proxy n -> Proxy a -> Dict (0 <= n)
+  fact' _ _ = unsafeCoerce (Dict :: Dict (0 <= 0))
+instance Facts' ()


=====================================
testsuite/tests/generics/T25148b.hs
=====================================
@@ -0,0 +1,42 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE TypeFamilies #-}
+module T25148b where
+
+import Data.Functor.Const
+import Data.Proxy
+
+class Monoid a => C a where
+  m :: forall {k} (b :: k). Const a b
+  m = Const mempty
+
+class Monoid a => C2 a where
+  m2 :: forall {k} {b :: k}. Const a b
+  m2 = Const mempty
+
+class Monoid a => C3 a where
+  m3 :: forall {k} (b :: k) {p :: Proxy b}. Const a p
+  m3 = Const mempty
+
+data VisProxy k (a :: k) = VisProxy
+
+class Monoid a => C4 a where
+  m4 :: forall {k} (b :: k) {p :: VisProxy k b}. Const a p
+  m4 = Const mempty
+
+type family Any :: k
+
+class Monoid a => C5 a where
+  m5 :: Proxy Any -> a
+  m5 _ = mempty
+
+-----
+
+data T = MkT
+  deriving anyclass (C, C2, C3, C4, C5)
+
+instance Semigroup T where
+  _ <> _ = MkT
+instance Monoid T where
+  mempty = MkT


=====================================
testsuite/tests/generics/all.T
=====================================
@@ -45,5 +45,8 @@ test('T10361b', normal, compile, [''])
 test('T11358', normal, compile_and_run, [''])
 test('T12220', normal, compile, [''])
 test('T15012', [extra_files(['T15012.hs', 'T15012a.hs'])], makefile_test, [])
+test('T14266', normal, compile, [''])
 test('T19819', normal, compile_and_run, [''])
 test('T21185', normal, compile, [''])
+test('T25148a', normal, compile, [''])
+test('T25148b', normal, compile, [''])


=====================================
testsuite/tests/unsatisfiable/UnsatDefault.stderr
=====================================
@@ -1,6 +1,6 @@
-
 UnsatDefault.hs:14:10: error: [GHC-22250]
     • Please define the method manually. You can try...
-    • In the expression: UnsatDefault.$dmmethod @(Int)
-      In an equation for ‘method’: method = UnsatDefault.$dmmethod @(Int)
+    • In the expression: UnsatDefault.$dmmethod @Int
+      In an equation for ‘method’: method = UnsatDefault.$dmmethod @Int
       In the instance declaration for ‘C Int’
+



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

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b0f71f0a36ed41df044de2e2918babfa07560287
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/20240924/3ac25626/attachment-0001.html>


More information about the ghc-commits mailing list