Major patch to re-engineer known-key names

Addresses #27013 for reinstallable base.

The main Note is Note [Overview of known entities] in GHC.Builtin. Read it carefully and keep it up to date.

Here is a ToDo list. Let's keep it up to date.

Pushing the changes through

  • Get rid of the legacy GHC.Builtin.KnownKeys.basicKnownKeyNames entirely.

    • Each item should move to to KnownOccs (mostly) or KnownKeys (some)
    • This is the most tiresome remaining task, because each needs individual attention.
    • Example: specTyConName:
      • specTyConName is never used directly.
      • But specTyConKey is used in SpecConstr
      • So we want SPEC to become a known-key entity
      • Move it to knownKeyTable and export it from GHC.Essentials
      • Job done
    • Example: errorMessageTypeErrorFamName
      • errorMessageTypeErrorFamName is used in Constraint.hs
        | tyConName tc == errorMessageTypeErrorFamName
      • Replace this use with hasKnownKey tc errorMessageTypeErrorFamKey
      • Add TypeError to knownKeyTable and export it from GHC.Essentials
      • Job done
  • Delete unused statically allocated keys from Builtin.KnownKeys. (There are many!)

  • Delete most of the module names in GHC.Builtin.Modules, which should now be unused.

  • Get rid of all Names in GHC.Builtin.TH; pretty much all should be known-occ. We can get rid of all, or almost all, of the statically-allocated uniques too.

  • Once basicKnownKeyNames is gone, delete legacy code for the old known-keys stuff

    • Specifically oldLookupKnownKeyName and friends
    • Note [Symbol table representation of names] is legacy and the code that supports it
    • Get rid of legacy Note [Known-key names] in GHC.Builtin.KnownKeys
  • base:GHC.Essentials should not really be exposed to users by base; it's is a GHC implementation mechanism, not really for end users. Maybe this is a cabal-file issue.

  • There is something fishy about these two exports from GHC.Essentials; they don't seem to exist.

       , pragSpecD, pragSpecInlD

    Teo has opinions here.

  • There is some legacy code around the unit-id for ghc-internal and base. See "Mechanisms ghc-internal must provide" and "Special treatment of ghc-internal hashes". Maybe we still need this for wired-in Names, I'm not sure.

Design choices

  • Do we want GHC.KnownOccs.knownOccs? It's tiresome to maintain and only used for error checks, if that.
  • At the momment, when GHC wants to get GHC.Essentials, it looks for it in the same way as any other import. But we don't really want the user to be able to import it; it should really be a hidden module in base. But then we'd need a different way to find it, since you can't usually import hidden modules. It's not quite clear what the rules for "how GHC finds GHC.Essentials" should be.

Regression tests

  • What should we do about these warnings? They crash some CI with -Werror

    libraries/ghc-experimental/src/GHC/Profiling/Eras.hs:1:14: warning: [GHC-19244] [-Wtrustworthy-safe]
      ‘GHC.Profiling.Eras’ is marked as Trustworthy but has been inferred as safe!
    
    libraries/ghc-experimental/src/Data/Sum/Experimental.hs:1:14: warning: [GHC-19244] [-Wtrustworthy-safe]
      ‘Data.Sum.Experimental’ is marked as Trustworthy but has been inferred as safe!
    
     libraries/ghc-experimental/src/Prelude/Experimental.hs:1:14: warning: [GHC-19244] [-Wtrustworthy-safe]
      ‘Prelude.Experimental’ is marked as Trustworthy but has been inferred as safe!
  • Some "hole-fits" and instances in scope error messages come out in a different order. Presumbly I change the sort order somehow, although I did not intend to do so. We could either just accept them, or find out why the sort order has changed.

  • Some compile-time perf regressions. It'd be worth investigating; perhaps there is some low-hanging fruit we can pluck.

  • Some tests no longer create $trModule bindings because they are unnecessary if there are no data types defined. See mkTypeableBinds. I think we can just accept the changed ouptut.

  • Some plugin tests fail because I refactored the module names in GHC.Builtin. I think we should just accept this and change the source code of the tests; but plugin authors may have to adapt. The new structure is better though.

  • This change:

    TcStaticPointersFail02.hs:9:6: [GHC-39999]
    -     No instance for ‘ghc-internal-<VERSION>-<HASH>:GHC.Internal.Data.Typeable.Internal.Typeable
    -                         b’
    +     No instance for ‘GHC.Internal.Data.Typeable.Internal.Typeable b’

    Looks better to me! Accept.

Edited by Wolfgang Jeltsch

Merge request reports

Loading