From: chak
@@ -23,24 +23,117 @@
using a structure that abstracts over the concrete representation of
bound occurences of identifiers and patterns. The module TcHsSyn
- instantiates this structure for the type checker using TcRnTypes
.TcId
- to represent identifiers - in fact, a TcId
is currently
- nothing but just a synonym for a plain
+ used to represent identifiers in some signatures during type checking
+ is, in fact, nothing but a synonym for a plain
Id
.
- The interface of the type checker (and renamer) to the rest of the
- compiler is provided by renamer) to the rest of the compiler is provided
+ by TcRnDriver
.
Entire modules are processed by calling tcRnModule
and GHCi
- uses tcRnStmt
and tcRnExpr
to typecheck
- statements and expressions, respectively. Moreover,
- tcRnIface
and tcRnExtCore
are provided to
- typecheck interface files and external Core code.
+ uses tcRnStmt
, tcRnExpr
, and
+ tcRnType
to typecheck statements and expressions, and to
+ kind check types, respectively. Moreover, tcRnExtCore
is
+ provided to typecheck external Core code. Moreover,
+ tcTopSrcDecls
is used by Template Haskell - more
+ specifically by TcSplice.tc_bracket
+ - to type check the contents of declaration brackets.
+
+ The function tcRnModule
controls the complete static
+ analysis of a Haskell module. It sets up the combined renamer and type
+ checker monad, resolves all import statements, initiates the actual
+ renaming and type checking process, and finally, wraps off by processing
+ the export list.
+
+ The actual type checking and renaming process is initiated via
+ TcRnDriver.tcRnSrcDecls
, which uses a helper called
+ tc_rn_src_decls
to implement the iterative renaming and
+ type checking process required by Template
+ Haskell. However, before it invokes tc_rn_src_decls
,
+ it takes care of hi-boot files; afterwards, it simplifies type
+ constraints and zonking (see below regarding the later).
+ The function tc_rn_src_decls
partitions static analysis of
+ a whole module into multiple rounds, where the initial round is followed
+ by an additional one for each toplevel splice. It collects all
+ declarations up to the next splice into an HsDecl.HsGroup
+ to rename and type check that declaration group by calling
+ TcRnDriver.tcRnGroup
. Afterwards, it executes the
+ splice (if there are any left) and proceeds to the next group, which
+ includes the declarations produced by the splice.
+
+ The function tcRnGroup
, finally, gets down to invoke the
+ actual renaming and type checking via
+ TcRnDriver.rnTopSrcDecls
and
+ TcRnDriver.tcTopSrcDecls
, respectively. The renamer, apart
+ from renaming, computes the global type checking environment, of type
+ TcRnTypes.TcGblEnv
, which is stored in the type checking
+ monad before type checking commences.
+
+ The type checking of a declaration group, performed by
+ tcTopSrcDecls
starts by processing of the type and class
+ declarations of the current module, using the function
+ TcTyClsDecls.tcTyAndClassDecls
. This is followed by a
+ first round over instance declarations using
+ TcInstDcls.tcInstDecls1
, which in particular generates all
+ additional bindings due to the deriving process. Then come foreign
+ import declarations (TcForeign.tcForeignImports
) and
+ default declarations (TcDefaults.tcDefaults
).
+
+ Now, finally, toplevel value declarations (including derived ones) are
+ type checked using TcBinds.tcTopBinds
. Afterwards,
+ TcInstDcls.tcInstDecls2
traverses instances for the second
+ time. Type checking concludes with processing foreign exports
+ (TcForeign.tcForeignExports
) and rewrite rules
+ (TcRules.tcRules
). Finally, the global environment is
+ extended with the new bindings.
+
+ Type and class declarations are type checked in a couple of phases that
+ contain recursive dependencies - aka knots. The first knot
+ encompasses almost the whole type checking of these declarations and
+ forms the main piece of TcTyClsDecls.tcTyAndClassDecls
.
+
+ Inside this big knot, the first main operation is kind checking, which
+ again involves a knot. It is implemented by kcTyClDecls
,
+ which performs kind checking of potentially recursively-dependent type
+ and class declarations using kind variables for initially unknown kinds.
+ During processing the individual declarations some of these variables
+ will be instantiated depending on the context; the rest gets by default
+ kind *
(during zonking of the kind signatures).
+ Type synonyms are treated specially in this process, because they can
+ have an unboxed type, but they cannot be recursive. Hence, their kinds
+ are inferred in dependency order. Moreover, in contrast to class
+ declarations and other type declarations, synonyms are not entered into
+ the global environment as a global TyThing
.
+ (TypeRep.TyThing
is a sum type that combines the various
+ flavours of typish entities, such that they can be stuck into type
+ environments and similar.)
+
@@ -208,7 +301,7 @@ tau -> tyvar
-Last modified: Sat Sep 13 23:35:24 BST 2003 +Last modified: Mon May 9 11:02:20 EST 2005