summary refs log tree commit diff stats
path: root/compiler/semstmts.nim
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-08-22 19:22:28 +0300
committerZahary Karadjov <zahary@gmail.com>2013-08-23 01:10:20 +0300
commitfee2a7ecfa883d100e1177b1cc7d738c6cfeaa83 (patch)
tree3e78d3bb91a49552d746192296f1c327942e3ccb /compiler/semstmts.nim
parenta8c8a85135e73777ea2c115bf1352456c1dd69aa (diff)
downloadNim-fee2a7ecfa883d100e1177b1cc7d738c6cfeaa83.tar.gz
Experimental support for delayed instantiation of generics
This postpones the semantic pass over the generic's body until
the generic is instantiated. There are several pros and cons for
this method and the capabilities that it enables may still be possible
in the old framework if we teach it a few new trick. Such an attempt
will follow in the next commits.

pros:
1) It allows macros to be expanded during generic instantiation that
will provide the body of the generic. See ``tmacrogenerics``.
2) The instantiation code is dramatically simplified. Dealing with unknown
types in the generic's body pre-pass requires a lot of hacky code and error
silencing in semTypeNode. See ``tgenericshardcases``.

cons:
1) There is a performance penalty of roughly 5% when bootstrapping.
2) Certain errors that used to be detected in the previous pre-pass won't
be detected with the new scheme until instantiation.
Diffstat (limited to 'compiler/semstmts.nim')
-rw-r--r--compiler/semstmts.nim16
1 files changed, 10 insertions, 6 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 33c0adac1..a15b3e10a 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -729,12 +729,16 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
       # like: mydata.seq
       rawAddSon(s.typ, newTypeS(tyEmpty, c))
       s.ast = a
-      inc c.InGenericContext
-      var body = semTypeNode(c, a.sons[2], nil)
-      dec c.InGenericContext
-      if body != nil:
-        body.sym = s
-        body.size = -1 # could not be computed properly
+      when oUseLateInstantiation:
+        var body: PType = nil
+        s.typScope = c.currentScope.parent
+      else:
+        inc c.InGenericContext
+        var body = semTypeNode(c, a.sons[2], nil)
+        dec c.InGenericContext
+        if body != nil:
+          body.sym = s
+          body.size = -1 # could not be computed properly
       s.typ.sons[sonsLen(s.typ) - 1] = body
       popOwner()
       closeScope(c)