1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
|
%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[RnBinds]{Renaming and dependency analysis of bindings}
This module does renaming and dependency analysis on value bindings in
the abstract syntax. It does {\em not} do cycle-checks on class or
type-synonym declarations; those cannot be done at this stage because
they may be affected by renaming (which isn't fully worked out yet).
\begin{code}
module RnBinds (
rnTopBinds, rnTopMonoBinds,
rnMethodBinds, renameSigs,
rnBinds,
unknownSigErr
) where
#include "HsVersions.h"
import {-# SOURCE #-} RnSource ( rnHsSigType )
import HsSyn
import HsBinds ( eqHsSig, sigName, hsSigDoc )
import RdrHsSyn
import RnHsSyn
import RnMonad
import RnExpr ( rnMatch, rnGRHSs, rnPat, checkPrecMatch )
import RnEnv ( bindLocatedLocalsRn, lookupBndrRn,
lookupGlobalOccRn, lookupSigOccRn,
warnUnusedLocalBinds, mapFvRn, extendTyVarEnvFVRn,
FreeVars, emptyFVs, plusFV, plusFVs, unitFV, addOneFV
)
import CmdLineOpts ( DynFlag(..) )
import Digraph ( stronglyConnComp, SCC(..) )
import Name ( OccName, Name, nameOccName )
import NameSet
import RdrName ( RdrName, rdrNameOcc )
import BasicTypes ( RecFlag(..) )
import List ( partition )
import Outputable
import PrelNames ( isUnboundName )
\end{code}
-- ToDo: Put the annotations into the monad, so that they arrive in the proper
-- place and can be used when complaining.
The code tree received by the function @rnBinds@ contains definitions
in where-clauses which are all apparently mutually recursive, but which may
not really depend upon each other. For example, in the top level program
\begin{verbatim}
f x = y where a = x
y = x
\end{verbatim}
the definitions of @a@ and @y@ do not depend on each other at all.
Unfortunately, the typechecker cannot always check such definitions.
\footnote{Mycroft, A. 1984. Polymorphic type schemes and recursive
definitions. In Proceedings of the International Symposium on Programming,
Toulouse, pp. 217-39. LNCS 167. Springer Verlag.}
However, the typechecker usually can check definitions in which only the
strongly connected components have been collected into recursive bindings.
This is precisely what the function @rnBinds@ does.
ToDo: deal with case where a single monobinds binds the same variable
twice.
The vertag tag is a unique @Int@; the tags only need to be unique
within one @MonoBinds@, so that unique-Int plumbing is done explicitly
(heavy monad machinery not needed).
\begin{code}
type VertexTag = Int
type Cycle = [VertexTag]
type Edge = (VertexTag, VertexTag)
\end{code}
%************************************************************************
%* *
%* naming conventions *
%* *
%************************************************************************
\subsection[name-conventions]{Name conventions}
The basic algorithm involves walking over the tree and returning a tuple
containing the new tree plus its free variables. Some functions, such
as those walking polymorphic bindings (HsBinds) and qualifier lists in
list comprehensions (@Quals@), return the variables bound in local
environments. These are then used to calculate the free variables of the
expression evaluated in these environments.
Conventions for variable names are as follows:
\begin{itemize}
\item
new code is given a prime to distinguish it from the old.
\item
a set of variables defined in @Exp@ is written @dvExp@
\item
a set of variables free in @Exp@ is written @fvExp@
\end{itemize}
%************************************************************************
%* *
%* analysing polymorphic bindings (HsBinds, Bind, MonoBinds) *
%* *
%************************************************************************
\subsubsection[dep-HsBinds]{Polymorphic bindings}
Non-recursive expressions are reconstructed without any changes at top
level, although their component expressions may have to be altered.
However, non-recursive expressions are currently not expected as
\Haskell{} programs, and this code should not be executed.
Monomorphic bindings contain information that is returned in a tuple
(a @FlatMonoBindsInfo@) containing:
\begin{enumerate}
\item
a unique @Int@ that serves as the ``vertex tag'' for this binding.
\item
the name of a function or the names in a pattern. These are a set
referred to as @dvLhs@, the defined variables of the left hand side.
\item
the free variables of the body. These are referred to as @fvBody@.
\item
the definition's actual code. This is referred to as just @code@.
\end{enumerate}
The function @nonRecDvFv@ returns two sets of variables. The first is
the set of variables defined in the set of monomorphic bindings, while the
second is the set of free variables in those bindings.
The set of variables defined in a non-recursive binding is just the
union of all of them, as @union@ removes duplicates. However, the
free variables in each successive set of cumulative bindings is the
union of those in the previous set plus those of the newest binding after
the defined variables of the previous set have been removed.
@rnMethodBinds@ deals only with the declarations in class and
instance declarations. It expects only to see @FunMonoBind@s, and
it expects the global environment to contain bindings for the binders
(which are all class operations).
%************************************************************************
%* *
\subsubsection{ Top-level bindings}
%* *
%************************************************************************
@rnTopBinds@ assumes that the environment already
contains bindings for the binders of this particular binding.
\begin{code}
rnTopBinds :: RdrNameHsBinds -> RnMS (RenamedHsBinds, FreeVars)
rnTopBinds EmptyBinds = returnRn (EmptyBinds, emptyFVs)
rnTopBinds (MonoBind bind sigs _) = rnTopMonoBinds bind sigs
-- The parser doesn't produce other forms
rnTopMonoBinds mbinds sigs
= mapRn lookupBndrRn binder_rdr_names `thenRn` \ binder_names ->
let
bndr_name_set = mkNameSet binder_names
in
renameSigs (okBindSig bndr_name_set) sigs `thenRn` \ (siglist, sig_fvs) ->
doptRn Opt_WarnMissingSigs `thenRn` \ warnMissing ->
let
type_sig_vars = [n | Sig n _ _ <- siglist]
un_sigd_binders | warnMissing = nameSetToList (delListFromNameSet
bndr_name_set type_sig_vars)
| otherwise = []
in
mapRn_ (addWarnRn.missingSigWarn) un_sigd_binders `thenRn_`
rn_mono_binds siglist mbinds `thenRn` \ (final_binds, bind_fvs) ->
returnRn (final_binds, bind_fvs `plusFV` sig_fvs)
where
binder_rdr_names = collectMonoBinders mbinds
\end{code}
%************************************************************************
%* *
%* Nested binds
%* *
%************************************************************************
\subsubsection{Nested binds}
@rnMonoBinds@
\begin{itemize}
\item collects up the binders for this declaration group,
\item checks that they form a set
\item extends the environment to bind them to new local names
\item calls @rnMonoBinds@ to do the real work
\end{itemize}
%
\begin{code}
rnBinds :: RdrNameHsBinds
-> (RenamedHsBinds -> RnMS (result, FreeVars))
-> RnMS (result, FreeVars)
rnBinds EmptyBinds thing_inside = thing_inside EmptyBinds
rnBinds (MonoBind bind sigs _) thing_inside = rnMonoBinds bind sigs thing_inside
-- the parser doesn't produce other forms
rnMonoBinds :: RdrNameMonoBinds
-> [RdrNameSig]
-> (RenamedHsBinds -> RnMS (result, FreeVars))
-> RnMS (result, FreeVars)
rnMonoBinds mbinds sigs thing_inside -- Non-empty monobinds
= -- Extract all the binders in this group,
-- and extend current scope, inventing new names for the new binders
-- This also checks that the names form a set
bindLocatedLocalsRn (text "a binding group")
mbinders_w_srclocs $ \ new_mbinders ->
let
binder_set = mkNameSet new_mbinders
in
-- Rename the signatures
renameSigs (okBindSig binder_set) sigs `thenRn` \ (siglist, sig_fvs) ->
-- Report the fixity declarations in this group that
-- don't refer to any of the group's binders.
-- Then install the fixity declarations that do apply here
-- Notice that they scope over thing_inside too
let
fixity_sigs = [(name,sig) | FixSig sig@(FixitySig name _ _) <- siglist ]
in
extendFixityEnv fixity_sigs $
rn_mono_binds siglist mbinds `thenRn` \ (binds, bind_fvs) ->
-- Now do the "thing inside", and deal with the free-variable calculations
thing_inside binds `thenRn` \ (result,result_fvs) ->
let
all_fvs = result_fvs `plusFV` bind_fvs `plusFV` sig_fvs
unused_binders = nameSetToList (binder_set `minusNameSet` all_fvs)
in
warnUnusedLocalBinds unused_binders `thenRn_`
returnRn (result, delListFromNameSet all_fvs new_mbinders)
where
mbinders_w_srclocs = collectLocatedMonoBinders mbinds
\end{code}
%************************************************************************
%* *
\subsubsection{ MonoBinds -- the main work is done here}
%* *
%************************************************************************
@rn_mono_binds@ is used by {\em both} top-level and nested bindings.
It assumes that all variables bound in this group are already in scope.
This is done {\em either} by pass 3 (for the top-level bindings),
{\em or} by @rnMonoBinds@ (for the nested ones).
\begin{code}
rn_mono_binds :: [RenamedSig] -- Signatures attached to this group
-> RdrNameMonoBinds
-> RnMS (RenamedHsBinds, --
FreeVars) -- Free variables
rn_mono_binds siglist mbinds
=
-- Rename the bindings, returning a MonoBindsInfo
-- which is a list of indivisible vertices so far as
-- the strongly-connected-components (SCC) analysis is concerned
flattenMonoBinds siglist mbinds `thenRn` \ mbinds_info ->
-- Do the SCC analysis
let
edges = mkEdges (mbinds_info `zip` [(0::Int)..])
scc_result = stronglyConnComp edges
final_binds = foldr (ThenBinds . reconstructCycle) EmptyBinds scc_result
-- Deal with bound and free-var calculation
rhs_fvs = plusFVs [fvs | (_,fvs,_,_) <- mbinds_info]
in
returnRn (final_binds, rhs_fvs)
\end{code}
@flattenMonoBinds@ is ever-so-slightly magical in that it sticks
unique ``vertex tags'' on its output; minor plumbing required.
Sigh --- need to pass along the signatures for the group of bindings,
in case any of them \fbox{\ ???\ }
\begin{code}
flattenMonoBinds :: [RenamedSig] -- Signatures
-> RdrNameMonoBinds
-> RnMS [FlatMonoBindsInfo]
flattenMonoBinds sigs EmptyMonoBinds = returnRn []
flattenMonoBinds sigs (AndMonoBinds bs1 bs2)
= flattenMonoBinds sigs bs1 `thenRn` \ flat1 ->
flattenMonoBinds sigs bs2 `thenRn` \ flat2 ->
returnRn (flat1 ++ flat2)
flattenMonoBinds sigs (PatMonoBind pat grhss locn)
= pushSrcLocRn locn $
rnPat pat `thenRn` \ (pat', pat_fvs) ->
-- Find which things are bound in this group
let
names_bound_here = mkNameSet (collectPatBinders pat')
in
sigsForMe names_bound_here sigs `thenRn` \ sigs_for_me ->
rnGRHSs grhss `thenRn` \ (grhss', fvs) ->
returnRn
[(names_bound_here,
fvs `plusFV` pat_fvs,
PatMonoBind pat' grhss' locn,
sigs_for_me
)]
flattenMonoBinds sigs (FunMonoBind name inf matches locn)
= pushSrcLocRn locn $
lookupBndrRn name `thenRn` \ new_name ->
let
names_bound_here = unitNameSet new_name
in
sigsForMe names_bound_here sigs `thenRn` \ sigs_for_me ->
mapFvRn rnMatch matches `thenRn` \ (new_matches, fvs) ->
mapRn_ (checkPrecMatch inf new_name) new_matches `thenRn_`
returnRn
[(unitNameSet new_name,
fvs,
FunMonoBind new_name inf new_matches locn,
sigs_for_me
)]
sigsForMe names_bound_here sigs
= foldlRn check [] (filter (sigForThisGroup names_bound_here) sigs)
where
check sigs sig = case filter (eqHsSig sig) sigs of
[] -> returnRn (sig:sigs)
other -> dupSigDeclErr sig `thenRn_`
returnRn sigs
\end{code}
@rnMethodBinds@ is used for the method bindings of a class and an instance
declaration. Like @rnMonoBinds@ but without dependency analysis.
NOTA BENE: we record each {\em binder} of a method-bind group as a free variable.
That's crucial when dealing with an instance decl:
\begin{verbatim}
instance Foo (T a) where
op x = ...
\end{verbatim}
This might be the {\em sole} occurrence of @op@ for an imported class @Foo@,
and unless @op@ occurs we won't treat the type signature of @op@ in the class
decl for @Foo@ as a source of instance-decl gates. But we should! Indeed,
in many ways the @op@ in an instance decl is just like an occurrence, not
a binder.
\begin{code}
rnMethodBinds :: [Name] -- Names for generic type variables
-> RdrNameMonoBinds
-> RnMS (RenamedMonoBinds, FreeVars)
rnMethodBinds gen_tyvars EmptyMonoBinds = returnRn (EmptyMonoBinds, emptyFVs)
rnMethodBinds gen_tyvars (AndMonoBinds mb1 mb2)
= rnMethodBinds gen_tyvars mb1 `thenRn` \ (mb1', fvs1) ->
rnMethodBinds gen_tyvars mb2 `thenRn` \ (mb2', fvs2) ->
returnRn (mb1' `AndMonoBinds` mb2', fvs1 `plusFV` fvs2)
rnMethodBinds gen_tyvars (FunMonoBind name inf matches locn)
= pushSrcLocRn locn $
lookupGlobalOccRn name `thenRn` \ sel_name ->
-- We use the selector name as the binder
mapFvRn rn_match matches `thenRn` \ (new_matches, fvs) ->
mapRn_ (checkPrecMatch inf sel_name) new_matches `thenRn_`
returnRn (FunMonoBind sel_name inf new_matches locn, fvs `addOneFV` sel_name)
where
-- Gruesome; bring into scope the correct members of the generic type variables
-- See comments in RnSource.rnDecl(ClassDecl)
rn_match match@(Match _ (TypePatIn ty : _) _ _)
= extendTyVarEnvFVRn gen_tvs (rnMatch match)
where
tvs = map rdrNameOcc (extractHsTyRdrNames ty)
gen_tvs = [tv | tv <- gen_tyvars, nameOccName tv `elem` tvs]
rn_match match = rnMatch match
-- Can't handle method pattern-bindings which bind multiple methods.
rnMethodBinds gen_tyvars mbind@(PatMonoBind other_pat _ locn)
= pushSrcLocRn locn $
failWithRn (EmptyMonoBinds, emptyFVs) (methodBindErr mbind)
\end{code}
%************************************************************************
%* *
\subsection[reconstruct-deps]{Reconstructing dependencies}
%* *
%************************************************************************
This @MonoBinds@- and @ClassDecls@-specific code is segregated here,
as the two cases are similar.
\begin{code}
reconstructCycle :: SCC FlatMonoBindsInfo
-> RenamedHsBinds
reconstructCycle (AcyclicSCC (_, _, binds, sigs))
= MonoBind binds sigs NonRecursive
reconstructCycle (CyclicSCC cycle)
= MonoBind this_gp_binds this_gp_sigs Recursive
where
this_gp_binds = foldr1 AndMonoBinds [binds | (_, _, binds, _) <- cycle]
this_gp_sigs = foldr1 (++) [sigs | (_, _, _, sigs) <- cycle]
\end{code}
%************************************************************************
%* *
\subsubsection{ Manipulating FlatMonoBindInfo}
%* *
%************************************************************************
During analysis a @MonoBinds@ is flattened to a @FlatMonoBindsInfo@.
The @RenamedMonoBinds@ is always an empty bind, a pattern binding or
a function binding, and has itself been dependency-analysed and
renamed.
\begin{code}
type FlatMonoBindsInfo
= (NameSet, -- Set of names defined in this vertex
NameSet, -- Set of names used in this vertex
RenamedMonoBinds,
[RenamedSig]) -- Signatures, if any, for this vertex
mkEdges :: [(FlatMonoBindsInfo, VertexTag)] -> [(FlatMonoBindsInfo, VertexTag, [VertexTag])]
mkEdges flat_info
= [ (info, tag, dest_vertices (nameSetToList names_used))
| (info@(names_defined, names_used, mbind, sigs), tag) <- flat_info
]
where
-- An edge (v,v') indicates that v depends on v'
dest_vertices src_mentions = [ target_vertex
| ((names_defined, _, _, _), target_vertex) <- flat_info,
mentioned_name <- src_mentions,
mentioned_name `elemNameSet` names_defined
]
\end{code}
%************************************************************************
%* *
\subsubsection[dep-Sigs]{Signatures (and user-pragmas for values)}
%* *
%************************************************************************
@renameSigs@ checks for:
\begin{enumerate}
\item more than one sig for one thing;
\item signatures given for things not bound here;
\item with suitably flaggery, that all top-level things have type signatures.
\end{enumerate}
%
At the moment we don't gather free-var info from the types in
signatures. We'd only need this if we wanted to report unused tyvars.
\begin{code}
renameSigs :: (RenamedSig -> Bool) -- OK-sig predicate
-> [RdrNameSig]
-> RnMS ([RenamedSig], FreeVars)
renameSigs ok_sig [] = returnRn ([], emptyFVs) -- Common shortcut
renameSigs ok_sig sigs
= -- Rename the signatures
mapFvRn renameSig sigs `thenRn` \ (sigs', fvs) ->
-- Check for (a) duplicate signatures
-- (b) signatures for things not in this group
let
in_scope = filter is_in_scope sigs'
is_in_scope sig = case sigName sig of
Just n -> not (isUnboundName n)
Nothing -> True
(goods, bads) = partition ok_sig in_scope
in
mapRn_ unknownSigErr bads `thenRn_`
returnRn (goods, fvs)
-- We use lookupSigOccRn in the signatures, which is a little bit unsatisfactory
-- because this won't work for:
-- instance Foo T where
-- {-# INLINE op #-}
-- Baz.op = ...
-- We'll just rename the INLINE prag to refer to whatever other 'op'
-- is in scope. (I'm assuming that Baz.op isn't in scope unqualified.)
-- Doesn't seem worth much trouble to sort this.
renameSig :: Sig RdrName -> RnMS (Sig Name, FreeVars)
-- ClassOpSig is renamed elsewhere.
renameSig (Sig v ty src_loc)
= pushSrcLocRn src_loc $
lookupSigOccRn v `thenRn` \ new_v ->
rnHsSigType (quotes (ppr v)) ty `thenRn` \ (new_ty,fvs) ->
returnRn (Sig new_v new_ty src_loc, fvs `addOneFV` new_v)
renameSig (SpecInstSig ty src_loc)
= pushSrcLocRn src_loc $
rnHsSigType (text "A SPECIALISE instance pragma") ty `thenRn` \ (new_ty, fvs) ->
returnRn (SpecInstSig new_ty src_loc, fvs)
renameSig (SpecSig v ty src_loc)
= pushSrcLocRn src_loc $
lookupSigOccRn v `thenRn` \ new_v ->
rnHsSigType (quotes (ppr v)) ty `thenRn` \ (new_ty,fvs) ->
returnRn (SpecSig new_v new_ty src_loc, fvs `addOneFV` new_v)
renameSig (FixSig (FixitySig v fix src_loc))
= pushSrcLocRn src_loc $
lookupSigOccRn v `thenRn` \ new_v ->
returnRn (FixSig (FixitySig new_v fix src_loc), unitFV new_v)
renameSig (InlineSig v p src_loc)
= pushSrcLocRn src_loc $
lookupSigOccRn v `thenRn` \ new_v ->
returnRn (InlineSig new_v p src_loc, unitFV new_v)
renameSig (NoInlineSig v p src_loc)
= pushSrcLocRn src_loc $
lookupSigOccRn v `thenRn` \ new_v ->
returnRn (NoInlineSig new_v p src_loc, unitFV new_v)
\end{code}
\begin{code}
renameIE :: (RdrName -> RnMS Name) -> IE RdrName -> RnMS (IE Name, FreeVars)
renameIE lookup_occ_nm (IEVar v)
= lookup_occ_nm v `thenRn` \ new_v ->
returnRn (IEVar new_v, unitFV new_v)
renameIE lookup_occ_nm (IEThingAbs v)
= lookup_occ_nm v `thenRn` \ new_v ->
returnRn (IEThingAbs new_v, unitFV new_v)
renameIE lookup_occ_nm (IEThingAll v)
= lookup_occ_nm v `thenRn` \ new_v ->
returnRn (IEThingAll new_v, unitFV new_v)
renameIE lookup_occ_nm (IEThingWith v vs)
= lookup_occ_nm v `thenRn` \ new_v ->
mapRn lookup_occ_nm vs `thenRn` \ new_vs ->
returnRn (IEThingWith new_v new_vs, plusFVs [ unitFV x | x <- new_v:new_vs ])
renameIE lookup_occ_nm (IEModuleContents m)
= returnRn (IEModuleContents m, emptyFVs)
\end{code}
%************************************************************************
%* *
\subsection{Error messages}
%* *
%************************************************************************
\begin{code}
dupSigDeclErr sig
= pushSrcLocRn loc $
addErrRn (sep [ptext SLIT("Duplicate") <+> ptext what_it_is <> colon,
ppr sig])
where
(what_it_is, loc) = hsSigDoc sig
unknownSigErr sig
= pushSrcLocRn loc $
addErrRn (sep [ptext SLIT("Misplaced") <+> ptext what_it_is <> colon,
ppr sig])
where
(what_it_is, loc) = hsSigDoc sig
missingSigWarn var
= sep [ptext SLIT("definition but no type signature for"), quotes (ppr var)]
methodBindErr mbind
= hang (ptext SLIT("Can't handle multiple methods defined by one pattern binding"))
4 (ppr mbind)
\end{code}
|