[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