Skip to content

Commit e1075e8

Browse files
isovectorjneira
andauthored
Wingman: Don't clobber where clauses (#2184)
* Extend TopLevelRHS pattern to track the where clause * Don't case split if there's a where clause * Add tests Co-authored-by: Javier Neira <[email protected]>
1 parent 8d7e8f1 commit e1075e8

File tree

5 files changed

+41
-9
lines changed

5 files changed

+41
-9
lines changed

plugins/hls-tactics-plugin/src/Wingman/GHC.hs

+8-3
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,18 @@ type PatCompat pass = LPat pass
309309

310310
------------------------------------------------------------------------------
311311
-- | Should make sure it's a fun bind
312-
pattern TopLevelRHS :: OccName -> [PatCompat GhcTc] -> LHsExpr GhcTc -> Match GhcTc (LHsExpr GhcTc)
313-
pattern TopLevelRHS name ps body <-
312+
pattern TopLevelRHS
313+
:: OccName
314+
-> [PatCompat GhcTc]
315+
-> LHsExpr GhcTc
316+
-> HsLocalBindsLR GhcTc GhcTc
317+
-> Match GhcTc (LHsExpr GhcTc)
318+
pattern TopLevelRHS name ps body where_binds <-
314319
Match _
315320
(FunRhs (L _ (occName -> name)) _ _)
316321
ps
317322
(GRHSs _
318-
[L _ (GRHS _ [] body)] _)
323+
[L _ (GRHS _ [] body)] (L _ where_binds))
319324

320325

321326
dataConExTys :: DataCon -> [TyCoVar]

plugins/hls-tactics-plugin/src/Wingman/LanguageServer.hs

+20-6
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ mkJudgementAndContext cfg g (TrackedStale binds bmap) rss (TrackedStale tcg tcgm
273273
mkFirstJudgement
274274
ctx
275275
(local_hy <> cls_hy)
276-
(isRhsHole tcg_rss tcs)
276+
(isRhsHoleWithoutWhere tcg_rss tcs)
277277
g
278278
, ctx
279279
)
@@ -341,6 +341,7 @@ getRhsPosVals (unTrack -> rss) (unTrack -> tcs)
341341
TopLevelRHS name ps
342342
(L (RealSrcSpan span) -- body with no guards and a single defn
343343
(HsVar _ (L _ hole)))
344+
_
344345
| containsSpan rss span -- which contains our span
345346
, isHole $ occName hole -- and the span is a hole
346347
-> flip evalState 0 $ buildTopLevelHypothesis name ps
@@ -478,12 +479,25 @@ mkIdHypothesis (splitId -> (name, ty)) prov =
478479

479480

480481
------------------------------------------------------------------------------
481-
-- | Is this hole immediately to the right of an equals sign?
482-
isRhsHole :: Tracked age RealSrcSpan -> Tracked age TypecheckedSource -> Bool
483-
isRhsHole (unTrack -> rss) (unTrack -> tcs) =
482+
-- | Is this hole immediately to the right of an equals sign --- and is there
483+
-- no where clause attached to it?
484+
--
485+
-- It's important that there is no where clause because otherwise it gets
486+
-- clobbered. See #2183 for an example.
487+
--
488+
-- This isn't a perfect check, and produces some ugly code. But it's much much
489+
-- better than the alternative, which is to destructively modify the user's
490+
-- AST.
491+
isRhsHoleWithoutWhere
492+
:: Tracked age RealSrcSpan
493+
-> Tracked age TypecheckedSource
494+
-> Bool
495+
isRhsHoleWithoutWhere (unTrack -> rss) (unTrack -> tcs) =
484496
everything (||) (mkQ False $ \case
485-
TopLevelRHS _ _ (L (RealSrcSpan span) _) -> containsSpan rss span
486-
_ -> False
497+
TopLevelRHS _ _
498+
(L (RealSrcSpan span) _)
499+
(EmptyLocalBinds _) -> containsSpan rss span
500+
_ -> False
487501
) tcs
488502

489503

plugins/hls-tactics-plugin/test/CodeAction/RefineSpec.hs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ spec = do
1616
refineTest 2 8 "RefineCon"
1717
refineTest 4 10 "RefineReader"
1818
refineTest 8 10 "RefineGADT"
19+
refineTest 2 8 "RefineIntroWhere"
1920

2021
describe "messages" $ do
2122
mkShowMessageTest Refine "" 2 8 "MessageForallA" TacticErrors
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
test :: Maybe Int -> Int
2+
test = \ m_n -> _w0
3+
where
4+
-- Don't delete me!
5+
blah = undefined
6+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
test :: Maybe Int -> Int
2+
test = _
3+
where
4+
-- Don't delete me!
5+
blah = undefined
6+

0 commit comments

Comments
 (0)