never executed always true always false
1
2 {-# LANGUAGE TypeFamilies #-}
3
4 {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
5
6 {-
7 (c) The University of Glasgow 2006
8 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
9
10
11 Pattern-matching constructors
12 -}
13
14 module GHC.HsToCore.Match.Constructor ( matchConFamily, matchPatSyn ) where
15
16 import GHC.Prelude
17
18 import {-# SOURCE #-} GHC.HsToCore.Match ( match )
19
20 import GHC.Hs
21 import GHC.HsToCore.Binds
22 import GHC.Core.ConLike
23 import GHC.Types.Basic ( Origin(..) )
24 import GHC.Tc.Utils.TcType
25 import GHC.Core.Multiplicity
26 import GHC.HsToCore.Monad
27 import GHC.HsToCore.Utils
28 import GHC.Core ( CoreExpr )
29 import GHC.Core.Make ( mkCoreLets )
30 import GHC.Utils.Misc
31 import GHC.Types.Id
32 import GHC.Types.Name.Env
33 import GHC.Types.FieldLabel ( flSelector )
34 import GHC.Types.SrcLoc
35 import GHC.Utils.Outputable
36 import GHC.Utils.Panic
37 import GHC.Utils.Panic.Plain
38 import Control.Monad(liftM)
39 import Data.List (groupBy)
40 import Data.List.NonEmpty (NonEmpty(..))
41
42 {-
43 We are confronted with the first column of patterns in a set of
44 equations, all beginning with constructors from one ``family'' (e.g.,
45 @[]@ and @:@ make up the @List@ ``family''). We want to generate the
46 alternatives for a @Case@ expression. There are several choices:
47 \begin{enumerate}
48 \item
49 Generate an alternative for every constructor in the family, whether
50 they are used in this set of equations or not; this is what the Wadler
51 chapter does.
52 \begin{description}
53 \item[Advantages:]
54 (a)~Simple. (b)~It may also be that large sparsely-used constructor
55 families are mainly handled by the code for literals.
56 \item[Disadvantages:]
57 (a)~Not practical for large sparsely-used constructor families, e.g.,
58 the ASCII character set. (b)~Have to look up a list of what
59 constructors make up the whole family.
60 \end{description}
61
62 \item
63 Generate an alternative for each constructor used, then add a default
64 alternative in case some constructors in the family weren't used.
65 \begin{description}
66 \item[Advantages:]
67 (a)~Alternatives aren't generated for unused constructors. (b)~The
68 STG is quite happy with defaults. (c)~No lookup in an environment needed.
69 \item[Disadvantages:]
70 (a)~A spurious default alternative may be generated.
71 \end{description}
72
73 \item
74 ``Do it right:'' generate an alternative for each constructor used,
75 and add a default alternative if all constructors in the family
76 weren't used.
77 \begin{description}
78 \item[Advantages:]
79 (a)~You will get cases with only one alternative (and no default),
80 which should be amenable to optimisation. Tuples are a common example.
81 \item[Disadvantages:]
82 (b)~Have to look up constructor families in TDE (as above).
83 \end{description}
84 \end{enumerate}
85
86 We are implementing the ``do-it-right'' option for now. The arguments
87 to @matchConFamily@ are the same as to @match@; the extra @Int@
88 returned is the number of constructors in the family.
89
90 The function @matchConFamily@ is concerned with this
91 have-we-used-all-the-constructors? question; the local function
92 @match_cons_used@ does all the real work.
93 -}
94
95 matchConFamily :: NonEmpty Id
96 -> Type
97 -> NonEmpty (NonEmpty EquationInfo)
98 -> DsM (MatchResult CoreExpr)
99 -- Each group of eqns is for a single constructor
100 matchConFamily (var :| vars) ty groups
101 = do let mult = idMult var
102 -- Each variable in the argument list correspond to one column in the
103 -- pattern matching equations. Its multiplicity is the context
104 -- multiplicity of the pattern. We extract that multiplicity, so that
105 -- 'matchOneconLike' knows the context multiplicity, in case it needs
106 -- to come up with new variables.
107 alts <- mapM (fmap toRealAlt . matchOneConLike vars ty mult) groups
108 return (mkCoAlgCaseMatchResult var ty alts)
109 where
110 toRealAlt alt = case alt_pat alt of
111 RealDataCon dcon -> alt{ alt_pat = dcon }
112 _ -> panic "matchConFamily: not RealDataCon"
113
114 matchPatSyn :: NonEmpty Id
115 -> Type
116 -> NonEmpty EquationInfo
117 -> DsM (MatchResult CoreExpr)
118 matchPatSyn (var :| vars) ty eqns
119 = do let mult = idMult var
120 alt <- fmap toSynAlt $ matchOneConLike vars ty mult eqns
121 return (mkCoSynCaseMatchResult var ty alt)
122 where
123 toSynAlt alt = case alt_pat alt of
124 PatSynCon psyn -> alt{ alt_pat = psyn }
125 _ -> panic "matchPatSyn: not PatSynCon"
126
127 type ConArgPats = HsConPatDetails GhcTc
128
129 matchOneConLike :: [Id]
130 -> Type
131 -> Mult
132 -> NonEmpty EquationInfo
133 -> DsM (CaseAlt ConLike)
134 matchOneConLike vars ty mult (eqn1 :| eqns) -- All eqns for a single constructor
135 = do { let inst_tys = assert (all tcIsTcTyVar ex_tvs) $
136 -- ex_tvs can only be tyvars as data types in source
137 -- Haskell cannot mention covar yet (Aug 2018).
138 assert (tvs1 `equalLength` ex_tvs) $
139 arg_tys ++ mkTyVarTys tvs1
140
141 val_arg_tys = conLikeInstOrigArgTys con1 inst_tys
142 -- dataConInstOrigArgTys takes the univ and existential tyvars
143 -- and returns the types of the *value* args, which is what we want
144
145 match_group :: [Id]
146 -> [(ConArgPats, EquationInfo)] -> DsM (MatchResult CoreExpr)
147 -- All members of the group have compatible ConArgPats
148 match_group arg_vars arg_eqn_prs
149 = assert (notNull arg_eqn_prs) $
150 do { (wraps, eqns') <- liftM unzip (mapM shift arg_eqn_prs)
151 ; let group_arg_vars = select_arg_vars arg_vars arg_eqn_prs
152 ; match_result <- match (group_arg_vars ++ vars) ty eqns'
153 ; return $ foldr1 (.) wraps <$> match_result
154 }
155
156 shift (_, eqn@(EqnInfo
157 { eqn_pats = ConPat
158 { pat_args = args
159 , pat_con_ext = ConPatTc
160 { cpt_tvs = tvs
161 , cpt_dicts = ds
162 , cpt_binds = bind
163 }
164 } : pats
165 }))
166 = do ds_bind <- dsTcEvBinds bind
167 return ( wrapBinds (tvs `zip` tvs1)
168 . wrapBinds (ds `zip` dicts1)
169 . mkCoreLets ds_bind
170 , eqn { eqn_orig = Generated
171 , eqn_pats = conArgPats val_arg_tys args ++ pats }
172 )
173 shift (_, (EqnInfo { eqn_pats = ps })) = pprPanic "matchOneCon/shift" (ppr ps)
174 ; let scaled_arg_tys = map (scaleScaled mult) val_arg_tys
175 -- The 'val_arg_tys' are taken from the data type definition, they
176 -- do not take into account the context multiplicity, therefore we
177 -- need to scale them back to get the correct context multiplicity
178 -- to desugar the sub-pattern in each field. We need to know these
179 -- multiplicity because of the invariant that, in Core, binders in a
180 -- constructor pattern must be scaled by the multiplicity of the
181 -- case. See Note [Case expression invariants].
182 ; arg_vars <- selectConMatchVars scaled_arg_tys args1
183 -- Use the first equation as a source of
184 -- suggestions for the new variables
185
186 -- Divide into sub-groups; see Note [Record patterns]
187 ; let groups :: [[(ConArgPats, EquationInfo)]]
188 groups = groupBy compatible_pats [ (pat_args (firstPat eqn), eqn)
189 | eqn <- eqn1:eqns ]
190
191 ; match_results <- mapM (match_group arg_vars) groups
192
193 ; return $ MkCaseAlt{ alt_pat = con1,
194 alt_bndrs = tvs1 ++ dicts1 ++ arg_vars,
195 alt_wrapper = wrapper1,
196 alt_result = foldr1 combineMatchResults match_results } }
197 where
198 ConPat { pat_con = L _ con1
199 , pat_args = args1
200 , pat_con_ext = ConPatTc
201 { cpt_arg_tys = arg_tys
202 , cpt_wrap = wrapper1
203 , cpt_tvs = tvs1
204 , cpt_dicts = dicts1
205 }
206 } = firstPat eqn1
207 fields1 = map flSelector (conLikeFieldLabels con1)
208
209 ex_tvs = conLikeExTyCoVars con1
210
211 -- Choose the right arg_vars in the right order for this group
212 -- Note [Record patterns]
213 select_arg_vars :: [Id] -> [(ConArgPats, EquationInfo)] -> [Id]
214 select_arg_vars arg_vars ((arg_pats, _) : _)
215 | RecCon flds <- arg_pats
216 , let rpats = rec_flds flds
217 , not (null rpats) -- Treated specially; cf conArgPats
218 = assertPpr (fields1 `equalLength` arg_vars)
219 (ppr con1 $$ ppr fields1 $$ ppr arg_vars) $
220 map lookup_fld rpats
221 | otherwise
222 = arg_vars
223 where
224 fld_var_env = mkNameEnv $ zipEqual "get_arg_vars" fields1 arg_vars
225 lookup_fld (L _ rpat) = lookupNameEnv_NF fld_var_env
226 (idName (hsRecFieldId rpat))
227 select_arg_vars _ [] = panic "matchOneCon/select_arg_vars []"
228
229 -----------------
230 compatible_pats :: (ConArgPats,a) -> (ConArgPats,a) -> Bool
231 -- Two constructors have compatible argument patterns if the number
232 -- and order of sub-matches is the same in both cases
233 compatible_pats (RecCon flds1, _) (RecCon flds2, _) = same_fields flds1 flds2
234 compatible_pats (RecCon flds1, _) _ = null (rec_flds flds1)
235 compatible_pats _ (RecCon flds2, _) = null (rec_flds flds2)
236 compatible_pats _ _ = True -- Prefix or infix con
237
238 same_fields :: HsRecFields GhcTc (LPat GhcTc) -> HsRecFields GhcTc (LPat GhcTc)
239 -> Bool
240 same_fields flds1 flds2
241 = all2 (\(L _ f1) (L _ f2)
242 -> hsRecFieldId f1 == hsRecFieldId f2)
243 (rec_flds flds1) (rec_flds flds2)
244
245
246 -----------------
247 selectConMatchVars :: [Scaled Type] -> ConArgPats -> DsM [Id]
248 selectConMatchVars arg_tys con
249 = case con of
250 RecCon {} -> newSysLocalsDs arg_tys
251 PrefixCon _ ps -> selectMatchVars (zipMults arg_tys ps)
252 InfixCon p1 p2 -> selectMatchVars (zipMults arg_tys [p1, p2])
253 where
254 zipMults = zipWithEqual "selectConMatchVar" (\a b -> (scaledMult a, unLoc b))
255
256 conArgPats :: [Scaled Type]-- Instantiated argument types
257 -- Used only to fill in the types of WildPats, which
258 -- are probably never looked at anyway
259 -> ConArgPats
260 -> [Pat GhcTc]
261 conArgPats _arg_tys (PrefixCon _ ps) = map unLoc ps
262 conArgPats _arg_tys (InfixCon p1 p2) = [unLoc p1, unLoc p2]
263 conArgPats arg_tys (RecCon (HsRecFields { rec_flds = rpats }))
264 | null rpats = map WildPat (map scaledThing arg_tys)
265 -- Important special case for C {}, which can be used for a
266 -- datacon that isn't declared to have fields at all
267 | otherwise = map (unLoc . hfbRHS . unLoc) rpats
268
269 {-
270 Note [Record patterns]
271 ~~~~~~~~~~~~~~~~~~~~~~
272 Consider
273 data T = T { x,y,z :: Bool }
274
275 f (T { y=True, x=False }) = ...
276
277 We must match the patterns IN THE ORDER GIVEN, thus for the first
278 one we match y=True before x=False. See #246; or imagine
279 matching against (T { y=False, x=undefined }): should fail without
280 touching the undefined.
281
282 Now consider:
283
284 f (T { y=True, x=False }) = ...
285 f (T { x=True, y= False}) = ...
286
287 In the first we must test y first; in the second we must test x
288 first. So we must divide even the equations for a single constructor
289 T into sub-groups, based on whether they match the same field in the
290 same order. That's what the (groupBy compatible_pats) grouping.
291
292 All non-record patterns are "compatible" in this sense, because the
293 positional patterns (T a b) and (a `T` b) all match the arguments
294 in order. Also T {} is special because it's equivalent to (T _ _).
295 Hence the (null rpats) checks here and there.
296
297 -}