Skip to content

Conversation

@leana8959
Copy link

@leana8959 leana8959 commented Nov 11, 2025

This is the second part of the exact print parser. We changed the parser so that it doesn't merge the common stanzas during the parsing stage.

Depends on #11285 to update the test suite (after which the diff will be significantly smaller).

Background

Common stanzas are merged into their corresponding section during the parsing stage. This merging process doesn't retain the definition of the imports (i.e. common <name> ...) nor where they are used (import: <name>). To achieve exact printing and to be able to programmatically update the import list, we need to retain this information.

This PR is to remedy exactly that by deferring the merging process.

Implementation

We insert a new field gpdCommonStanza :: Map ImportName (CondTree ConfVar [Dependency] BuildInfo) in the GenericPackageDescription data type to track all the defined common stanzas. The merging is run only when the new accessors are called on a GenericPackageDescription.
We also added a bidirectional PatternSynonym that uses the old record syntax. The impact on existing code should be very low. Comparing against my PR to update the test suite is promising leana8959/cabal@accessor-tests...leana8959:cabal:no-flatten-package-description.

Please let me know your thoughts :)


Checklist below:

This PR modifies behaviour or interface

Include the following checklist in your PR:

Currently we have achieve the following:
- Stop merging, the merging function "endo" is id
- CondTree are completly retained in bigger types such as libarry and
  executable

We will need to do the following:
- Allow merging in the accessor

We broke:
- A bunch of Read and Ord instances
We isolated the type TestSuiteStanza and the logic to infer test type
We isolated the BenchmarkStanza type and the logic to infer benchmark
type.
We now use the WithImports type to tag imports
@leana8959 leana8959 force-pushed the no-flatten-package-description branch from 492ad9e to d8a1fcc Compare November 14, 2025 00:58
@leana8959
Copy link
Author

Here are the benchmark results by timing the ./validate --partial-hackage-tests test.

  • baseline (master branch)

    $ hyperfine --setup "./validate.sh" "./validate.sh --partial-hackage-tests"
    Benchmark 1: ./validate.sh --partial-hackage-tests
      Time (mean ± σ):     224.440 s ±  5.713 s    [User: 191.896 s, System: 34.800 s]
      Range (min … max):   218.596 s … 239.915 s    10 runs
    
  • no-flatten-package-description

    $ hyperfine --setup "./validate.sh" "./validate.sh --partial-hackage-tests"
    Benchmark 1: ./validate.sh --partial-hackage-tests
      Time (mean ± σ):     232.745 s ± 10.650 s    [User: 194.793 s, System: 38.621 s]
      Range (min … max):   220.815 s … 254.096 s    10 runs
    

@ulysses4ever
Copy link
Collaborator

I'm not sure why validate is used for benchmarking parser changes. Validate is likely dominated by completely unrelated factors (e. g. solver). Would it be possible to just download a bunch of cabal files from Hackage (see clc-stackage for a curated set of packages) and run only the parser on them?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants