-
-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wingman: TODO(sandy) error pops up after the first tactic #2448
Comments
thanks for the bug report, pinging @isovector due to the explicit mention 😉 |
I'm having the same issue with VSCode on macOS (11.6) with HLS 1.5.1. |
Which version of GHC, @wenkokke ? I'll see if I can repro this on the weekend. |
I got these errors with GHC 8.10.7, using any of the case splitting primitives except for introduce-and-destruct, so my experience is consistent with the errors shown above. I can do a bit more thorough testing if that’d help? |
That would be extremely helpful, thanks. The block that pushes out the error message is a MaybeT over mostly HLS functionality. I haven't touched Wingman for a few releases, so my guess is that something in the infrastructure has changed --- likely one of the data sources that used to be blocking is no longer. Do you notice more successes if you wait for 30 seconds after making the last change? Do you see this problem less often on smaller projects? |
I see this error on every single attempt that I make to pattern match regardless of project size (though I have only tested it on small projects). I'm guessing that the amount of time that I wait doesn't really affect things, and I think that I haven't been calling these functions immediately... but I'm not sure. I will report back. |
I started a cabal project with only a single file with only the following lines: module Test where
nope :: Bool -> Bool
nope b = _wc Now running "Case split on b" raises "TODO(sandy)" as a popup. However, "introduce lambda" works just fine, e.g., to obtain the above code from: nope :: Bool -> Bool
nope = _ Similarly, "introduce and destruct term" works just fine. The amount of time waited has no effect on any of these behaviors. |
My guess is that something broke the datacon lookup stuff. The most recent change to this function was #2128. I'm traveling right now, but will try to find some time to dig in over the weekend. |
Hi @isovector . I've tried different approaches and found that 1 . Start with this file.data Dummy a = Dummy a
f :: Dummy Int -> Int
f = _ 2. If I launch "Introduce lambda", It doesn't faildata Dummy a = Dummy a
f :: Dummy Int -> Int
f du = _wa 3. If after (2) I launch "case split on du" It fails with TODO(sandy).data Dummy a = Dummy a
f :: Dummy Int -> Int
f du = _wa -- Fails when triying "case split" action 3.1 If now, I come back to (1) and hit again "Introduce lambda" it fails with the same errordata Dummy a = Dummy a
f :: Dummy Int -> Int
f = _ -- Now this fails after first fail at (2) 3.2 If after (3) I re-start
|
I can confirm that this is indeed the case! |
Thanks for the repro! It sounds like something is going wrong in the HLS dependency cache. I'll take a look ASAP. |
OK, I can repro as well. Looking into it now. |
So interestingly, we can run different commands if we undo the change wingman just made. EG |
This is the line that's failing: haskell-language-server/plugins/hls-tactics-plugin/src/Wingman/LanguageServer.hs Line 316 in 0b6b5ec
|
Here is the dumped (Node
(NodeInfo
(fromList
[((,)
{FastString: "Module"}
{FastString: "Module"})])
[]
(fromList
[]))
({abstract:RealSrcSpan})
[(Node
(NodeInfo
(fromList
[((,)
{FastString: "DataDecl"}
{FastString: "TyClDecl"})])
[]
(fromList
[]))
({abstract:RealSrcSpan})
[(Node
(NodeInfo
(fromList
[])
[]
(fromList
[((,)
(Right
{Name: Dummy})
(IdentifierDetails
(Nothing)
(fromList
[(Decl
(DataDec)
(Just
({abstract:RealSrcSpan})))])))]))
({abstract:RealSrcSpan})
[])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "UserTyVar"}
{FastString: "HsTyVarBndr"})])
[]
(fromList
[((,)
(Right
{Name: a})
(IdentifierDetails
(Nothing)
(fromList
[(TyVarBind
(NoScope)
(ResolvedScopes
[(NoScope)
,(LocalScope
({abstract:RealSrcSpan}))]))])))]))
({abstract:RealSrcSpan})
[])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "ConDeclH98"}
{FastString: "ConDecl"})])
[]
(fromList
[]))
({abstract:RealSrcSpan})
[(Node
(NodeInfo
(fromList
[])
[]
(fromList
[((,)
(Right
{Name: Dummy})
(IdentifierDetails
(Nothing)
(fromList
[(Decl
(ConDec)
(Just
({abstract:RealSrcSpan})))])))]))
({abstract:RealSrcSpan})
[])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "HsTyVar"}
{FastString: "HsType"})])
[]
(fromList
[((,)
(Right
{Name: a})
(IdentifierDetails
(Nothing)
(fromList
[(Use)])))]))
({abstract:RealSrcSpan})
[])])])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "TypeSig"}
{FastString: "Sig"})])
[]
(fromList
[]))
({abstract:RealSrcSpan})
[(Node
(NodeInfo
(fromList
[])
[]
(fromList
[((,)
(Right
{Name: f})
(IdentifierDetails
(Nothing)
(fromList
[(TyDecl)])))]))
({abstract:RealSrcSpan})
[])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "HsFunTy"}
{FastString: "HsType"})])
[]
(fromList
[]))
({abstract:RealSrcSpan})
[(Node
(NodeInfo
(fromList
[((,)
{FastString: "HsAppTy"}
{FastString: "HsType"})])
[]
(fromList
[]))
({abstract:RealSrcSpan})
[(Node
(NodeInfo
(fromList
[((,)
{FastString: "HsTyVar"}
{FastString: "HsType"})])
[]
(fromList
[((,)
(Right
{Name: Dummy})
(IdentifierDetails
(Nothing)
(fromList
[(Use)])))]))
({abstract:RealSrcSpan})
[])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "HsTyVar"}
{FastString: "HsType"})])
[]
(fromList
[((,)
(Right
{Name: Int})
(IdentifierDetails
(Nothing)
(fromList
[(Use)])))]))
({abstract:RealSrcSpan})
[])])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "HsTyVar"}
{FastString: "HsType"})])
[]
(fromList
[((,)
(Right
{Name: Int})
(IdentifierDetails
(Nothing)
(fromList
[(Use)])))]))
({abstract:RealSrcSpan})
[])])])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "AbsBinds"}
{FastString: "HsBindLR"})
,((,)
{FastString: "FunBind"}
{FastString: "HsBindLR"})
,((,)
{FastString: "Match"}
{FastString: "Match"})])
[(FunTy
(VisArg)
(TyConApp
({abstract:TyCon})
[(TyConApp
({abstract:TyCon})
[])])
(TyConApp
({abstract:TyCon})
[]))]
(fromList
[]))
({abstract:RealSrcSpan})
[(Node
(NodeInfo
(fromList
[])
[]
(fromList
[((,)
(Right
{Name: f})
(IdentifierDetails
(Just
(FunTy
(VisArg)
(TyConApp
({abstract:TyCon})
[(TyConApp
({abstract:TyCon})
[])])
(TyConApp
({abstract:TyCon})
[])))
(fromList
[(MatchBind)
,(ValBind
(RegularBind)
(ModuleScope)
(Just
({abstract:RealSrcSpan})))])))]))
({abstract:RealSrcSpan})
[])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "VarPat"}
{FastString: "Pat"})])
[(TyConApp
({abstract:TyCon})
[(TyConApp
({abstract:TyCon})
[])])]
(fromList
[((,)
(Right
{Name: n})
(IdentifierDetails
(Just
(TyConApp
({abstract:TyCon})
[(TyConApp
({abstract:TyCon})
[])]))
(fromList
[(PatternBind
(LocalScope
({abstract:RealSrcSpan}))
(NoScope)
(Nothing))])))]))
({abstract:RealSrcSpan})
[])
,(Node
(NodeInfo
(fromList
[((,)
{FastString: "GRHS"}
{FastString: "GRHS"})])
[]
(fromList
[]))
({abstract:RealSrcSpan})
[(Node
(NodeInfo
(fromList
[((,)
{FastString: "HsUnboundVar"}
{FastString: "HsExpr"})
,((,)
{FastString: "HsVar"}
{FastString: "HsExpr"})])
[(TyConApp
({abstract:TyCon})
[])]
(fromList
[((,)
(Right
{Name: __a6Qy})
(IdentifierDetails
(Just
(TyConApp
({abstract:TyCon})
[]))
(fromList
[(Use)])))]))
({abstract:RealSrcSpan})
[])])])]) not super helpful without the RSS --- though the one we're looking for is |
Here's a trace of finding the right src span
and here's what happens when it fails:
|
Upon restarting, here's what we get for the previous failing case:
|
The asts we get come from here: haskell-language-server/plugins/hls-tactics-plugin/src/Wingman/LanguageServer.hs Line 214 in 0b6b5ec
which is explicitly marked as OK to be stale. That's probably the issue, and maybe the behavior here has changed. |
That doesn't appear to fix the issue. Weird: running the code action gives us this output:
but immediately after, we get a hover update, and this output
so for some reason, hovers are looking at fresh data, but code actions are not. ... which explains why the code actions appear as possibilities in the first place. |
Are code actions being cached? Like, they get generated once when the file is loaded, and then never again? @pepeiborra |
No, but we changed the way cache invalidation works for the build graph. Previously the build system would scan all the build nodes to find out what has changed, now it gets that information from the caller, i.e. ghcide. This is new in HLS 1.5.0 and requires using Maybe you need to call |
As far as I can tell, this is not a bug in Wingman. I'm going to run a bisect and see where it goes wrong. |
Bisect says 682386d is to blame. |
I'll get a proper test coded up tomorrow, and maybe @pepeiborra could help me spelunk through 682386d |
@isovector if I change the
haskell-language-server/plugins/hls-tactics-plugin/src/Wingman/LanguageServer.hs Lines 596 to 597 in ce1f353
|
I don't understand why this is necessary though, it could mean a bug in hls-graph |
Thanks for investigating, Pepe. Greatly appreciated! I'll get that merged later today. |
Your environment
Which OS do you use:
Ubuntu 20.04.3 LTS
Which lsp-client do you use:
VS Code
Describe your project (alternative: link to the project):
It is a regular
stack
project which can be found here. Nothing really wierd, just a normal advent of code project with one executable per day.stack snapshot: 18.6 -> GHC 8.10.7
HLS version: 1.5.1
Steps to reproduce
write the following file and positionate the cursor on the underscore, then trigger the code action "Wingman: case split on d"
Expected behaviour
It should complete the line
example d = _
introducingInput
constructor likeexample Input = _d
. Some times, It works fine when I re-starthls
but 8 out of 10 times it keeps failing.Actual behaviour
And error pops up
TODO(sandy)
Include debug information
This is the output when I set VS code extension setting to debug. (I've been unable to run
haskell-language-server-wrapper
)Debug output:
The text was updated successfully, but these errors were encountered: