GHC 9.6 Migration Guide

Hello all,

Part of GHC’s release process that has been historically under-advertised is our migration guide, where we document the major user-visible changes made in the compiler and its core libraries.

Today we are happy to share the migration guide for GHC 9.6. Our hope is that this guide serves as a useful resource for those porting their projects to GHC 9.6. Note that this is a living document which we hope the community can help maintain. If you notice anything missing please do bring it to our attention.


~ Ben


20 posts were split to a new topic: Language, library, and compiler stability

@bgamari I’m very glad this kind of document is being produced! :slight_smile:
One more step towards automating the production of compatibility patches.

I’m not a user of type-changing record updates myself but I’m wondering why the rejection of the code couldn’t have been put behind a flag just like the other warning that we have for record update, -Wambiguous-fields.

1 Like

Thanks @bgamari! Could I ask that the migration guide be completed with fixes? For example, in "
Type-changing record updates involving type families" there are two explanations to fix the problem. It’d be really useful to make this completely precise by providing code examples of both of those fixes.

Edit: actually it might just be this point that needs a code example, the next migration does have the fix illustrated.


Bear in mind that the previous state of record updates for GADTs was complex, buggy and ill-specified. The new design is much clearer: simply apply the translation of record updates in the Report.

GHC frequently fixes bugs with the side effect that code that was (accidentally) relying on the bug ceases to work. Volunteer contributors aren’t going to be pleased if every patch that fixes a bug also has to introduce a warning, retain/test the old code path for two versions, etc. and it seems like it would lead to a significant increase in the internal code complexity. Basically I don’t think it is feasible to have GHC maintain bug-for-bug compatibility between versions without a very substantial increase in the resources going in to maintenance.


I think the situation with -Wambiguous-fields was a bit different because there we had a clearly-specified existing feature that the GHC steering committee decided to deprecate (via the proposals process). The proposal specified the warning for code that had been relying on the feature, and the intended migration path (although there are some details still to resolve there).

In contrast, with GADT record updates in 9.6, there was no well-defined existing feature being deprecated, rather a collection of bugs were being fixed by giving a proper specification to something that previously lacked one.

Of course there is always a judgement call to be made about whether a bug fix that breaks existing programs is significant enough to warrant extra effort on backwards compatibility. But that extra effort has very real costs.


Thank you for the context! :slight_smile:


Would it be a good idea to document similar unspecified parts of the compiler such that people who care about backwards compatibility can avoid those parts? Even better if a tool like HLint or Stan could be used to warn you automatically when you are using those parts.

1 Like

I suggest that the discussions about both compiler stability and the SWG be broken out to separate threads and we keep this one focused on the 9.6 migration guide


Yes, I agree. I will break out the last 20-or-so posts into a new thread.

I have broken out the discussion of general stability concerns into a new thread, Language, library, and compiler stability.


Thanks! This will be very helpful. I’m looking forward to not having to use third party libraries for SNat etc.

I have trouble finding in the 9.6 migration guide where GHC.Tc.Types.Evidence.mkTcSymCo and GHC.Tc.Types.Evidence.mkTcTransCo have gone. Search for Evidence comes up empty, but perhaps I missed some more general remark that covers this. Listing all affected module names would certainly be helpful for users that have no idea what they are doing and just try to blindly apply the guide to whatever error messages pop up.

Anyway, thank you for the guide, it’s been very helpful so far.

Edit: alternatively, a stable link to (pre-alpha) haddocks of the new version of the affected APIs would work ( is 404).

Edit: alternatively, a stable link to (pre-alpha) haddocks of the new version of the affected APIs would work ( is 404).

@Mikolaj Here you go: ghc- The GHC API

I think this has been fixed as of Broken interpolation in GHC `master` haddocks (#22714) · Issues · Glasgow Haskell Compiler / GHC · GitLab

1 Like

Oh, great, thank you @amesgen.

it seems GHC.Tc.Types.Evidence.mkTcSymCo and GHC.Tc.Types.Evidence.mkTcTransCo have gone to GHC.Plugin with a name simplification. I guess a mention in the guide wouldn’t hurt, even if GHC.Plugin is an old invention (is it?). In any case, the three famous ghc-tcplugins-extra and ghc-typelits-* plugins compile fine now, after minor adjustments. I will create PRs.