Open phadej opened 1 year ago
The issue seems to be https://gitlab.haskell.org/ghc/ghc/-/issues/20582 as there are two ways to solve Monad (t m')
when transformers-0.6
is used. Either via superclass (i.e. MonadTrans
) or directly from given constraints.
Writing
liftCallCC ::
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) (a :: Type) (b :: Type) .
(MonadTrans t, Monad m
#if !MIN_VERSION_transformers(0,6,0)
, forall (m' :: Type -> Type) . Monad m' => Monad (t m')
#endif
) =>
CallCC m (t m a) b -> CallCC (t m) a b
liftCallCC f g = join . lift . f $ \exit -> pure $ g (lift . exit . pure)
seems to fix the issue, but I haven't tested that extensively. (Does mtl
's CI test against transformers-0.6
on all GHCs?).
As I identified the GHC issue I made a revision to mtl-2.3.1.
Thanks for noting the regression and build plan failure @phadej. Odd that this made it through CI without a hiccup - all builds are building for 2.3.1 with no issue. However, even in #131 for 9.0, the build passed, so something's fishy here.
I ran into the same issue, but also had CI succeed. I think what happens is that when testing locally whether my code compiles with transformers-0.6, I used
--constraint='transformers >0.6'
and thus forced its use. But on CI, because transformers
is a package that comes with GHC and thus is already installed, cabal
prefers the older, installed version.
This highlights a fundamental issue with our dependency ranges: There is no (good) way to actually check on CI that the full range of allowed versions actually works! https://github.com/haskell/cabal/issues/8387 would help at least with the upper end of the range, and would have caught this incompatibility before it would have hit hackage.
@nomeata Yes, it's an issue with dependency ranges, but there is no way to do better still using some ranges.
This an issue in GHC. Any library version (combination) may trigger a bug in GHC, so we cannot extrapolate using semantics of versioning system. But exhaustively checking all combinations is not realistic. So we approximate as well as we see fit.
And because this is an issue in GHC, everyone can run into this issue in their code - not only mtl
. So one possible solution is simply disallow transformers-0.6
on GHC-9.0. Quite blunt, but effective. Alternatively everyone have to be aware of this, like everyone had to be aware to not use PolyKinds
on GHC-7.4 (Everyone writing QuantifiedConstraints
code has to be aware of this issue, but users may not need to be).
EDIT: Another option is to have GHC-9.0.3, fixing the issue, but AFAIK it's not possible.
So one possible solution is simply disallow transformers-0.6 on GHC-9.0.
Yes, that’s actually quite reasonable. Is it just a matter of adding
if impl(ghc == 9.0.*)
buildable: false
to the transformer’s cabal files, and this could be done by a hackage revision even, right?
@nomeata Yes, and no.
buildable: false
doesn't have semantics you think. †
if impl(ghc ==9.0.*)
build-depends: unbuildable <0
has correct one.
That cannot be added via revision though currently, as the structure of .cabal
files cannot be changed. (IIRC there is issue somewhere on hackage-server or hackage-cli issue tracker to allow revisions adding conditional blocks which add build-depends to things already dependended upon - the general problem is that we don't want allow adding/removing arbitrary dependencies and revisions should be reversible, i.e. you should be able to undo any revision).
Luckily, you can amend build-depends: base
to exclude base
range used by particular GHC (for now, using base
version as a proxy for GHC version).
† The semantics for buildable
is that it's checked only when package version is already selected to be included in install plan (a bit like extra-libraries
are only checked at the build time). I.e. the cabal solver will happily select package version (with buildable: False
), but then the build will fail when configuring. See https://cabal.readthedocs.io/en/stable/cabal-package.html#pkg-field-buildable example. That is bad, and I recommend to never use buildable:
. (I suspect its semantics is legacy from ages before cabal-install had proper backtracking solver).
EDIT: there are also additional semantics where cabal
toggles buildable: False
test-suites and benchmarks for local packages, but I cannot find any documentation about that, and I only remember that it's confusing functionality.
Ah right tranformers
is bundled. Yeah, makes sense. i'll come up with a PR when my brain turns back on after the holidays. Right now, the revision is satisfactory. Thanks both of you! @kozross
Luckily, you can amend build-depends: base to exclude base range used by particular GHC (for now, using base version as a proxy for GHC version).
Is someone going to that, or should I raise an issue at https://github.com/haskell-infra/hackage-trustees/issues?
Is someone going to that
That is very intrusive revision, as a trustee I won't do it. Pedantically saying, transformers
isn't broken. You really should discuss with the maintainer first.
FWIW, GHC-9.2.1 and GHC-9.2.2 are also affected as the bug is fixed in ghc-9.2.3: https://www.haskell.org/ghc/blog/20220527-ghc-9.2.3-released.html (issue #20582
)
Sorry, quite right. Jumped the gun here. I'll create an issue upstream m
I asked Ross at https://hub.darcs.net/ross/transformers/issue/90
I've changed my mind on this. It seems a bit drastic to block GHC 9.0 from transformers-6.0, when as @phadej says, transformers isn't actually broken here. The above fix for mtl
seems appropriate, since for transformers >= 6.0 the forall
constraint is redundant, being implied by MonadTrans
. It's true that the GHC bug may bite other users combining MonadTrans
with type system extensions, but it seems excessive to make users of transformers who aren't using those extensions pay the price for that.
@emilypi : Currently mtl-2.3.1
is in an awkward state with a gap in the base
versions it supports. Could we get mtl-2.3.1.1
fixing this issue soon?
It seems a fix is already outlined in https://github.com/haskell/mtl/issues/138#issuecomment-1366103086.
Breakage in the wild:
rejecting: base-4.15.1.0/installed-4.15.1.0 (conflict: mtl => base>=4.12 && <4.15 || >=4.16 && <5)
EDIT: Doesn't happen with GHC-9.2.5 or other major versions for example, so probably some GHC bug?
I'm not making revision without knowing what is the cause of this problem.
Note:
mtl-2.3
is compiling fine with GHC-9.0. So there's some change inmtl-2.3.1
which triggered this. EDIT: liftCallCC was added in mtl-2.3.1