GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2020-11-09T22:25:46Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/15495Handling Source Locations via TTG2020-11-09T22:25:46ZShayan-NajdHandling Source Locations via TTG## Problem
The current implementation of [TTG HsSyn AST](https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/TreesThatGrowGuidance) in GHC stores source locations for terms of a datatype `Exp` in a separate wrapper datatype ...## Problem
The current implementation of [TTG HsSyn AST](https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/TreesThatGrowGuidance) in GHC stores source locations for terms of a datatype `Exp` in a separate wrapper datatype `LExp` which is mutually recursive with `Exp` such that every recursive reference to `Exp` is done \*\*indirectly\*\*, via a reference to the wrapper datatype `LExp` (see the example code below). We refer to this style of storing source locations as the ping-pong style.
Besides the indirection and the resulting complications of the ping-pong style, there are two key problems with it:
* It bakes-in the source locations in the base TTG AST, forcing all instances to store source locations, even if they don't need them.For example, TH AST does not carry source locations, or even within GHC, there are generated terms without source locations.
* It results in a form of conceptual redundancy: source locations are tree decorations and they belong in the extension points.
These issues are discussed in
* [TTG wiki home page](https://gitlab.haskell.org/ghc/ghc/wikis/implementing-trees-that-grow), and its sub-pages, especiallly:
* [Handling source locations](https://gitlab.haskell.org/ghc/ghc/wikis/implementing-trees-that-grow/handling-source-locations)
* [TTG guidance](https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/TreesThatGrowGuidance)
## Solution
We can move the source location decorations to a wrapper constructor and remove the ping-pong style.
This can be done smoothly, mechanically, and gradually by using a getter/setter methods for source locations.
More details can be found at [the related wiki page](https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/HandlingSourceLocations).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | alanz, bgamari, simonpj |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Handling Source Locations via TTG","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"⊥","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["alanz","bgamari","simonpj"],"type":"Task","description":"== Problem ==\r\nThe current implementation of [https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/TreesThatGrowGuidance TTG HsSyn AST] in GHC stores source locations for terms of a datatype `Exp` in a separate wrapper datatype `LExp` which is mutually recursive with `Exp` such that every recursive reference to `Exp` is done **indirectly**, via a reference to the wrapper datatype `LExp` (see the example code below). We refer to this style of storing source locations as the ping-pong style.\r\n\r\nBesides the indirection and the resulting complications of the ping-pong style, there are two key problems with it: \r\n\r\na. It bakes-in the source locations in the base TTG AST, forcing all instances to store source locations, even if they don't need them.For example, TH AST does not carry source locations, or even within GHC, there are generated terms without source locations. \r\n\r\nb. It results in a form of conceptual redundancy: source locations are tree decorations and they belong in the extension points.\r\n (see https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/TreesThatGrowGuidance TTG Guidance])\r\n\r\n== Solution ==\r\nWe can move the source location decorations to a wrapper constructor and remove the ping-pong style.\r\nThis can be done smoothly, mechanically, and gradually by using a getter/setter methods for source locations.\r\nMore details can be found at [https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/HandlingSourceLocations the related wiki page]. ","type_of_failure":"OtherFailure","blocking":[]} -->⊥