| ... |
... |
@@ -164,6 +164,56 @@ applying ``the mixture rule'' (SLPJ, p.~88) [which really {\em |
|
164
|
164
|
un}mixes the equations], producing a list of equation-info
|
|
165
|
165
|
blocks, each block having as its first column patterns compatible with each other.
|
|
166
|
166
|
|
|
|
167
|
+
|
|
|
168
|
+Note [Grouping equations]
|
|
|
169
|
+~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
170
|
+Given a bunch of equations, `groupEquations` makes groups of consecutive equations,
|
|
|
171
|
+in which the first patern of each member of a group shares the same `PatGroup`
|
|
|
172
|
+category.
|
|
|
173
|
+ groupEquations :: [EquationInfoNE] -> [NonEmpty (PatGroup, EquationInfoNE)]
|
|
|
174
|
+Generally, in each NonEmpty (PatGroup, EquationInfoNE) element of the result list,
|
|
|
175
|
+all the PatGroup's will be the same (e.g. all PgCon or all PgAny). But see (GE1)
|
|
|
176
|
+for an exception.
|
|
|
177
|
+
|
|
|
178
|
+We will match each group in turn, with failure falling through into the
|
|
|
179
|
+next group. For example
|
|
|
180
|
+ f x 0 = ... -- (E1)
|
|
|
181
|
+ f !y 1 = ... -- (E2)
|
|
|
182
|
+ f y 2 = ... -- (E3)
|
|
|
183
|
+ f (Just True) _ = ... -- (E4)
|
|
|
184
|
+ f Nothing _ = ... -- (E5)
|
|
|
185
|
+ f x 4 = ... -- (E6)
|
|
|
186
|
+ f _ 5 = ... -- (E7)
|
|
|
187
|
+
|
|
|
188
|
+The initial groups are
|
|
|
189
|
+ [E1]
|
|
|
190
|
+ [E2,E3, .. E7]
|
|
|
191
|
+because the bang dominates all the the equations that follow; see (GE1) below. Once we
|
|
|
192
|
+get inside the bang we'll again do a `groupEquations` and get groups
|
|
|
193
|
+ [E2,E3] -- PgAny
|
|
|
194
|
+ [E4,E5] -- PgCon
|
|
|
195
|
+ [E6,E6] -- PgAny
|
|
|
196
|
+
|
|
|
197
|
+Wrinkles
|
|
|
198
|
+
|
|
|
199
|
+(GE1) A bang pattern captures all the equations that follow. For example, given
|
|
|
200
|
+ g !x (p,True) = ...(E1)...
|
|
|
201
|
+ g x (p,False) = ...(E2)...
|
|
|
202
|
+ g True v = ...(E3)...
|
|
|
203
|
+ we want to get the (p,True) and (p,False) patterns in a single group so we can share
|
|
|
204
|
+ the matching on the pair, and we can't do that if we make two groups for the top
|
|
|
205
|
+ level match. See #27862. So we want these groups:
|
|
|
206
|
+
|
|
|
207
|
+ Group 1: !x (p,True) -> ..E1..
|
|
|
208
|
+ x (p,False) -> ..E2..
|
|
|
209
|
+
|
|
|
210
|
+ Group 2: True v -> ..E3..
|
|
|
211
|
+
|
|
|
212
|
+ A consequence is that in a group with a `PgBang` category, such as Group 1 above,
|
|
|
213
|
+ the second and subsequent equations may not be headed with a bang-pattern. Hence
|
|
|
214
|
+ in `matchBangs`, the function `getBangPat` is not surprised to see a non-bang pattern.
|
|
|
215
|
+
|
|
|
216
|
+(GE2) Overloaded literals: see Note [Grouping overloaded literal patterns]
|
|
167
|
217
|
-}
|
|
168
|
218
|
|
|
169
|
219
|
match :: [MatchId] -- ^ Variables rep\'ing the exprs we\'re matching with
|
| ... |
... |
@@ -176,11 +226,14 @@ match [] ty eqns = maybe (assertPprPanic (ppr ty)) combineEqnRhss $ nonEmpty eqn |
|
176
|
226
|
match (v:vs) ty eqns -- Eqns can be empty, but each equation is nonempty
|
|
177
|
227
|
= assertPpr (all (isInternalName . idName . matchId) vars) (ppr vars) $
|
|
178
|
228
|
do { dflags <- getDynFlags
|
|
|
229
|
+
|
|
|
230
|
+ -- Tidy the first pattern, to remove unnecessary diversity,
|
|
|
231
|
+ -- generating auxiliary bindings if necessary
|
|
179
|
232
|
; let platform = targetPlatform dflags
|
|
180
|
|
- -- Tidy the first pattern, generating
|
|
181
|
|
- -- auxiliary bindings if necessary
|
|
182
|
233
|
; (aux_binds, tidy_eqns) <- mapAndUnzipM (tidyEqnInfo v) eqns
|
|
|
234
|
+
|
|
183
|
235
|
-- Group the equations and match each group in turn
|
|
|
236
|
+ -- See Note [Grouping equations]
|
|
184
|
237
|
; let grouped = groupEquations platform tidy_eqns
|
|
185
|
238
|
|
|
186
|
239
|
-- print the view patterns that are commoned up to help debug
|
| ... |
... |
@@ -201,6 +254,7 @@ match (v:vs) ty eqns -- Eqns can be empty, but each equation is nonempty |
|
201
|
254
|
match_groups (g:gs) = mapM match_group $ g :| gs
|
|
202
|
255
|
|
|
203
|
256
|
match_group :: NonEmpty (PatGroup,EquationInfoNE) -> DsM (MatchResult CoreExpr)
|
|
|
257
|
+ -- See Note [Grouping equations]
|
|
204
|
258
|
match_group eqns@((group,_) :| _)
|
|
205
|
259
|
= case group of
|
|
206
|
260
|
PgCon {} -> matchConFamily vars ty (ne $ subGroupUniq [(c,e) | (PgCon c, e) <- eqns'])
|
| ... |
... |
@@ -246,6 +300,7 @@ matchVariables :: NonEmpty MatchId -> Type -> NonEmpty EquationInfoNE -> DsM (Ma |
|
246
|
300
|
matchVariables (_ :| vars) ty eqns = match vars ty $ NE.toList $ shiftEqns eqns
|
|
247
|
301
|
|
|
248
|
302
|
matchBangs :: NonEmpty MatchId -> Type -> NonEmpty EquationInfoNE -> DsM (MatchResult CoreExpr)
|
|
|
303
|
+-- See (GE1) in Note [Grouping equations]
|
|
249
|
304
|
matchBangs (var :| vars) ty eqns
|
|
250
|
305
|
= do { match_result <- match (var:vars) ty $ NE.toList $
|
|
251
|
306
|
decomposeFirstPat getBangPat <$> eqns
|
| ... |
... |
@@ -290,14 +345,20 @@ decomposeFirstPat :: (Pat GhcTc -> Pat GhcTc) -> EquationInfoNE -> EquationInfoN |
|
290
|
345
|
decomposeFirstPat extract eqn@(EqnMatch { eqn_pat = pat }) = eqn{eqn_pat = fmap extract pat}
|
|
291
|
346
|
decomposeFirstPat _ (EqnDone {}) = panic "decomposeFirstPat"
|
|
292
|
347
|
|
|
293
|
|
-getCoPat, getBangPat, getViewPat :: Pat GhcTc -> Pat GhcTc
|
|
|
348
|
+getCoPat :: Pat GhcTc -> Pat GhcTc
|
|
294
|
349
|
getCoPat (XPat (CoPat _ pat _)) = pat
|
|
295
|
350
|
getCoPat _ = panic "getCoPat"
|
|
296
|
|
-getBangPat (BangPat _ pat ) = unLoc pat
|
|
297
|
|
-getBangPat _ = panic "getBangPat"
|
|
|
351
|
+
|
|
|
352
|
+getViewPat :: Pat GhcTc -> Pat GhcTc
|
|
298
|
353
|
getViewPat (TcViewPat _ pat) = pat
|
|
299
|
354
|
getViewPat _ = panic "getViewPat"
|
|
300
|
355
|
|
|
|
356
|
+getBangPat :: Pat GhcTc -> Pat GhcTc
|
|
|
357
|
+-- See (GE1) in Note [Grouping equations]
|
|
|
358
|
+getBangPat (BangPat _ pat ) = unLoc pat
|
|
|
359
|
+getBangPat pat = pat
|
|
|
360
|
+
|
|
|
361
|
+
|
|
301
|
362
|
-- | Use this pattern synonym to match on a 'ViewPat'.
|
|
302
|
363
|
--
|
|
303
|
364
|
-- N.B.: View patterns can occur inside HsExpansions.
|
| ... |
... |
@@ -527,12 +588,10 @@ tidy1 _ non_interesting_pat |
|
527
|
588
|
tidy_bang_pat :: MatchId -> SrcSpanAnnA -> Pat GhcTc
|
|
528
|
589
|
-> DsM (DsWrapper, Pat GhcTc)
|
|
529
|
590
|
|
|
530
|
|
--- Discard par/sig under a bang
|
|
531
|
|
-tidy_bang_pat v _ (ParPat _ (L l p)) = putSrcSpanDsA l $ tidy_bang_pat v l p
|
|
532
|
|
-tidy_bang_pat v _ (SigPat _ (L l p) _) = putSrcSpanDsA l $ tidy_bang_pat v l p
|
|
533
|
|
-
|
|
534
|
|
--- Push the bang-pattern inwards, in the hope that
|
|
535
|
|
--- it may disappear next time
|
|
|
591
|
+-- Push the bang-pattern inwards, in the hope that it may disappear next time
|
|
|
592
|
+-- AsPat !(x@p) --> x@(!p)
|
|
|
593
|
+-- CoPat !(p |> co) --> (!p) |> co
|
|
|
594
|
+-- OrPat !(p || q) --> (!p || !q)
|
|
536
|
595
|
tidy_bang_pat v l (AsPat x v' p)
|
|
537
|
596
|
= tidy1 v (AsPat x v' (L l (BangPat noExtField p)))
|
|
538
|
597
|
tidy_bang_pat v l (XPat (CoPat w p t))
|
| ... |
... |
@@ -540,7 +599,16 @@ tidy_bang_pat v l (XPat (CoPat w p t)) |
|
540
|
599
|
tidy_bang_pat v l (OrPat x (p:|ps)) -- push bang into first pat alt
|
|
541
|
600
|
= tidy1 v (OrPat x (L l (BangPat noExtField p) :| ps))
|
|
542
|
601
|
|
|
|
602
|
+-- Discard par/sig/bang under a bang
|
|
|
603
|
+-- !(p) --> !p
|
|
|
604
|
+-- !(p::ty) --> !p
|
|
|
605
|
+-- !(!p) --> !p
|
|
|
606
|
+tidy_bang_pat v _ (ParPat _ (L l p)) = putSrcSpanDsA l $ tidy_bang_pat v l p
|
|
|
607
|
+tidy_bang_pat v _ (SigPat _ (L l p) _) = putSrcSpanDsA l $ tidy_bang_pat v l p
|
|
|
608
|
+tidy_bang_pat v _ (BangPat _ (L l p)) = putSrcSpanDsA l $ tidy_bang_pat v l p
|
|
|
609
|
+
|
|
543
|
610
|
-- Discard bang around strict pattern
|
|
|
611
|
+-- e.g. !(Just p) --> Just p
|
|
544
|
612
|
tidy_bang_pat v _ p@(LitPat {}) = tidy1 v p
|
|
545
|
613
|
tidy_bang_pat v _ p@(ListPat {}) = tidy1 v p
|
|
546
|
614
|
tidy_bang_pat v _ p@(TuplePat {}) = tidy1 v p
|
| ... |
... |
@@ -554,12 +622,13 @@ tidy_bang_pat v l p@(ConPat { pat_con = L _ (RealDataCon dc) |
|
554
|
622
|
}
|
|
555
|
623
|
})
|
|
556
|
624
|
-- Newtypes: push bang inwards (#9844)
|
|
557
|
|
- =
|
|
558
|
|
- if isNewTyCon (dataConTyCon dc)
|
|
559
|
|
- then tidy1 v (p { pat_args = push_bang_into_newtype_arg l (scaledThing ty) args })
|
|
560
|
|
- else tidy1 v p -- Data types: discard the bang
|
|
561
|
|
- where
|
|
562
|
|
- (ty:_) = dataConInstArgTys dc arg_tys
|
|
|
625
|
+ | isNewTyCon (dataConTyCon dc)
|
|
|
626
|
+ , (ty:_) <- dataConInstArgTys dc arg_tys
|
|
|
627
|
+ = tidy1 v (p { pat_args = push_bang_into_newtype_arg l (scaledThing ty) args })
|
|
|
628
|
+
|
|
|
629
|
+ -- Discard bang around non-newtype data constructors
|
|
|
630
|
+ | otherwise
|
|
|
631
|
+ = tidy1 v p
|
|
563
|
632
|
|
|
564
|
633
|
-------------------
|
|
565
|
634
|
-- Default case, leave the bang there:
|
| ... |
... |
@@ -1036,11 +1105,21 @@ groupEquations :: Platform -> [EquationInfoNE] -> [NonEmpty (PatGroup, EquationI |
|
1036
|
1105
|
-- (b) none of the gi are empty
|
|
1037
|
1106
|
-- The ordering of equations is unchanged
|
|
1038
|
1107
|
groupEquations platform eqns
|
|
1039
|
|
- = NE.groupBy same_gp $ [(patGroup platform (firstPat eqn), eqn) | eqn <- eqns]
|
|
1040
|
|
- -- comprehension on NonEmpty
|
|
|
1108
|
+ = group_eqns $ map add_gp eqns
|
|
1041
|
1109
|
where
|
|
1042
|
|
- same_gp :: (PatGroup,EquationInfo) -> (PatGroup,EquationInfo) -> Bool
|
|
1043
|
|
- (pg1,_) `same_gp` (pg2,_) = pg1 `sameGroup` pg2
|
|
|
1110
|
+ add_gp :: EquationInfoNE -> (PatGroup, EquationInfoNE)
|
|
|
1111
|
+ add_gp eqn = (patGroup platform (firstPat eqn), eqn)
|
|
|
1112
|
+
|
|
|
1113
|
+ group_eqns :: [(PatGroup,EquationInfoNE)] -> [NonEmpty (PatGroup, EquationInfoNE)]
|
|
|
1114
|
+ -- See Note [Grouping equations]
|
|
|
1115
|
+ group_eqns [] = []
|
|
|
1116
|
+ group_eqns ((PgBang,e) : pges) = [ (PgBang,e) :| pges ] -- See (GE1)
|
|
|
1117
|
+ group_eqns ((pg1,e) : pges) = ((pg1,e) :| pges1) : group_eqns pges2
|
|
|
1118
|
+ where
|
|
|
1119
|
+ (pges1, pges2) = span same_gp pges
|
|
|
1120
|
+
|
|
|
1121
|
+ same_gp :: (PatGroup,EquationInfo) -> Bool
|
|
|
1122
|
+ same_gp (pg2,_) = pg1 `sameGroup` pg2
|
|
1044
|
1123
|
|
|
1045
|
1124
|
-- TODO Make subGroup1 using a NonEmptyMap
|
|
1046
|
1125
|
subGroup :: (m -> [NonEmpty EquationInfo]) -- Map.elems
|