[project @ 1998-02-03 17:11:28 by simonm]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcInstUtil.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[TcInstUtil]{Utilities for typechecking instance declarations}
5
6 The bits common to TcInstDcls and TcDeriv.
7
8 \begin{code}
9 module TcInstUtil (
10         InstInfo(..),
11         mkInstanceRelatedIds,
12         buildInstanceEnvs,
13         classDataCon
14     ) where
15
16 #include "HsVersions.h"
17
18 import RnHsSyn          ( RenamedMonoBinds, RenamedSig(..) )
19
20 import TcMonad
21 import Inst             ( InstanceMapper )
22
23 import Bag              ( bagToList, Bag )
24 import Class            ( ClassInstEnv, Class, classBigSig )
25 import Id               ( mkDictFunId, Id )
26 import SpecEnv          ( emptySpecEnv, addToSpecEnv )
27 import Maybes           ( MaybeErr(..), mkLookupFunDef )
28 import Name             ( getSrcLoc, Name )
29 import SrcLoc           ( SrcLoc )
30 import Type             ( mkSigmaTy, mkDictTy, instantiateThetaTy,
31                           ThetaType, Type
32                         )
33 import PprType          ( pprConstraint )
34 import Class            ( classTyCon )
35 import TyCon            ( tyConDataCons )
36 import TyVar            ( TyVar, zipTyVarEnv )
37 import Unique           ( Unique )
38 import Util             ( equivClasses, panic, assertPanic )
39 import Outputable
40 \end{code}
41
42     instance c => k (t tvs) where b
43
44 \begin{code}
45 data InstInfo
46   = InstInfo
47       Class             -- Class, k
48       [TyVar]           -- Type variables, tvs
49       [Type]            -- The types at which the class is being instantiated
50       ThetaType         -- inst_decl_theta: the original context, c, from the
51                         --   instance declaration.  It constrains (some of)
52                         --   the TyVars above
53       ThetaType         -- dfun_theta: the inst_decl_theta, plus one
54                         --   element for each superclass; the "Mark
55                         --   Jones optimisation"
56       Id                -- The dfun id
57       RenamedMonoBinds  -- Bindings, b
58       SrcLoc            -- Source location assoc'd with this instance's defn
59       [RenamedSig]      -- User pragmas recorded for generating specialised instances
60 \end{code}
61
62
63 %************************************************************************
64 %*                                                                      *
65 \subsection{Creating instance related Ids}
66 %*                                                                      *
67 %************************************************************************
68
69 A tiny function which doesn't belong anywhere else.
70 It makes a nasty mutual-recursion knot if you put it in Class.
71
72 \begin{code}
73 classDataCon :: Class -> Id
74 classDataCon clas = case tyConDataCons (classTyCon clas) of
75                       (dict_constr:no_more) -> ASSERT( null no_more ) dict_constr 
76 \end{code}                    
77
78 %************************************************************************
79 %*                                                                      *
80 \subsection{Creating instance related Ids}
81 %*                                                                      *
82 %************************************************************************
83
84 \begin{code}
85 mkInstanceRelatedIds :: Name            -- Name to use for the dict fun;
86                      -> Class 
87                      -> [TyVar]
88                      -> [Type]
89                      -> ThetaType
90                      -> (Id, ThetaType)
91
92 mkInstanceRelatedIds dfun_name clas inst_tyvars inst_tys inst_decl_theta
93   = (dfun_id, dfun_theta)
94   where
95     (class_tyvars, sc_theta, _, _, _) = classBigSig clas
96     sc_theta' = instantiateThetaTy (zipTyVarEnv class_tyvars inst_tys) sc_theta
97
98     dfun_theta = case inst_decl_theta of
99                         []    -> []     -- If inst_decl_theta is empty, then we don't
100                                         -- want to have any dict arguments, so that we can
101                                         -- expose the constant methods.
102
103                         other -> inst_decl_theta ++ sc_theta'
104                                         -- Otherwise we pass the superclass dictionaries to
105                                         -- the dictionary function; the Mark Jones optimisation.
106
107     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
108
109     dfun_id = mkDictFunId dfun_name dfun_ty clas inst_tys
110 \end{code}
111
112
113 %************************************************************************
114 %*                                                                      *
115 \subsection{Converting instance info into suitable InstEnvs}
116 %*                                                                      *
117 %************************************************************************
118
119 \begin{code}
120 buildInstanceEnvs :: Bag InstInfo
121                   -> NF_TcM s InstanceMapper
122
123 buildInstanceEnvs info
124   = let
125         icmp :: InstInfo -> InstInfo -> Ordering
126         (InstInfo c1 _ _ _ _ _ _ _ _) `icmp` (InstInfo c2 _ _ _ _ _ _ _ _)
127           = c1 `compare` c2
128
129         info_by_class = equivClasses icmp (bagToList info)
130     in
131     mapNF_Tc buildInstanceEnv info_by_class    `thenNF_Tc` \ inst_env_entries ->
132     let
133         class_lookup_fn = mkLookupFunDef (==) inst_env_entries emptySpecEnv
134     in
135     returnNF_Tc class_lookup_fn
136 \end{code}
137
138 \begin{code}
139 buildInstanceEnv :: [InstInfo]          -- Non-empty, and all for same class
140                  -> NF_TcM s (Class, ClassInstEnv)
141
142 buildInstanceEnv inst_infos@((InstInfo clas _ _ _ _ _ _ _ _) : _)
143   = foldrNF_Tc addClassInstance
144             emptySpecEnv
145             inst_infos                          `thenNF_Tc` \ class_inst_env ->
146     returnNF_Tc (clas, class_inst_env)
147 \end{code}
148
149 @addClassInstance@ adds the appropriate stuff to the @ClassInstEnv@
150 based on information from a single instance declaration.  It complains
151 about any overlap with an existing instance.
152
153 \begin{code}
154 addClassInstance
155     :: InstInfo
156     -> ClassInstEnv
157     -> NF_TcM s ClassInstEnv
158
159 addClassInstance 
160     (InstInfo clas inst_tyvars inst_tys _ _ 
161               dfun_id _ src_loc _)
162     class_inst_env
163   =     -- Add the instance to the class's instance environment
164     case addToSpecEnv class_inst_env inst_tys dfun_id of
165         Failed (ty', dfun_id')    -> addErrTc (dupInstErr clas (inst_tys, src_loc) 
166                                                                (ty', getSrcLoc dfun_id'))
167                                                 `thenNF_Tc_`
168                                      returnNF_Tc class_inst_env
169
170         Succeeded class_inst_env' -> returnNF_Tc class_inst_env'
171 \end{code}
172
173 \begin{code}
174 dupInstErr clas info1@(tys1, locn1) info2@(tys2, locn2)
175         -- Overlapping/duplicate instances for given class; msg could be more glamourous
176   = hang (ptext SLIT("Duplicate or overlapping instance declarations"))
177          4 (sep [ptext SLIT("for") <+> quotes (pprConstraint clas tys1),
178                  nest 4 (sep [ptext SLIT("at")  <+> ppr locn1,
179                               ptext SLIT("and") <+> ppr locn2])])
180 \end{code}