2f4e23e393c2e5d7da38bea6fd4439e5c761f94d
[ghc.git] / compiler / vectorise / Vectorise / Generic / PAMethods.hs
1
2 -- | Generate methods for the PA class.
3 --
4 -- TODO: there is a large amount of redundancy here between the
5 -- a, PData a, and PDatas a forms. See if we can factor some of this out.
6 --
7 module Vectorise.Generic.PAMethods
8 ( buildPReprTyCon
9 , buildPAScAndMethods
10 ) where
11
12 import Vectorise.Utils
13 import Vectorise.Monad
14 import Vectorise.Builtins
15 import Vectorise.Generic.Description
16 import CoreSyn
17 import CoreUtils
18 import FamInstEnv
19 import MkCore ( mkWildCase, mkCoreLet )
20 import TyCon
21 import CoAxiom
22 import Type
23 import OccName
24 import Coercion
25 import MkId
26 import FamInst
27 import TysPrim( intPrimTy )
28
29 import DynFlags
30 import FastString
31 import MonadUtils
32 import Control.Monad
33 import Outputable
34
35
36 buildPReprTyCon :: TyCon -> TyCon -> SumRepr -> VM FamInst
37 buildPReprTyCon orig_tc vect_tc repr
38 = do name <- mkLocalisedName mkPReprTyConOcc (tyConName orig_tc)
39 rhs_ty <- sumReprType repr
40 prepr_tc <- builtin preprTyCon
41 let axiom = mkSingleCoAxiom name tyvars prepr_tc instTys rhs_ty
42 liftDs $ newFamInst SynFamilyInst axiom
43 where
44 tyvars = tyConTyVars vect_tc
45 instTys = [mkTyConApp vect_tc . mkTyVarTys $ tyConTyVars vect_tc]
46
47 -- buildPAScAndMethods --------------------------------------------------------
48
49 -- | This says how to build the PR superclass and methods of PA
50 -- Recall the definition of the PA class:
51 --
52 -- @
53 -- class class PR (PRepr a) => PA a where
54 -- toPRepr :: a -> PRepr a
55 -- fromPRepr :: PRepr a -> a
56 --
57 -- toArrPRepr :: PData a -> PData (PRepr a)
58 -- fromArrPRepr :: PData (PRepr a) -> PData a
59 --
60 -- toArrPReprs :: PDatas a -> PDatas (PRepr a)
61 -- fromArrPReprs :: PDatas (PRepr a) -> PDatas a
62 -- @
63 --
64 type PAInstanceBuilder
65 = TyCon -- ^ Vectorised TyCon
66 -> CoAxiom Unbranched
67 -- ^ Coercion to the representation TyCon
68 -> TyCon -- ^ 'PData' TyCon
69 -> TyCon -- ^ 'PDatas' TyCon
70 -> SumRepr -- ^ Description of generic representation.
71 -> VM CoreExpr -- ^ Instance function.
72
73
74 buildPAScAndMethods :: VM [(String, PAInstanceBuilder)]
75 buildPAScAndMethods
76 = return [ ("toPRepr", buildToPRepr)
77 , ("fromPRepr", buildFromPRepr)
78 , ("toArrPRepr", buildToArrPRepr)
79 , ("fromArrPRepr", buildFromArrPRepr)
80 , ("toArrPReprs", buildToArrPReprs)
81 , ("fromArrPReprs", buildFromArrPReprs)]
82
83
84 -- buildToPRepr ---------------------------------------------------------------
85 -- | Build the 'toRepr' method of the PA class.
86 buildToPRepr :: PAInstanceBuilder
87 buildToPRepr vect_tc repr_ax _ _ repr
88 = do let arg_ty = mkTyConApp vect_tc ty_args
89
90 -- Get the representation type of the argument.
91 res_ty <- mkPReprType arg_ty
92
93 -- Var to bind the argument
94 arg <- newLocalVar (fsLit "x") arg_ty
95
96 -- Build the expression to convert the argument to the generic representation.
97 result <- to_sum (Var arg) arg_ty res_ty repr
98
99 return $ Lam arg result
100 where
101 ty_args = mkTyVarTys (tyConTyVars vect_tc)
102
103 wrap_repr_inst = wrapTypeUnbranchedFamInstBody repr_ax ty_args
104
105 -- CoreExp to convert the given argument to the generic representation.
106 -- We start by doing a case branch on the possible data constructors.
107 to_sum :: CoreExpr -> Type -> Type -> SumRepr -> VM CoreExpr
108 to_sum _ _ _ EmptySum
109 = do void <- builtin voidVar
110 return $ wrap_repr_inst $ Var void
111
112 to_sum arg arg_ty res_ty (UnarySum r)
113 = do (pat, vars, body) <- con_alt r
114 return $ mkWildCase arg arg_ty res_ty
115 [(pat, vars, wrap_repr_inst body)]
116
117 to_sum arg arg_ty res_ty (Sum { repr_sum_tc = sum_tc
118 , repr_con_tys = tys
119 , repr_cons = cons })
120 = do alts <- mapM con_alt cons
121 let alts' = [(pat, vars, wrap_repr_inst
122 $ mkConApp sum_con (map Type tys ++ [body]))
123 | ((pat, vars, body), sum_con)
124 <- zip alts (tyConDataCons sum_tc)]
125 return $ mkWildCase arg arg_ty res_ty alts'
126
127 con_alt (ConRepr con r)
128 = do (vars, body) <- to_prod r
129 return (DataAlt con, vars, body)
130
131 -- CoreExp to convert data constructor fields to the generic representation.
132 to_prod :: ProdRepr -> VM ([Var], CoreExpr)
133 to_prod EmptyProd
134 = do void <- builtin voidVar
135 return ([], Var void)
136
137 to_prod (UnaryProd comp)
138 = do var <- newLocalVar (fsLit "x") (compOrigType comp)
139 body <- to_comp (Var var) comp
140 return ([var], body)
141
142 to_prod (Prod { repr_tup_tc = tup_tc
143 , repr_comp_tys = tys
144 , repr_comps = comps })
145 = do vars <- newLocalVars (fsLit "x") (map compOrigType comps)
146 exprs <- zipWithM to_comp (map Var vars) comps
147 let [tup_con] = tyConDataCons tup_tc
148 return (vars, mkConApp tup_con (map Type tys ++ exprs))
149
150 -- CoreExp to convert a data constructor component to the generic representation.
151 to_comp :: CoreExpr -> CompRepr -> VM CoreExpr
152 to_comp expr (Keep _ _) = return expr
153 to_comp expr (Wrap ty) = wrapNewTypeBodyOfWrap expr ty
154
155
156 -- buildFromPRepr -------------------------------------------------------------
157
158 -- |Build the 'fromPRepr' method of the PA class.
159 --
160 buildFromPRepr :: PAInstanceBuilder
161 buildFromPRepr vect_tc repr_ax _ _ repr
162 = do
163 arg_ty <- mkPReprType res_ty
164 arg <- newLocalVar (fsLit "x") arg_ty
165
166 result <- from_sum (unwrapTypeUnbranchedFamInstScrut repr_ax ty_args (Var arg))
167 repr
168 return $ Lam arg result
169 where
170 ty_args = mkTyVarTys (tyConTyVars vect_tc)
171 res_ty = mkTyConApp vect_tc ty_args
172
173 from_sum _ EmptySum
174 = do dummy <- builtin fromVoidVar
175 return $ Var dummy `App` Type res_ty
176
177 from_sum expr (UnarySum r) = from_con expr r
178 from_sum expr (Sum { repr_sum_tc = sum_tc
179 , repr_con_tys = tys
180 , repr_cons = cons })
181 = do vars <- newLocalVars (fsLit "x") tys
182 es <- zipWithM from_con (map Var vars) cons
183 return $ mkWildCase expr (exprType expr) res_ty
184 [(DataAlt con, [var], e)
185 | (con, var, e) <- zip3 (tyConDataCons sum_tc) vars es]
186
187 from_con expr (ConRepr con r)
188 = from_prod expr (mkConApp con $ map Type ty_args) r
189
190 from_prod _ con EmptyProd = return con
191 from_prod expr con (UnaryProd r)
192 = do e <- from_comp expr r
193 return $ con `App` e
194
195 from_prod expr con (Prod { repr_tup_tc = tup_tc
196 , repr_comp_tys = tys
197 , repr_comps = comps
198 })
199 = do vars <- newLocalVars (fsLit "y") tys
200 es <- zipWithM from_comp (map Var vars) comps
201 let [tup_con] = tyConDataCons tup_tc
202 return $ mkWildCase expr (exprType expr) res_ty
203 [(DataAlt tup_con, vars, con `mkApps` es)]
204
205 from_comp expr (Keep _ _) = return expr
206 from_comp expr (Wrap ty) = unwrapNewTypeBodyOfWrap expr ty
207
208
209 -- buildToArrRepr -------------------------------------------------------------
210
211 -- |Build the 'toArrRepr' method of the PA class.
212 --
213 buildToArrPRepr :: PAInstanceBuilder
214 buildToArrPRepr vect_tc repr_co pdata_tc _ r
215 = do arg_ty <- mkPDataType el_ty
216 res_ty <- mkPDataType =<< mkPReprType el_ty
217 arg <- newLocalVar (fsLit "xs") arg_ty
218
219 pdata_co <- mkBuiltinCo pdataTyCon
220 let co = mkAppCo pdata_co
221 . mkSymCo
222 $ mkUnbranchedAxInstCo Nominal repr_co ty_args
223
224 scrut = unwrapFamInstScrut pdata_tc ty_args (Var arg)
225
226 (vars, result) <- to_sum r
227
228 return . Lam arg
229 $ mkWildCase scrut (mkTyConApp pdata_tc ty_args) res_ty
230 [(DataAlt pdata_dc, vars, mkCast result co)]
231 where
232 ty_args = mkTyVarTys $ tyConTyVars vect_tc
233 el_ty = mkTyConApp vect_tc ty_args
234 [pdata_dc] = tyConDataCons pdata_tc
235
236 to_sum ss
237 = case ss of
238 EmptySum -> builtin pvoidVar >>= \pvoid -> return ([], Var pvoid)
239 UnarySum r -> to_con r
240 Sum{}
241 -> do let psum_tc = repr_psum_tc ss
242 let [psum_con] = tyConDataCons psum_tc
243 (vars, exprs) <- mapAndUnzipM to_con (repr_cons ss)
244 sel <- newLocalVar (fsLit "sel") (repr_sel_ty ss)
245 return ( sel : concat vars
246 , wrapFamInstBody psum_tc (repr_con_tys ss)
247 $ mkConApp psum_con
248 $ map Type (repr_con_tys ss) ++ (Var sel : exprs))
249
250 to_prod ss
251 = case ss of
252 EmptyProd -> builtin pvoidVar >>= \pvoid -> return ([], Var pvoid)
253 UnaryProd r
254 -> do pty <- mkPDataType (compOrigType r)
255 var <- newLocalVar (fsLit "x") pty
256 expr <- to_comp (Var var) r
257 return ([var], expr)
258 Prod{}
259 -> do let [ptup_con] = tyConDataCons (repr_ptup_tc ss)
260 ptys <- mapM (mkPDataType . compOrigType) (repr_comps ss)
261 vars <- newLocalVars (fsLit "x") ptys
262 exprs <- zipWithM to_comp (map Var vars) (repr_comps ss)
263 return ( vars
264 , wrapFamInstBody (repr_ptup_tc ss) (repr_comp_tys ss)
265 $ mkConApp ptup_con
266 $ map Type (repr_comp_tys ss) ++ exprs)
267
268 to_con (ConRepr _ r) = to_prod r
269
270 to_comp expr (Keep _ _) = return expr
271 to_comp expr (Wrap ty) = wrapNewTypeBodyOfPDataWrap expr ty
272
273
274 -- buildFromArrPRepr ----------------------------------------------------------
275
276 -- |Build the 'fromArrPRepr' method for the PA class.
277 --
278 buildFromArrPRepr :: PAInstanceBuilder
279 buildFromArrPRepr vect_tc repr_co pdata_tc _ r
280 = do arg_ty <- mkPDataType =<< mkPReprType el_ty
281 res_ty <- mkPDataType el_ty
282 arg <- newLocalVar (fsLit "xs") arg_ty
283
284 pdata_co <- mkBuiltinCo pdataTyCon
285 let co = mkAppCo pdata_co
286 $ mkUnbranchedAxInstCo Nominal repr_co var_tys
287
288 let scrut = mkCast (Var arg) co
289
290 let mk_result args
291 = wrapFamInstBody pdata_tc var_tys
292 $ mkConApp pdata_con
293 $ map Type var_tys ++ args
294
295 (expr, _) <- fixV $ \ ~(_, args) ->
296 from_sum res_ty (mk_result args) scrut r
297
298 return $ Lam arg expr
299 where
300 var_tys = mkTyVarTys $ tyConTyVars vect_tc
301 el_ty = mkTyConApp vect_tc var_tys
302 [pdata_con] = tyConDataCons pdata_tc
303
304 from_sum res_ty res expr ss
305 = case ss of
306 EmptySum -> return (res, [])
307 UnarySum r -> from_con res_ty res expr r
308 Sum {}
309 -> do let psum_tc = repr_psum_tc ss
310 let [psum_con] = tyConDataCons psum_tc
311 sel <- newLocalVar (fsLit "sel") (repr_sel_ty ss)
312 ptys <- mapM mkPDataType (repr_con_tys ss)
313 vars <- newLocalVars (fsLit "xs") ptys
314 (res', args) <- fold from_con res_ty res (map Var vars) (repr_cons ss)
315 let scrut = unwrapFamInstScrut psum_tc (repr_con_tys ss) expr
316 let body = mkWildCase scrut (exprType scrut) res_ty
317 [(DataAlt psum_con, sel : vars, res')]
318 return (body, Var sel : args)
319
320 from_prod res_ty res expr ss
321 = case ss of
322 EmptyProd -> return (res, [])
323 UnaryProd r -> from_comp res_ty res expr r
324 Prod {}
325 -> do let ptup_tc = repr_ptup_tc ss
326 let [ptup_con] = tyConDataCons ptup_tc
327 ptys <- mapM mkPDataType (repr_comp_tys ss)
328 vars <- newLocalVars (fsLit "ys") ptys
329 (res', args) <- fold from_comp res_ty res (map Var vars) (repr_comps ss)
330 let scrut = unwrapFamInstScrut ptup_tc (repr_comp_tys ss) expr
331 let body = mkWildCase scrut (exprType scrut) res_ty
332 [(DataAlt ptup_con, vars, res')]
333 return (body, args)
334
335 from_con res_ty res expr (ConRepr _ r) = from_prod res_ty res expr r
336
337 from_comp _ res expr (Keep _ _) = return (res, [expr])
338 from_comp _ res expr (Wrap ty) = do { expr' <- unwrapNewTypeBodyOfPDataWrap expr ty
339 ; return (res, [expr'])
340 }
341
342 fold f res_ty res exprs rs
343 = foldrM f' (res, []) (zip exprs rs)
344 where
345 f' (expr, r) (res, args)
346 = do (res', args') <- f res_ty res expr r
347 return (res', args' ++ args)
348
349
350 -- buildToArrPReprs -----------------------------------------------------------
351 -- | Build the 'toArrPReprs' instance for the PA class.
352 -- This converts a PData of elements into the generic representation.
353 buildToArrPReprs :: PAInstanceBuilder
354 buildToArrPReprs vect_tc repr_co _ pdatas_tc r
355 = do
356 -- The argument type of the instance.
357 -- eg: 'PDatas (Tree a b)'
358 arg_ty <- mkPDatasType el_ty
359
360 -- The result type.
361 -- eg: 'PDatas (PRepr (Tree a b))'
362 res_ty <- mkPDatasType =<< mkPReprType el_ty
363
364 -- Variable to bind the argument to the instance
365 -- eg: (xss :: PDatas (Tree a b))
366 varg <- newLocalVar (fsLit "xss") arg_ty
367
368 -- Coercion to case between the (PRepr a) type and its instance.
369 pdatas_co <- mkBuiltinCo pdatasTyCon
370 let co = mkAppCo pdatas_co
371 . mkSymCo
372 $ mkUnbranchedAxInstCo Nominal repr_co ty_args
373
374 let scrut = unwrapFamInstScrut pdatas_tc ty_args (Var varg)
375 (vars, result) <- to_sum r
376
377 return $ Lam varg
378 $ mkWildCase scrut (mkTyConApp pdatas_tc ty_args) res_ty
379 [(DataAlt pdatas_dc, vars, mkCast result co)]
380
381 where
382 -- The element type of the argument.
383 -- eg: 'Tree a b'.
384 ty_args = mkTyVarTys $ tyConTyVars vect_tc
385 el_ty = mkTyConApp vect_tc ty_args
386
387 -- PDatas data constructor
388 [pdatas_dc] = tyConDataCons pdatas_tc
389
390 to_sum ss
391 = case ss of
392 -- We can't convert data types with no data.
393 -- See Note: [Empty PDatas].
394 EmptySum -> do dflags <- getDynFlags
395 return ([], errorEmptyPDatas dflags el_ty)
396 UnarySum r -> do dflags <- getDynFlags
397 to_con (errorEmptyPDatas dflags el_ty) r
398
399 Sum{}
400 -> do let psums_tc = repr_psums_tc ss
401 let [psums_con] = tyConDataCons psums_tc
402 sels <- newLocalVar (fsLit "sels") (repr_sels_ty ss)
403
404 -- Take the number of selectors to serve as the length of
405 -- and PDatas Void arrays in the product. See Note [Empty PDatas].
406 let xSums = App (repr_selsLength_v ss) (Var sels)
407
408 xSums_var <- newLocalVar (fsLit "xsum") intPrimTy
409
410 (vars, exprs) <- mapAndUnzipM (to_con xSums_var) (repr_cons ss)
411 return ( sels : concat vars
412 , wrapFamInstBody psums_tc (repr_con_tys ss)
413 $ mkCoreLet (NonRec xSums_var xSums)
414 -- mkCoreLet ensures that the let/app invariant holds
415 $ mkConApp psums_con
416 $ map Type (repr_con_tys ss) ++ (Var sels : exprs))
417
418 to_prod xSums ss
419 = case ss of
420 EmptyProd
421 -> do pvoids <- builtin pvoidsVar
422 return ([], App (Var pvoids) (Var xSums) )
423
424 UnaryProd r
425 -> do pty <- mkPDatasType (compOrigType r)
426 var <- newLocalVar (fsLit "x") pty
427 expr <- to_comp (Var var) r
428 return ([var], expr)
429
430 Prod{}
431 -> do let [ptups_con] = tyConDataCons (repr_ptups_tc ss)
432 ptys <- mapM (mkPDatasType . compOrigType) (repr_comps ss)
433 vars <- newLocalVars (fsLit "x") ptys
434 exprs <- zipWithM to_comp (map Var vars) (repr_comps ss)
435 return ( vars
436 , wrapFamInstBody (repr_ptups_tc ss) (repr_comp_tys ss)
437 $ mkConApp ptups_con
438 $ map Type (repr_comp_tys ss) ++ exprs)
439
440 to_con xSums (ConRepr _ r)
441 = to_prod xSums r
442
443 to_comp expr (Keep _ _) = return expr
444 to_comp expr (Wrap ty) = wrapNewTypeBodyOfPDatasWrap expr ty
445
446
447 -- buildFromArrPReprs ---------------------------------------------------------
448 buildFromArrPReprs :: PAInstanceBuilder
449 buildFromArrPReprs vect_tc repr_co _ pdatas_tc r
450 = do
451 -- The argument type of the instance.
452 -- eg: 'PDatas (PRepr (Tree a b))'
453 arg_ty <- mkPDatasType =<< mkPReprType el_ty
454
455 -- The result type.
456 -- eg: 'PDatas (Tree a b)'
457 res_ty <- mkPDatasType el_ty
458
459 -- Variable to bind the argument to the instance
460 -- eg: (xss :: PDatas (PRepr (Tree a b)))
461 varg <- newLocalVar (fsLit "xss") arg_ty
462
463 -- Build the coercion between PRepr and the instance type
464 pdatas_co <- mkBuiltinCo pdatasTyCon
465 let co = mkAppCo pdatas_co
466 $ mkUnbranchedAxInstCo Nominal repr_co var_tys
467
468 let scrut = mkCast (Var varg) co
469
470 let mk_result args
471 = wrapFamInstBody pdatas_tc var_tys
472 $ mkConApp pdatas_con
473 $ map Type var_tys ++ args
474
475 (expr, _) <- fixV $ \ ~(_, args) ->
476 from_sum res_ty (mk_result args) scrut r
477
478 return $ Lam varg expr
479 where
480 -- The element type of the argument.
481 -- eg: 'Tree a b'.
482 ty_args = mkTyVarTys $ tyConTyVars vect_tc
483 el_ty = mkTyConApp vect_tc ty_args
484
485 var_tys = mkTyVarTys $ tyConTyVars vect_tc
486 [pdatas_con] = tyConDataCons pdatas_tc
487
488 from_sum res_ty res expr ss
489 = case ss of
490 -- We can't convert data types with no data.
491 -- See Note: [Empty PDatas].
492 EmptySum -> do dflags <- getDynFlags
493 return (res, errorEmptyPDatas dflags el_ty)
494 UnarySum r -> from_con res_ty res expr r
495
496 Sum {}
497 -> do let psums_tc = repr_psums_tc ss
498 let [psums_con] = tyConDataCons psums_tc
499 sel <- newLocalVar (fsLit "sels") (repr_sels_ty ss)
500 ptys <- mapM mkPDatasType (repr_con_tys ss)
501 vars <- newLocalVars (fsLit "xs") ptys
502 (res', args) <- fold from_con res_ty res (map Var vars) (repr_cons ss)
503 let scrut = unwrapFamInstScrut psums_tc (repr_con_tys ss) expr
504 let body = mkWildCase scrut (exprType scrut) res_ty
505 [(DataAlt psums_con, sel : vars, res')]
506 return (body, Var sel : args)
507
508 from_prod res_ty res expr ss
509 = case ss of
510 EmptyProd -> return (res, [])
511 UnaryProd r -> from_comp res_ty res expr r
512 Prod {}
513 -> do let ptups_tc = repr_ptups_tc ss
514 let [ptups_con] = tyConDataCons ptups_tc
515 ptys <- mapM mkPDatasType (repr_comp_tys ss)
516 vars <- newLocalVars (fsLit "ys") ptys
517 (res', args) <- fold from_comp res_ty res (map Var vars) (repr_comps ss)
518 let scrut = unwrapFamInstScrut ptups_tc (repr_comp_tys ss) expr
519 let body = mkWildCase scrut (exprType scrut) res_ty
520 [(DataAlt ptups_con, vars, res')]
521 return (body, args)
522
523 from_con res_ty res expr (ConRepr _ r)
524 = from_prod res_ty res expr r
525
526 from_comp _ res expr (Keep _ _) = return (res, [expr])
527 from_comp _ res expr (Wrap ty) = do { expr' <- unwrapNewTypeBodyOfPDatasWrap expr ty
528 ; return (res, [expr'])
529 }
530
531 fold f res_ty res exprs rs
532 = foldrM f' (res, []) (zip exprs rs)
533 where
534 f' (expr, r) (res, args)
535 = do (res', args') <- f res_ty res expr r
536 return (res', args' ++ args)
537
538
539 -- Notes ----------------------------------------------------------------------
540 {-
541 Note [Empty PDatas]
542 ~~~~~~~~~~~~~~~~~~~
543 We don't support "empty" data types like the following:
544
545 data Empty0
546 data Empty1 = MkEmpty1
547 data Empty2 = MkEmpty2 Empty0
548 ...
549
550 There is no parallel data associcated with these types, so there is no where
551 to store the length of the PDatas array with our standard representation.
552
553 Enumerations like the following are ok:
554 data Bool = True | False
555
556 The native and generic representations are:
557 type instance (PDatas Bool) = VPDs:Bool Sels2
558 type instance (PDatas (Repr Bool)) = PSum2s Sels2 (PDatas Void) (PDatas Void)
559
560 To take the length of a (PDatas Bool) we take the length of the contained Sels2.
561 When converting a (PDatas Bool) to a (PDatas (Repr Bool)) we use this length to
562 initialise the two (PDatas Void) arrays.
563
564 However, with this:
565 data Empty1 = MkEmpty1
566
567 The native and generic representations would be:
568 type instance (PDatas Empty1) = VPDs:Empty1
569 type instance (PDatas (Repr Empty1)) = PVoids Int
570
571 The 'Int' argument of PVoids is supposed to store the length of the PDatas
572 array. When converting the (PDatas Empty1) to a (PDatas (Repr Empty1)) we
573 need to come up with a value for it, but there isn't one.
574
575 To fix this we'd need to add an Int field to VPDs:Empty1 as well, but that's
576 too much hassle and there's no point running a parallel computation on no
577 data anyway.
578 -}
579 errorEmptyPDatas :: DynFlags -> Type -> a
580 errorEmptyPDatas dflags tc
581 = cantVectorise dflags "Vectorise.PAMethods"
582 $ vcat [ text "Cannot vectorise data type with no parallel data " <> quotes (ppr tc)
583 , text "Data types to be vectorised must contain at least one constructor"
584 , text "with at least one field." ]