Can’t use SPECIALIZE with type equalities among constraints (GHC says "RULE left-hand side too complicated to desugar")
Repro: With 9.8.1-alpha1 and https://ghc.gitlab.haskell.org/head.hackage/ (as well as with 9.6 (with -allow-newer
) and 9.4) run cabal build
on commit https://github.com/Mikolaj/horde-ad/commit/a458406e367be83e1c6294ac40323b0980df750d
Output:
[26 of 28] Compiling HordeAd.Core.Engine ( src/HordeAd/Core/Engine.hs, /home/mikolaj/r/horde-ad/dist-newstyle/build/x86_64-linux/ghc-9.8.0.20230727/horde-ad-0.1.0.0/l/horde-ad-simplified/build/horde-ad-simplified/HordeAd/Core/Engine.o, /home/mikolaj/r/horde-ad/dist-newstyle/build/x86_64-linux/ghc-9.8.0.20230727/horde-ad-0.1.0.0/l/horde-ad-simplified/build/horde-ad-simplified/HordeAd/Core/Engine.dyn_o ) [Source file changed]
src/HordeAd/Core/Engine.hs:71:1: warning: [GHC-69441]
RULE left-hand side too complicated to desugar
Optimised lhs: case ghc-prim:GHC.Types.eq_sel
@Type @(Value vals) @vals $d~_ahFb
of co_ajgp
{ __DEFAULT ->
case ghc-prim:GHC.Types.eq_sel
@Type @vals @(Value astvals) $d~_ahFa
of co_ajgn
{ __DEFAULT ->
rev
@GHC.TypeNats.Nat
@Double
@y
@AstRanked
@vals
@astvals
$dDerivativeStages_ahFj
$dGoodScalar_ahFk
irred_ahF7
$dAdaptableDomains_ahF8
$dAdaptableDomains_ahF9
($d~_ajgr
`cast` (((~) <Type>_N <vals>_N co)_R
:: Coercible
Constraint
((vals :: Type) ~ (vals :: Type))
((vals :: Type) ~ (Value astvals :: Type))))
($d~_ajgs
`cast` (((~) <Type>_N (Sym co) <vals>_N)_R
:: Coercible
Constraint
((vals :: Type) ~ (vals :: Type))
((Value vals :: Type) ~ (vals :: Type))))
}
}
Orig lhs: let {
$dAdaptableDomains_ahFn :: AdaptableDomains OD.Array vals
[LclId]
$dAdaptableDomains_ahFn = $dAdaptableDomains_ahF9 } in
let {
$dAdaptableDomains_ahFm
:: AdaptableDomains (AstDynamic FullSpan) astvals
[LclId]
$dAdaptableDomains_ahFm = $dAdaptableDomains_ahF8 } in
let {
$dNFData_ajgC :: Control.DeepSeq.NFData Double
[LclId]
$dNFData_ajgC = Control.DeepSeq.$fNFDataDouble } in
let {
$dIfDifferentiable_ajgB :: IfDifferentiable Double
[LclId]
$dIfDifferentiable_ajgB
= HordeAd.Core.Types.$fIfDifferentiableDouble } in
let {
$dTypeable_ajgA
:: base:Data.Typeable.Internal.Typeable @Type Double
[LclId]
$dTypeable_ajgA
= base:Data.Typeable.Internal.C:Typeable
@Type
@Double
(base:Data.Typeable.Internal.mkTrCon
@Type
@Double
ghc-prim:GHC.Types.$tcDouble
(ghc-prim:GHC.Types.[]
@base:Data.Typeable.Internal.SomeTypeRep)) } in
let {
$dRowSum_ajgz :: HordeAd.Internal.TensorFFI.RowSum Double
[LclId]
$dRowSum_ajgz = HordeAd.Internal.TensorFFI.$fRowSumDouble } in
let {
$dNum_ajgy :: Num (Data.Vector.Storable.Vector Double)
[LclId]
$dNum_ajgy
= hmatrix-0.20.2-a909d242164031954bd359e3feb0f8b55923b4ddf0108c63e593969eccb79ce9:Numeric.Vector.$fNumVector1 } in
let {
$dNum_ajgx :: Num Double
[LclId]
$dNum_ajgx = GHC.Float.$fNumDouble } in
let {
$dNumeric_ajgw
:: hmatrix-0.20.2-a909d242164031954bd359e3feb0f8b55923b4ddf0108c63e593969eccb79ce9:Internal.Numeric.Numeric
Double
[LclId]
$dNumeric_ajgw
= hmatrix-0.20.2-a909d242164031954bd359e3feb0f8b55923b4ddf0108c63e593969eccb79ce9:Internal.Numeric.$fNumericDouble } in
let {
$dOrd_ajgv :: Ord Double
[LclId]
$dOrd_ajgv = ghc-prim:GHC.Classes.$fOrdDouble } in
let {
$dShow_ajgu :: Show Double
[LclId]
$dShow_ajgu = GHC.Float.$fShowDouble } in
let {
$d(%,,,,,,,,%)_ajgt
:: HordeAd.Core.Types.GoodScalarConstraint Double
[LclId]
$d(%,,,,,,,,%)_ajgt
= ($dShow_ajgu, $dOrd_ajgv, $dNumeric_ajgw, $dNum_ajgx, $dNum_ajgy,
$dRowSum_ajgz, $dTypeable_ajgA, $dIfDifferentiable_ajgB,
$dNFData_ajgC) } in
let {
$dGoodScalar_ahFk :: GoodScalar Double
[LclId]
$dGoodScalar_ahFk
= HordeAd.Core.Types.$fGoodScalarr @Double $d(%,,,,,,,,%)_ajgt } in
let {
$dDerivativeStages_ahFj
:: DerivativeStages @GHC.TypeNats.Nat AstRanked
[LclId]
$dDerivativeStages_ahFj
= HordeAd.Core.Engine.$fDerivativeStagesNaturalAstRanked } in
let {
$d~_ajgs :: (vals :: Type) ~ (vals :: Type)
[LclId]
$d~_ajgs
= ghc-prim:GHC.Types.Eq#
@Type
@vals
@vals
@~(<vals>_N :: (vals :: Type) ~ (vals :: Type)) } in
let {
$d~_ajgr :: (vals :: Type) ~ (vals :: Type)
[LclId]
$d~_ajgr
= ghc-prim:GHC.Types.Eq#
@Type
@vals
@vals
@~(<vals>_N :: (vals :: Type) ~ (vals :: Type)) } in
let {
$dKnownNat_ajgq :: KnownNat y
[LclId]
$dKnownNat_ajgq
= irred_ahF7
`cast` (Sub (HordeAd.Core.Types.D:R:HasSingletonDict[1] <y>_N)
:: Coercible
Constraint
(HasSingletonDict @GHC.TypeNats.Nat y)
(KnownNat y)) } in
let {
irred_ahFl :: HasSingletonDict @GHC.TypeNats.Nat y
[LclId]
irred_ahFl
= $dKnownNat_ajgq
`cast` (Sub (Sym (HordeAd.Core.Types.D:R:HasSingletonDict[1]
<y>_N))
:: Coercible
Constraint
(KnownNat y)
(HasSingletonDict @GHC.TypeNats.Nat y)) } in
case ghc-prim:GHC.Types.eq_sel @Type @(Value vals) @vals $d~_ahFb
of co_ajgp
{ __DEFAULT ->
let {
$d~_ahFp :: (Value vals :: Type) ~ (vals :: Type)
[LclId]
$d~_ahFp
= $d~_ajgs
`cast` (Sub (Sym ((~) <Type>_N co <vals>_N)_N)
:: Coercible
Constraint
((vals :: Type) ~ (vals :: Type))
((Value vals :: Type) ~ (vals :: Type))) } in
case ghc-prim:GHC.Types.eq_sel
@Type @vals @(Value astvals) $d~_ahFa
of co_ajgn
{ __DEFAULT ->
let {
co_ajgo :: (Value astvals :: Type) ~ (vals :: Type)
[LclId[CoVarId]]
co_ajgo = CO: Sym co } in
let {
$d~_ahFo :: (vals :: Type) ~ (Value astvals :: Type)
[LclId]
$d~_ahFo
= $d~_ajgr
`cast` (Sub (Sym ((~) <Type>_N <vals>_N co)_N)
:: Coercible
Constraint
((vals :: Type) ~ (vals :: Type))
((vals :: Type) ~ (Value astvals :: Type))) } in
rev
@GHC.TypeNats.Nat
@Double
@y
@AstRanked
@vals
@astvals
$dDerivativeStages_ahFj
$dGoodScalar_ahFk
irred_ahFl
$dAdaptableDomains_ahFm
$dAdaptableDomains_ahFn
$d~_ahFo
$d~_ahFp
}
}
|
71 | {-# SPECIALIZE rev
| ^^^^^^^^^^^^^^^^^^...
The problem is that usually I can tell GHC -fconstraint-solver-iterations=10000
or one of a few other similar flags and it goes through, but here it doesn't tell me how to prod it. Also, the library is now 100 times simpler than it was previously, so I don't understand what's causing the problem. Also, GHC apparently specializes the code just fine with -fexpose-all-unfoldings -fspecialise-aggressively
(which I can tell, because it does not complain despite -Wmissed-specialisations
and even -Wall-missed-specialisations
, as far as I can plough through the spam of the latter), but I can't replicate the same specialization manually.