Skip to content

Commit 32e1fad

Browse files
Construct record datacons (#1356)
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent a9b796c commit 32e1fad

File tree

6 files changed

+46
-10
lines changed

6 files changed

+46
-10
lines changed

plugins/hls-tactics-plugin/src/Ide/Plugin/Tactic/CodeGen.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ buildDataCon
189189
-> DataCon -- ^ The data con to build
190190
-> [Type] -- ^ Type arguments for the data con
191191
-> RuleM (Trace, LHsExpr GhcPs)
192-
buildDataCon jdg dc apps = do
193-
let args = dataConInstOrigArgTys' dc apps
192+
buildDataCon jdg dc tyapps = do
193+
let args = dataConInstOrigArgTys' dc tyapps
194194
(tr, sgs)
195195
<- fmap unzipTrace
196196
$ traverse ( \(arg, n) ->

plugins/hls-tactics-plugin/src/Ide/Plugin/Tactic/CodeGen/Utils.hs

+12-7
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
module Ide.Plugin.Tactic.CodeGen.Utils where
44

5-
import Data.List
6-
import DataCon
7-
import Development.IDE.GHC.Compat
8-
import GHC.Exts
9-
import GHC.SourceGen (RdrNameStr)
10-
import GHC.SourceGen.Overloaded
11-
import Name
5+
import Data.List
6+
import DataCon
7+
import Development.IDE.GHC.Compat
8+
import GHC.Exts
9+
import GHC.SourceGen (recordConE, RdrNameStr)
10+
import GHC.SourceGen.Overloaded
11+
import Ide.Plugin.Tactic.GHC (getRecordFields)
12+
import Name
1213

1314

1415
------------------------------------------------------------------------------
@@ -20,6 +21,10 @@ mkCon dcon (fmap unLoc -> args)
2021
| dataConIsInfix dcon
2122
, (lhs : rhs : args') <- args =
2223
noLoc $ foldl' (@@) (op lhs (coerceName dcon_name) rhs) args'
24+
| Just fields <- getRecordFields dcon =
25+
noLoc $ recordConE (coerceName dcon_name) $ do
26+
(arg, (field, _)) <- zip args fields
27+
pure (coerceName field, arg)
2328
| otherwise =
2429
noLoc $ foldl' (@@) (bvar' $ occName dcon_name) args
2530
where

plugins/hls-tactics-plugin/src/Ide/Plugin/Tactic/GHC.hs

+13-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Control.Monad.State
99
import qualified Data.Map as M
1010
import Data.Maybe (isJust)
1111
import Data.Traversable
12-
import qualified DataCon as DataCon
12+
import DataCon
1313
import Development.IDE.GHC.Compat
1414
import Generics.SYB (mkT, everywhere)
1515
import Ide.Plugin.Tactic.Types
@@ -88,6 +88,18 @@ freshTyvars t = do
8888
) t
8989

9090

91+
------------------------------------------------------------------------------
92+
-- | Given a datacon, extract its record fields' names and types. Returns
93+
-- nothing if the datacon is not a record.
94+
getRecordFields :: DataCon -> Maybe [(OccName, CType)]
95+
getRecordFields dc =
96+
case dataConFieldLabels dc of
97+
[] -> Nothing
98+
lbls -> for lbls $ \lbl -> do
99+
(_, ty) <- dataConFieldType_maybe dc $ flLabel lbl
100+
pure (mkVarOccFS $ flLabel lbl, CType ty)
101+
102+
91103
------------------------------------------------------------------------------
92104
-- | Is this an algebraic type?
93105
algebraicTyCon :: Type -> Maybe TyCon

test/functional/Tactic.hs

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ tests = testGroup
117117
, expectFail "GoldenFish.hs" 5 18 Auto ""
118118
, goldenTest "GoldenArbitrary.hs" 25 13 Auto ""
119119
, goldenTest "FmapBoth.hs" 2 12 Auto ""
120+
, goldenTest "RecordCon.hs" 7 8 Auto ""
120121
, goldenTest "FmapJoin.hs" 2 14 Auto ""
121122
, goldenTest "Fgmap.hs" 2 9 Auto ""
122123
, goldenTest "FmapJoinInLet.hs" 4 19 Auto ""

test/testdata/tactic/RecordCon.hs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
data MyRecord a = Record
2+
{ field1 :: a
3+
, field2 :: Int
4+
}
5+
6+
blah :: (a -> Int) -> a -> MyRecord a
7+
blah = _
8+
9+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
data MyRecord a = Record
2+
{ field1 :: a
3+
, field2 :: Int
4+
}
5+
6+
blah :: (a -> Int) -> a -> MyRecord a
7+
blah = (\ fai a -> Record {field1 = a, field2 = fai a})
8+
9+

0 commit comments

Comments
 (0)