@@ -9,6 +9,7 @@ module Wingman.CodeGen
9
9
) where
10
10
11
11
12
+ import ConLike
12
13
import Control.Lens ((%~) , (<>~) , (&) )
13
14
import Control.Monad.Except
14
15
import Control.Monad.State
@@ -25,6 +26,7 @@ import GHC.SourceGen.Binds
25
26
import GHC.SourceGen.Expr
26
27
import GHC.SourceGen.Overloaded
27
28
import GHC.SourceGen.Pat
29
+ import PatSyn
28
30
import Type hiding (Var )
29
31
import Wingman.CodeGen.Utils
30
32
import Wingman.GHC
@@ -36,7 +38,7 @@ import Wingman.Types
36
38
37
39
38
40
destructMatches
39
- :: (DataCon -> Judgement -> Rule )
41
+ :: (ConLike -> Judgement -> Rule )
40
42
-- ^ How to construct each match
41
43
-> Maybe OccName
42
44
-- ^ Scrutinee
@@ -54,47 +56,49 @@ destructMatches f scrut t jdg = do
54
56
case dcs of
55
57
[] -> throwError $ GoalMismatch " destruct" g
56
58
_ -> fmap unzipTrace $ for dcs $ \ dc -> do
57
- let ev = mapMaybe mkEvidence $ dataConInstArgTys dc apps
59
+ let con = RealDataCon dc
60
+ ev = mapMaybe mkEvidence $ dataConInstArgTys dc apps
58
61
-- We explicitly do not need to add the method hypothesis to
59
62
-- #syn_scoped
60
63
method_hy = foldMap evidenceToHypothesis ev
61
- args = dataConInstOrigArgTys' dc apps
64
+ args = conLikeInstOrigArgTys' con apps
62
65
modify $ appEndo $ foldMap (Endo . evidenceToSubst) ev
63
66
subst <- gets ts_unifier
64
67
names <- mkManyGoodNames (hyNamesInScope hy) args
65
- let hy' = patternHypothesis scrut dc jdg
68
+ let hy' = patternHypothesis scrut con jdg
66
69
$ zip names
67
70
$ coerce args
68
71
j = fmap (CType . substTyAddInScope subst . unCType)
69
72
$ introduce hy'
70
73
$ introduce method_hy
71
74
$ withNewGoal g jdg
72
- ext <- f dc j
75
+ ext <- f con j
73
76
pure $ ext
74
77
& # syn_trace %~ rose (" match " <> show dc <> " {" <> intercalate " , " (fmap show names) <> " }" )
75
78
. pure
76
79
& # syn_scoped <>~ hy'
77
- & # syn_val %~ match [mkDestructPat dc names] . unLoc
80
+ & # syn_val %~ match [mkDestructPat con names] . unLoc
78
81
79
82
80
83
------------------------------------------------------------------------------
81
84
-- | Produces a pattern for a data con and the names of its fields.
82
- mkDestructPat :: DataCon -> [OccName ] -> Pat GhcPs
83
- mkDestructPat dcon names
84
- | isTupleDataCon dcon =
85
+ mkDestructPat :: ConLike -> [OccName ] -> Pat GhcPs
86
+ mkDestructPat con names
87
+ | RealDataCon dcon <- con
88
+ , isTupleDataCon dcon =
85
89
tuple pat_args
86
90
| otherwise =
87
- infixifyPatIfNecessary dcon $
91
+ infixifyPatIfNecessary con $
88
92
conP
89
- (coerceName $ dataConName dcon )
93
+ (coerceName $ conLikeName con )
90
94
pat_args
91
95
where
92
96
pat_args = fmap bvar' names
93
97
94
98
95
- infixifyPatIfNecessary :: DataCon -> Pat GhcPs -> Pat GhcPs
99
+ infixifyPatIfNecessary :: ConLike -> Pat GhcPs -> Pat GhcPs
96
100
infixifyPatIfNecessary dcon x
97
- | dataConIsInfix dcon =
101
+ | conLikeIsInfix dcon =
98
102
case x of
99
103
ConPatIn op (PrefixCon [lhs, rhs]) ->
100
104
ConPatIn op $ InfixCon lhs rhs
@@ -113,8 +117,8 @@ unzipTrace = sequenceA
113
117
--
114
118
-- NOTE: The behaviour depends on GHC's 'dataConInstOrigArgTys'.
115
119
-- We need some tweaks if the compiler changes the implementation.
116
- dataConInstOrigArgTys '
117
- :: DataCon
120
+ conLikeInstOrigArgTys '
121
+ :: ConLike
118
122
-- ^ 'DataCon'structor
119
123
-> [Type ]
120
124
-- ^ /Universally/ quantified type arguments to a result type.
@@ -123,21 +127,30 @@ dataConInstOrigArgTys'
123
127
-- For example, for @MkMyGADT :: b -> MyGADT a c@, we
124
128
-- must pass @[a, c]@ as this argument but not @b@, as @b@ is an existential.
125
129
-> [Type ]
126
- -- ^ Types of arguments to the DataCon with returned type is instantiated with the second argument.
127
- dataConInstOrigArgTys ' con uniTys =
128
- let exvars = dataConExTys con
129
- in dataConInstOrigArgTys con $
130
+ -- ^ Types of arguments to the ConLike with returned type is instantiated with the second argument.
131
+ conLikeInstOrigArgTys ' con uniTys =
132
+ let exvars = conLikeExTys con
133
+ in conLikeInstOrigArgTys con $
130
134
uniTys ++ fmap mkTyVarTy exvars
131
135
-- Rationale: At least in GHC <= 8.10, 'dataConInstOrigArgTys'
132
136
-- unifies the second argument with DataCon's universals followed by existentials.
133
137
-- If the definition of 'dataConInstOrigArgTys' changes,
134
138
-- this place must be changed accordingly.
135
139
140
+
141
+ conLikeExTys :: ConLike -> [TyCoVar ]
142
+ conLikeExTys (RealDataCon d) = dataConExTys d
143
+ conLikeExTys (PatSynCon p) = patSynExTys p
144
+
145
+ patSynExTys :: PatSyn -> [TyCoVar ]
146
+ patSynExTys ps = patSynExTyVars ps
147
+
148
+
136
149
------------------------------------------------------------------------------
137
150
-- | Combinator for performing case splitting, and running sub-rules on the
138
151
-- resulting matches.
139
152
140
- destruct' :: (DataCon -> Judgement -> Rule ) -> HyInfo CType -> Judgement -> Rule
153
+ destruct' :: (ConLike -> Judgement -> Rule ) -> HyInfo CType -> Judgement -> Rule
141
154
destruct' f hi jdg = do
142
155
when (isDestructBlacklisted jdg) $ throwError NoApplicableTactic
143
156
let term = hi_name hi
@@ -156,7 +169,7 @@ destruct' f hi jdg = do
156
169
------------------------------------------------------------------------------
157
170
-- | Combinator for performign case splitting, and running sub-rules on the
158
171
-- resulting matches.
159
- destructLambdaCase' :: (DataCon -> Judgement -> Rule ) -> Judgement -> Rule
172
+ destructLambdaCase' :: (ConLike -> Judgement -> Rule ) -> Judgement -> Rule
160
173
destructLambdaCase' f jdg = do
161
174
when (isDestructBlacklisted jdg) $ throwError NoApplicableTactic
162
175
let g = jGoal jdg
@@ -171,11 +184,11 @@ destructLambdaCase' f jdg = do
171
184
-- | Construct a data con with subgoals for each field.
172
185
buildDataCon
173
186
:: Judgement
174
- -> DataCon -- ^ The data con to build
187
+ -> ConLike -- ^ The data con to build
175
188
-> [Type ] -- ^ Type arguments for the data con
176
189
-> RuleM (Synthesized (LHsExpr GhcPs ))
177
190
buildDataCon jdg dc tyapps = do
178
- let args = dataConInstOrigArgTys ' dc tyapps
191
+ let args = conLikeInstOrigArgTys ' dc tyapps
179
192
ext
180
193
<- fmap unzipTrace
181
194
$ traverse ( \ (arg, n) ->
0 commit comments