haskell-language-server icon indicating copy to clipboard operation
haskell-language-server copied to clipboard

HLS confuses multiple paths to the same library, in presence of nested cabal project

Open Ptival opened this issue 1 year ago • 2 comments

Tested with HLS 2.0.0.0 (has been bugging me for many versions)

I have created a reproducible repository for this issue.

  1. Clone the repo, either stay in the main branch or switch to the error-when-opening-deep-dep branch
  2. Open VSCode in the root directory.
  3. Open MyLib.hs and fiddle with it to make sure it does type check (it should).
  4. Put your cursor on SomeTypeCtor, and jump-to-definition (F12 for me, or Go to Definition in the command palette)

What I see:

  • DeepDep.hs opens, but
  • Now there is a type (kind) error in MyLib.hs, or the form:
• Expected kind ‘deep-dep-0.1.0.0:DeepDep.SomeType’,
    but ‘'SomeTypeCtor 'True’ has kind ‘SomeType’
  NB: ‘deep-dep-0.1.0.0:DeepDep.SomeType’
        is defined in ‘DeepDep’ in package ‘deep-dep-0.1.0.0’
      ‘SomeType’ is defined at
        /home/val/personal/demonstrate-hls-issue/toplevel/deps/submodule/deep-dep/src/DeepDep.hs:5:1-36
• In the first argument of ‘SomeParameterizedType’, namely
    ‘('SomeTypeCtor 'True)’
  In the type ‘SomeParameterizedType ('SomeTypeCtor 'True)’
  In the type declaration for ‘Test’

What seems to happen is that HLS tries to type check deep-dep, but in the process creates an independent copy of it, separate from the one that MyLib depends upon. Then it gets confused between two instances of the very same kind that it now considers distinct.


There is a fix, demonstrated in the fixed-it branch of the reproduction repository. If you add a hie.yaml in the submodule directory, that lists all local paths and libraries, then when you open DeepDep.hs, everything keeps type-checking.

Unfortunately, in my real world use case, there are dozens of submodules, there are submodules that contain other submodules in a nested fashion, and none of those have any hie.yaml.

Adding a toplevel hie.yaml that lists everything does not seem to suffice: see error-with-toplevel-hie branch.

It'd be great if the default behavior was not to get confused in such a way. Clearly it's doable, as demonstrated in the fixed-it branch, but a solution that could rely on solely the top-level hie.yaml would be ideal.

Ptival avatar Jun 02 '23 22:06 Ptival

In case it helps, this is the directory structure in the error-when-opening-deep-dep branch:

.
├── cabal.project
├── deps
│   └── submodule
│       ├── cabal.project
│       ├── deep-dep
│       │   ├── deep-dep.cabal
│       │   └── src
│       │       └── DeepDep.hs
│       └── less-deep-dep
│           ├── less-deep-dep.cabal
│           └── src
│               └── LessDeepDep.hs
├── src
│   └── MyLib.hs
└── toplevel.cabal

Ptival avatar Jun 02 '23 22:06 Ptival

I can reproduce, and I think this is an issue with multiple home units https://well-typed.com/blog/2023/03/cabal-multi-unit/ and https://gist.github.com/fendor/5b26d36538787c8c2ed8c6eb6e68541f#interactive-ghc-session and what not. In short, many open issues.

Bad news, for old GHC versions, I don't think there is much we can do. The good news is, as you might tell from the blog posts, cabal and GHC support for multiple home units has been added. Once we also give hie-bios the necessary facelifting, we should be able to kill all these issues for good.

fendor avatar Jun 03 '23 10:06 fendor

I think this should be fixed by the proper multi-home-unit support.

michaelpj avatar May 15 '24 13:05 michaelpj