be149af9d7b3029b48254851ca8ec24cd2f97700
[ghc.git] / compiler / vectorise / Vectorise / Monad / InstEnv.hs
1 module Vectorise.Monad.InstEnv
2 ( lookupInst
3 , lookupFamInst
4 )
5 where
6
7 import Vectorise.Monad.Global
8 import Vectorise.Monad.Base
9 import Vectorise.Env
10
11 import FamInstEnv
12 import InstEnv
13 import Class
14 import Type
15 import TyCon
16 import Outputable
17
18
19 #include "HsVersions.h"
20
21
22 getInstEnv :: VM (InstEnv, InstEnv)
23 getInstEnv = readGEnv global_inst_env
24
25 getFamInstEnv :: VM FamInstEnvs
26 getFamInstEnv = readGEnv global_fam_inst_env
27
28
29 -- Look up the dfun of a class instance.
30 --
31 -- The match must be unique - ie, match exactly one instance - but the
32 -- type arguments used for matching may be more specific than those of
33 -- the class instance declaration. The found class instances must not have
34 -- any type variables in the instance context that do not appear in the
35 -- instances head (i.e., no flexi vars); for details for what this means,
36 -- see the docs at InstEnv.lookupInstEnv.
37 --
38 lookupInst :: Class -> [Type] -> VM (DFunId, [Type])
39 lookupInst cls tys
40 = do { instEnv <- getInstEnv
41 ; case lookupInstEnv instEnv cls tys of
42 ([(inst, inst_tys)], _, _)
43 | noFlexiVar -> return (instanceDFunId inst, inst_tys')
44 | otherwise -> cantVectorise "VectMonad.lookupInst: flexi var: "
45 (ppr $ mkTyConApp (classTyCon cls) tys)
46 where
47 inst_tys' = [ty | Right ty <- inst_tys]
48 noFlexiVar = all isRight inst_tys
49 _other ->
50 cantVectorise "VectMonad.lookupInst: not found " (ppr cls <+> ppr tys)
51 }
52 where
53 isRight (Left _) = False
54 isRight (Right _) = True
55
56 -- Look up the representation tycon of a family instance.
57 --
58 -- The match must be unique - ie, match exactly one instance - but the
59 -- type arguments used for matching may be more specific than those of
60 -- the family instance declaration.
61 --
62 -- Return the instance tycon and its type instance. For example, if we have
63 --
64 -- lookupFamInst 'T' '[Int]' yields (':R42T', 'Int')
65 --
66 -- then we have a coercion (ie, type instance of family instance coercion)
67 --
68 -- :Co:R42T Int :: T [Int] ~ :R42T Int
69 --
70 -- which implies that :R42T was declared as 'data instance T [a]'.
71 --
72 lookupFamInst :: TyCon -> [Type] -> VM (TyCon, [Type])
73 lookupFamInst tycon tys
74 = ASSERT( isFamilyTyCon tycon )
75 do { instEnv <- getFamInstEnv
76 ; case lookupFamInstEnv instEnv tycon tys of
77 [(fam_inst, rep_tys)] -> return (famInstTyCon fam_inst, rep_tys)
78 _other ->
79 cantVectorise "VectMonad.lookupFamInst: not found: "
80 (ppr $ mkTyConApp tycon tys)
81 }