Skip to content

Instantly share code, notes, and snippets.

@vidit-od
Last active August 23, 2026 19:15
Show Gist options
  • Select an option

  • Save vidit-od/032f03afac51d0e3507b2b9d1bd9a277 to your computer and use it in GitHub Desktop.

Select an option

Save vidit-od/032f03afac51d0e3507b2b9d1bd9a277 to your computer and use it in GitHub Desktop.

Google Summer of Code 2026 — Final Work Submission

Project: Goto Dependency Definition
Contributor: Vidit
Organization: Haskell.org
Mentors: Fendor, Zubin

Project Goals

The goal of this project was to extend the Haskell Language Server (HLS) with support for Goto Definition in dependency source files.

The work focused on two primary objectives:

  1. Extend the HLS rule system with typed, hierarchical rule inputs so that rules can be safely scoped to the kinds of files they are designed to handle.
  2. Integrating Goto Definition support for external dependencies.

Plan

  • Triggering Goto opens the dependency file like any other file.
  • HLS then persieves these dependency files as other Project files and starts triggering all rules on it
  • This leads to immediate failures.
  • To prevent this, HLS must be taught how to distinguish between different file types and when to trigger what rule.
  • For this, First Typed Rules was first implemented and then Goto dependency defination was build on top of it.

Implementation details

1. Typed Rules

  • The first phase of implementing Goto Definition for dependencies was to teach HLS the difference between dependency files and normal project files.
  • A hierarchical, AST-based rule input system was developed.
  • Each rule is now scoped to a specific RuleInput, denoting where that particular rule can be triggered.
  • For example, if a rule is scoped as a ProjectHaskellRule, it means that the rule cannot be triggered for dependency Haskell files or any other file type outside that scope.
  • The overall hierarchy is:
'SomeInput'                          -- any rule input
├── 'NoInput'                        -- global
└── 'SomeFileInput'                  -- has a 'NormalizedFilePath'
    ├── 'SomeHaskellInput'           -- all Haskell files
    │   ├── 'NonProjectHaskellInput' -- files in .hls/dependencies
    │   └── 'ProjectHaskellInput'    -- Haskell files in your project
    └── 'CabalInput'                 -- all .cabal files

Work done here: Typed Rules

2. Goto Dependency Definition

  • Dependency files refer to Haskell source files belonging to external packages rather than the current project.
  • These files lack the original project's build context, so running all rules on them could produce incorrect results, failures, and unnecessary work.
  • With Typed Rules, however, this is no longer a problem.
  • The Goto Definition implementation already had a strong foundation in PR #3749.
  • This implementation was rebased on top of the current master branch and Typed Rules, and then further developed to support Goto Definition for dependencies.

work done here : Goto Dependency

Architecture Exploration

The idea of using an AST-based hierarchical Typed Rule system came after multiple architectural iterations:

  1. Flat Types

    • All types are flat, with no correlation between different types.
    • Implementation: PR #4983
  2. Subsumable Types

    • A parent type subsumes all of its child types.
    • This allows automatic upcasting but increases the burden of type matching.

In the end, an AST-based hierarchy was chosen because of its simplicity and intuitive usage.

What Is Missing / Left to Do

  • Typed Rules have been reviewed extensively but have not been merged yet.
  • Once Typed Rules are merged, the Goto Dependency Definition work should be the next step toward merging.

Links

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