Skip to content

WIP: modular ping pong

Philipp Krüger requested to merge matheus23/ghc:wip/modular-ping-pong into master

In short: I'm trying to do the work of changing how source locations are tagged onto the AST, following the LPat experiment. There is also more info on the wiki page.

Longer: In many places in the compiler, the Located a type synonym resolves to (in essence) (SrcSpan, a). After this PR usage of Located a across the compiler's AST will be replaced with the type family XRec pass a:

data ConDecl pass
  | ConDeclH98
      { ...
      , con_name :: XRec pass (IdP pass) -- instead of 'Located (IdP pass)'
      ...
      }

For any GhcPasses this will resolve to Located a again:

type instance XRec (GhcPass p) a = Located a

Motivation

Using Located across the compiler's AST is a problem, as it is not possible to use the same AST for applications that don't have source locations, for example Template Haskell.

Another application would be to enable api annotations to be stored alongside the AST instead of outside.

In general this change is in spirit of how source locations were changed in Pat.hs, see the previous MR !1970 (closed).

Details

This MR is split into two commits:

1. Commit

XRec now has a simpler definition. We seemed to agree on that in #17587 (closed).

type family XRec p a
type instance XRec (GhcPass p) a = Located a

2. Commit

This one tries to change as many Located X into XRec pass X as possible. The diff is supposed to be as stupid as possible, so in some cases a Located X was not changed to XRec pass, for example cases in which a pass parameter was not available, or one case in which the datatype derived Functor, Foldable and Traversable, which wouldn't be possible with XRec.

Changing Located to XRec is not as straight-forward as only changing definitions, obviously. Following follow-up changes had to be done:

  1. Some functions were defined polymorphically over LHsExpr pass for example. These were mostly changed to LHsExpr (GhcPass p), except for some cases in Utils.hs, which are used from haddock, so had to be polymorphic. In those cases I added a constraint like this: XRec pass (HsExpr pass) ~ Located (HsExpr pass) => ....
  2. It is not possible to write type class instances over LHsExpr (GhcPass p) for example, as the type checker doesn't allow type synonym family application in instances. In those cases I followed what was done for LPat: I resolved the type synonym family applications by hand. I also added comments for the old instance definitions, as they're not invalid from an intuitive point of view and in some cases the expanded definitions were quite far from the original. Should they be kept?
  3. For some reason I had to annotate a type in GHC/Hs/Expr.hs#pp_arg, I don't know why, unfortunately.
  4. In GHC/Hs/Rename/Source.hs#rnConDecl I had to add pattern-matches and updates to con_forall as it changed from Located Bool to XRec pass Bool, and since pass changes, GHC didn't quite figure out that it's type was allowed to change without manually updating it.

To-Do:

  • Change code-comments accordingly
  • Document this solution style in the wiki pages under handling source locations
  • Change the commit messages to include links to the wiki/issues
  • Update haddock source code
Edited by Philipp Krüger

Merge request reports