[project @ 1997-05-18 22:53:47 by sof]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcEnv.lhs
1 \begin{code}
2 #include "HsVersions.h"
3
4 module TcEnv(
5         TcEnv, 
6
7         initEnv, getEnv_LocalIds, getEnv_TyCons, getEnv_Classes,
8         
9         tcExtendTyVarEnv, tcLookupTyVar, 
10
11         tcExtendTyConEnv, tcLookupTyCon, tcLookupTyConByKey, 
12         tcExtendClassEnv, tcLookupClass, tcLookupClassByKey,
13         tcGetTyConsAndClasses,
14
15         tcExtendGlobalValEnv, tcExtendLocalValEnv,
16         tcLookupLocalValue, tcLookupLocalValueOK, tcLookupLocalValueByKey, 
17         tcLookupGlobalValue, tcLookupGlobalValueByKey, tcLookupGlobalValueMaybe,
18         tcAddImportedIdInfo,
19         tcLookupGlobalValueByKeyMaybe, 
20
21         newMonoIds, newLocalIds, newLocalId,
22         tcGetGlobalTyVars, tcExtendGlobalTyVars
23   ) where
24
25
26 IMP_Ubiq()
27 IMPORT_DELOOPER(TcMLoop)  -- for paranoia checking
28
29 import HsTypes  ( HsTyVar(..) )
30 import Id       ( SYN_IE(Id), GenId, idType, mkUserLocal, mkUserId, replaceIdInfo, getIdInfo )
31 import PragmaInfo ( PragmaInfo(..) )
32 import TcHsSyn  ( SYN_IE(TcIdBndr), TcIdOcc(..) )
33 import TcKind   ( TcKind, newKindVars, newKindVar, tcDefaultKind, kindToTcKind, Kind )
34 import TcType   ( SYN_IE(TcType), TcMaybe, SYN_IE(TcTyVar), SYN_IE(TcTyVarSet),
35                   newTyVarTys, tcInstTyVars, zonkTcTyVars
36                 )
37 import TyVar    ( unionTyVarSets, emptyTyVarSet, tyVarSetToList, SYN_IE(TyVar) )
38 import PprType  ( GenTyVar )
39 import Type     ( tyVarsOfTypes, splitForAllTy )
40 import TyCon    ( TyCon, tyConKind, synTyConArity, SYN_IE(Arity) )
41 import Class    ( SYN_IE(Class), GenClass, classSig )
42
43 import TcMonad
44
45 import IdInfo           ( noIdInfo )
46 import Name             ( Name, OccName(..), getSrcLoc, occNameString,
47                           maybeWiredInTyConName, maybeWiredInIdName,
48                           NamedThing(..)
49                         )
50 import PprStyle
51 import Pretty
52 import Unique           ( pprUnique10{-, pprUnique ToDo:rm-}, Unique )
53 import UniqFM        
54 import Util             ( zipEqual, zipWithEqual, zipWith3Equal, zipLazy,
55                           panic, pprPanic, pprTrace
56                         )
57 import Outputable
58 \end{code}
59
60 Data type declarations
61 ~~~~~~~~~~~~~~~~~~~~~
62
63 \begin{code}
64 data TcEnv s = TcEnv
65                   (TyVarEnv s)
66                   (TyConEnv s)
67                   (ClassEnv s)
68                   (ValueEnv Id)                 -- Globals
69                   (ValueEnv (TcIdBndr s))       -- Locals
70                   (MutableVar s (TcTyVarSet s)) -- Free type variables of locals
71                                                 -- ...why mutable? see notes with tcGetGlobalTyVars
72
73 type TyVarEnv s  = UniqFM (TcKind s, TyVar)
74 type TyConEnv s  = UniqFM (TcKind s, Maybe Arity, TyCon)        -- Arity present for Synonyms only
75 type ClassEnv s  = UniqFM (TcKind s, Class)
76 type ValueEnv id = UniqFM id
77
78 initEnv :: MutableVar s (TcTyVarSet s) -> TcEnv s
79 initEnv mut = TcEnv emptyUFM emptyUFM emptyUFM emptyUFM emptyUFM mut 
80
81 getEnv_LocalIds (TcEnv _ _ _ _ ls _) = eltsUFM ls
82 getEnv_TyCons   (TcEnv _ ts _ _ _ _) = [tycon | (_, _, tycon) <- eltsUFM ts]
83 getEnv_Classes  (TcEnv _ _ cs _ _ _) = [clas  | (_, clas)     <- eltsUFM cs]
84 \end{code}
85
86 Type variable env
87 ~~~~~~~~~~~~~~~~~
88 \begin{code}
89 tcExtendTyVarEnv :: [Name] -> [(TcKind s, TyVar)] -> TcM s r -> TcM s r
90 tcExtendTyVarEnv names kinds_w_types scope
91   = tcGetEnv                                    `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
92     let
93         tve' = addListToUFM tve (zipEqual "tcTyVarScope" names kinds_w_types)
94     in
95     tcSetEnv (TcEnv tve' tce ce gve lve gtvs) scope
96 \end{code}
97
98 The Kind, TyVar, Class and TyCon envs
99 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100
101 Extending the environments.  Notice the uses of @zipLazy@, which makes sure
102 that the knot-tied TyVars, TyCons and Classes aren't looked at too early.
103
104 \begin{code}
105 tcExtendTyConEnv :: [(Name,Maybe Arity)] -> [TyCon] -> TcM s r -> TcM s r
106
107 tcExtendTyConEnv names_w_arities tycons scope
108   = newKindVars (length names_w_arities)        `thenNF_Tc` \ kinds ->
109     tcGetEnv                                    `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
110     let
111         tce' = addListToUFM tce [ (name, (kind, arity, tycon)) 
112                                 | ((name,arity), (kind,tycon))
113                                   <- zipEqual "tcExtendTyConEnv" names_w_arities (kinds `zipLazy` tycons)
114                                 ]
115     in
116     tcSetEnv (TcEnv tve tce' ce gve lve gtvs) scope     `thenTc` \ result ->
117     mapNF_Tc tcDefaultKind kinds                        `thenNF_Tc_`
118     returnTc result 
119
120
121 tcExtendClassEnv :: [Name] -> [Class] -> TcM s r -> TcM s r
122 tcExtendClassEnv names classes scope
123   = newKindVars (length names)  `thenNF_Tc` \ kinds ->
124     tcGetEnv                    `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
125     let
126         ce' = addListToUFM ce (zipEqual "tcExtendClassEnv" names (kinds `zipLazy` classes))
127     in
128     tcSetEnv (TcEnv tve tce ce' gve lve gtvs) scope     `thenTc` \ result ->
129     mapNF_Tc tcDefaultKind kinds                        `thenNF_Tc_`
130     returnTc result 
131 \end{code}
132
133
134 Looking up in the environments.
135
136 \begin{code}
137 tcLookupTyVar name
138   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
139     returnNF_Tc (lookupWithDefaultUFM tve (pprPanic "tcLookupTyVar:" (ppr PprShowAll name)) name)
140
141
142 tcLookupTyCon name
143   = case maybeWiredInTyConName name of
144         Just tc -> returnTc (kindToTcKind (tyConKind tc), synTyConArity tc, tc)
145         Nothing -> tcGetEnv             `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
146                    case lookupUFM tce name of
147                         Just stuff -> returnTc stuff
148                         Nothing    ->   -- Could be that he's using a class name as a type constructor
149                                       case lookupUFM ce name of
150                                         Just _  -> failTc (classAsTyConErr name)
151                                         Nothing -> pprPanic "tcLookupTyCon:" (ppr PprDebug name)
152
153 tcLookupTyConByKey uniq
154   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
155     let 
156        (kind, arity, tycon) =  lookupWithDefaultUFM_Directly tce 
157                                         (pprPanic "tcLookupTyCon:" (pprUnique10 uniq)) 
158                                         uniq
159     in
160     returnNF_Tc tycon
161
162 tcLookupClass name
163   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
164 --  pprTrace "tcLookupClass:" (hsep [text "Uniq:", pprUnique10 (uniqueOf name), text "; avail:", hsep (map (pprUnique10 . fst) (ufmToList ce))]) $
165 --  pprTrace "tcLookupClass:" (hsep [text "Uniq:", pprUnique (uniqueOf name), text "; avail:", hsep (map (pprUnique . fst) (ufmToList ce))]) $
166     case lookupUFM ce name of
167         Just stuff -> returnTc stuff
168         Nothing    ->   -- Could be that he's using a type constructor as a class
169                         case lookupUFM tce name of
170                           Just _ ->  failTc (tyConAsClassErr name)
171                           Nothing -> pprPanic "tcLookupClass:" (ppr PprShowAll name)
172
173 tcLookupClassByKey uniq
174   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
175     let
176         (kind, clas) = lookupWithDefaultUFM_Directly ce 
177                                 (pprPanic "tcLookupClassByKey:" (pprUnique10 uniq))
178                                 uniq
179     in
180     returnNF_Tc clas
181
182 tcGetTyConsAndClasses :: NF_TcM s ([TyCon], [Class])
183 tcGetTyConsAndClasses
184   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
185     returnNF_Tc ([tc | (_, _, tc) <- eltsUFM tce],
186                  [c  | (_, c)     <- eltsUFM ce])
187 \end{code}
188
189
190
191 Extending and consulting the value environment
192 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
193 \begin{code}
194 tcExtendGlobalValEnv ids scope
195   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
196     let
197         gve' = addListToUFM_Directly gve [(uniqueOf id, id) | id <- ids]
198     in
199     tcSetEnv (TcEnv tve tce ce gve' lve gtvs) scope
200
201 tcExtendLocalValEnv names ids scope
202   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
203     tcReadMutVar gtvs   `thenNF_Tc` \ global_tvs ->
204     let
205         lve' = addListToUFM lve (zipEqual "tcExtendLocalValEnv" names ids)
206         extra_global_tyvars = tyVarsOfTypes (map idType ids)
207         new_global_tyvars   = global_tvs `unionTyVarSets` extra_global_tyvars
208     in
209     tcNewMutVar new_global_tyvars       `thenNF_Tc` \ gtvs' ->
210
211     tcSetEnv (TcEnv tve tce ce gve lve' gtvs') scope
212 \end{code}
213
214 @tcGetGlobalTyVars@ returns a fully-zonked set of tyvars free in the environment.
215 To improve subsequent calls to the same function it writes the zonked set back into
216 the environment.
217
218 \begin{code}
219 tcGetGlobalTyVars :: NF_TcM s (TcTyVarSet s)
220 tcGetGlobalTyVars
221   = tcGetEnv                            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
222     tcReadMutVar gtvs                   `thenNF_Tc` \ global_tvs ->
223     zonkTcTyVars global_tvs             `thenNF_Tc` \ global_tvs' ->
224     tcWriteMutVar gtvs global_tvs'      `thenNF_Tc_` 
225     returnNF_Tc global_tvs'
226
227 tcExtendGlobalTyVars extra_global_tvs scope
228   = tcGetEnv                            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
229     tcReadMutVar gtvs                   `thenNF_Tc` \ global_tvs ->
230     let
231         new_global_tyvars = global_tvs `unionTyVarSets` extra_global_tvs
232     in
233     tcNewMutVar new_global_tyvars       `thenNF_Tc` \ gtvs' ->
234     tcSetEnv (TcEnv tve tce ce gve lve gtvs') scope
235 \end{code}
236
237 \begin{code}
238 tcLookupLocalValue :: Name -> NF_TcM s (Maybe (TcIdBndr s))
239 tcLookupLocalValue name
240   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
241     returnNF_Tc (lookupUFM lve name)
242
243 tcLookupLocalValueByKey :: Unique -> NF_TcM s (Maybe (TcIdBndr s))
244 tcLookupLocalValueByKey uniq
245   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
246     returnNF_Tc (lookupUFM_Directly lve uniq)
247
248 tcLookupLocalValueOK :: String -> Name -> NF_TcM s (TcIdBndr s)
249 tcLookupLocalValueOK err name
250   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
251     returnNF_Tc (lookupWithDefaultUFM lve (panic err) name)
252
253
254 tcLookupGlobalValue :: Name -> NF_TcM s Id
255
256 tcLookupGlobalValue name
257   = case maybeWiredInIdName name of
258         Just id -> returnNF_Tc id
259         Nothing -> tcGetEnv             `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
260                    returnNF_Tc (lookupWithDefaultUFM gve def name)
261   where
262     def = pprPanic "tcLookupGlobalValue:" (ppr PprDebug name)
263
264 tcLookupGlobalValueMaybe :: Name -> NF_TcM s (Maybe Id)
265
266 tcLookupGlobalValueMaybe name
267   = case maybeWiredInIdName name of
268         Just id -> returnNF_Tc (Just id)
269         Nothing -> tcGetEnv             `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
270                    returnNF_Tc (lookupUFM gve name)
271
272
273 tcLookupGlobalValueByKey :: Unique -> NF_TcM s Id
274 tcLookupGlobalValueByKey uniq
275   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
276     returnNF_Tc (lookupWithDefaultUFM_Directly gve def uniq)
277   where
278 #ifdef DEBUG
279     def = pprPanic "tcLookupGlobalValueByKey:" (pprUnique10 uniq)
280 #else
281     def = panic "tcLookupGlobalValueByKey"
282 #endif
283
284 tcLookupGlobalValueByKeyMaybe :: Unique -> NF_TcM s (Maybe Id)
285 tcLookupGlobalValueByKeyMaybe uniq
286   = tcGetEnv            `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
287     returnNF_Tc (lookupUFM_Directly gve uniq)
288
289         -- Extract the IdInfo from an IfaceSig imported from an interface file
290 tcAddImportedIdInfo :: Id -> NF_TcM s Id
291 tcAddImportedIdInfo id
292   = tcLookupGlobalValueMaybe (getName id)       `thenNF_Tc` \ maybe_id ->
293     let 
294         new_info = case maybe_id of
295                      Nothing          -> noIdInfo
296                      Just imported_id -> getIdInfo imported_id
297                 -- ToDo: could check that types are the same
298     in
299     returnNF_Tc (id `replaceIdInfo` new_info)
300         -- The Id must be returned without a data dependency on maybe_id
301 \end{code}
302
303
304 Constructing new Ids
305 ~~~~~~~~~~~~~~~~~~~~
306
307 \begin{code}
308 -- Uses the Name as the Name of the Id
309 newMonoIds :: [Name] -> Kind -> ([TcIdBndr s] -> TcM s a) -> TcM s a
310
311 newMonoIds names kind m
312   = newTyVarTys no_of_names kind        `thenNF_Tc` \ tys ->
313     let
314         new_ids       = zipWithEqual "newMonoIds" mk_id names tys
315         mk_id name ty = mkUserId name ty NoPragmaInfo
316     in
317     tcExtendLocalValEnv names new_ids (m new_ids)
318   where
319     no_of_names = length names
320
321 newLocalId :: OccName -> TcType s -> NF_TcM s (TcIdBndr s)
322 newLocalId name ty
323   = tcGetSrcLoc         `thenNF_Tc` \ loc ->
324     tcGetUnique         `thenNF_Tc` \ uniq ->
325     returnNF_Tc (mkUserLocal name uniq ty loc)
326
327 newLocalIds :: [OccName] -> [TcType s] -> NF_TcM s [TcIdBndr s]
328 newLocalIds names tys
329   = tcGetSrcLoc                 `thenNF_Tc` \ loc ->
330     tcGetUniques (length names) `thenNF_Tc` \ uniqs ->
331     let
332         new_ids            = zipWith3Equal "newLocalIds" mk_id names uniqs tys
333         mk_id name uniq ty = mkUserLocal name uniq ty loc
334     in
335     returnNF_Tc new_ids
336 \end{code}
337
338 \begin{code}
339 classAsTyConErr name sty
340   = hcat [ptext SLIT("Class used as a type constructor: "), ppr sty name]
341
342 tyConAsClassErr name sty
343   = hcat [ptext SLIT("Type constructor used as a class: "), ppr sty name]
344 \end{code}