summary refs log tree commit diff stats
path: root/compiler/ast.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/ast.nim')
-rw-r--r--compiler/ast.nim29
1 files changed, 18 insertions, 11 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 514ab6a7c..bb015ea27 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -366,12 +366,8 @@ type
     tfFromGeneric,    # type is an instantiation of a generic; this is needed
                       # because for instantiations of objects, structural
                       # type equality has to be used
-    tfInstantiated,   # XXX: used to mark generic params after instantiation.
-                      # if the concrete type happens to be an implicit generic
-                      # this can lead to invalid proc signatures in the second
-                      # pass of semProcTypeNode performed after instantiation.
-                      # this won't be needed if we don't perform this redundant
-                      # second pass (stay tuned).
+    tfUnresolved,     # marks unresolved typedesc params: e.g.
+                      # proc foo(T: typedesc, list: seq[T]): var T
     tfRetType,        # marks return types in proc (used to detect type classes 
                       # used as return types for return type inference)
     tfAll,            # type class requires all constraints to be met (default)
@@ -690,6 +686,8 @@ type
                               # for record types a nkRecord node
                               # for enum types a list of symbols
                               # for tyInt it can be the int literal
+                              # for procs and tyGenericBody, it's the
+                              # formal param list
                               # else: unused
     destructor*: PSym         # destructor. warning: nil here may not necessary
                               # mean that there is no destructor.
@@ -794,6 +792,7 @@ const
   nkStrKinds* = {nkStrLit..nkTripleStrLit}
 
   skLocalVars* = {skVar, skLet, skForVar, skParam, skResult}
+  skProcKinds* = {skProc, skTemplate, skMacro, skIterator, skMethod, skConverter}
 
   lfFullExternalName* = lfParamCopy # \
     # only used when 'gCmd == cmdPretty': Indicates that the symbol has been
@@ -1053,8 +1052,8 @@ proc NewType(kind: TTypeKind, owner: PSym): PType =
   result.size = - 1
   result.align = 2            # default alignment
   result.id = getID()
-  when debugIds: 
-    RegisterId(result)        
+  when debugIds:
+    RegisterId(result)
   #if result.id < 2000 then
   #  MessageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id))
   
@@ -1091,7 +1090,6 @@ proc copyType(t: PType, owner: PSym, keepId: bool): PType =
   if keepId: 
     result.id = t.id
   else: 
-    result.id = getID()
     when debugIds: RegisterId(result)
   result.sym = t.sym          # backend-info should not be copied
   
@@ -1361,10 +1359,19 @@ proc getStrOrChar*(a: PNode): string =
 
 proc isGenericRoutine*(s: PSym): bool = 
   case s.kind
-  of skProc, skTemplate, skMacro, skIterator, skMethod, skConverter:
-    result = s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty
+  of skProcKinds:
+    result = sfFromGeneric in s.flags or
+             (s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty)
   else: nil
 
+proc skipGenericOwner*(s: PSym): PSym =
+  InternalAssert s.kind in skProcKinds
+  ## Generic instantiations are owned by their originating generic
+  ## symbol. This proc skips such owners and goes straigh to the owner
+  ## of the generic itself (the module or the enclosing proc).
+  result = if sfFromGeneric in s.flags: s.owner.owner
+           else: s.owner
+
 proc isRoutine*(s: PSym): bool {.inline.} =
   result = s.kind in {skProc, skTemplate, skMacro, skIterator, skMethod,
                       skConverter}