File tree 6 files changed +46
-10
lines changed
plugins/hls-tactics-plugin/src/Ide/Plugin/Tactic
6 files changed +46
-10
lines changed Original file line number Diff line number Diff line change @@ -189,8 +189,8 @@ buildDataCon
189
189
-> DataCon -- ^ The data con to build
190
190
-> [Type ] -- ^ Type arguments for the data con
191
191
-> 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
194
194
(tr, sgs)
195
195
<- fmap unzipTrace
196
196
$ traverse ( \ (arg, n) ->
Original file line number Diff line number Diff line change 2
2
3
3
module Ide.Plugin.Tactic.CodeGen.Utils where
4
4
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
12
13
13
14
14
15
------------------------------------------------------------------------------
@@ -20,6 +21,10 @@ mkCon dcon (fmap unLoc -> args)
20
21
| dataConIsInfix dcon
21
22
, (lhs : rhs : args') <- args =
22
23
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)
23
28
| otherwise =
24
29
noLoc $ foldl' (@@) (bvar' $ occName dcon_name) args
25
30
where
Original file line number Diff line number Diff line change @@ -9,7 +9,7 @@ import Control.Monad.State
9
9
import qualified Data.Map as M
10
10
import Data.Maybe (isJust )
11
11
import Data.Traversable
12
- import qualified DataCon as DataCon
12
+ import DataCon
13
13
import Development.IDE.GHC.Compat
14
14
import Generics.SYB (mkT , everywhere )
15
15
import Ide.Plugin.Tactic.Types
@@ -88,6 +88,18 @@ freshTyvars t = do
88
88
) t
89
89
90
90
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
+
91
103
------------------------------------------------------------------------------
92
104
-- | Is this an algebraic type?
93
105
algebraicTyCon :: Type -> Maybe TyCon
Original file line number Diff line number Diff line change @@ -117,6 +117,7 @@ tests = testGroup
117
117
, expectFail " GoldenFish.hs" 5 18 Auto " "
118
118
, goldenTest " GoldenArbitrary.hs" 25 13 Auto " "
119
119
, goldenTest " FmapBoth.hs" 2 12 Auto " "
120
+ , goldenTest " RecordCon.hs" 7 8 Auto " "
120
121
, goldenTest " FmapJoin.hs" 2 14 Auto " "
121
122
, goldenTest " Fgmap.hs" 2 9 Auto " "
122
123
, goldenTest " FmapJoinInLet.hs" 4 19 Auto " "
Original file line number Diff line number Diff line change
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 number Diff line number Diff line change
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
+
You can’t perform that action at this time.
0 commit comments