summary refs log tree commit diff stats
path: root/compiler/cgmeth.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/cgmeth.nim')
-rw-r--r--compiler/cgmeth.nim53
1 files changed, 30 insertions, 23 deletions
diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim
index 833bb6fe5..ca97d0494 100644
--- a/compiler/cgmeth.nim
+++ b/compiler/cgmeth.nim
@@ -69,21 +69,23 @@ type
 proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
   result = No
   if a.name.id != b.name.id: return
-  if a.typ.len != b.typ.len:
+  if a.typ.signatureLen != b.typ.signatureLen:
     return
 
-  for i in 1..<a.typ.len:
-    var aa = a.typ[i]
-    var bb = b.typ[i]
+  var i = 0
+  for x, y in paramTypePairs(a.typ, b.typ):
+    inc i
+    var aa = x
+    var bb = y
     while true:
       aa = skipTypes(aa, {tyGenericInst, tyAlias})
       bb = skipTypes(bb, {tyGenericInst, tyAlias})
       if aa.kind == bb.kind and aa.kind in {tyVar, tyPtr, tyRef, tyLent, tySink}:
-        aa = aa.lastSon
-        bb = bb.lastSon
+        aa = aa.elementType
+        bb = bb.elementType
       else:
         break
-    if sameType(a.typ[i], b.typ[i]):
+    if sameType(x, y):
       if aa.kind == tyObject and result != Invalid:
         result = Yes
     elif aa.kind == tyObject and bb.kind == tyObject and (i == 1 or multiMethods):
@@ -102,10 +104,10 @@ proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
   if result == Yes:
     # check for return type:
     # ignore flags of return types; # bug #22673
-    if not sameTypeOrNil(a.typ[0], b.typ[0], {IgnoreFlags}):
-      if b.typ[0] != nil and b.typ[0].kind == tyUntyped:
+    if not sameTypeOrNil(a.typ.returnType, b.typ.returnType, {IgnoreFlags}):
+      if b.typ.returnType != nil and b.typ.returnType.kind == tyUntyped:
         # infer 'auto' from the base to make it consistent:
-        b.typ[0] = a.typ[0]
+        b.typ.setReturnType a.typ.returnType
       else:
         return No
 
@@ -131,8 +133,8 @@ proc createDispatcher(s: PSym; g: ModuleGraph; idgen: IdGenerator): PSym =
   if disp.typ.callConv == ccInline: disp.typ.callConv = ccNimCall
   disp.ast = copyTree(s.ast)
   disp.ast[bodyPos] = newNodeI(nkEmpty, s.info)
-  disp.loc.r = ""
-  if s.typ[0] != nil:
+  disp.loc.snippet = ""
+  if s.typ.returnType != nil:
     if disp.ast.len > resultPos:
       disp.ast[resultPos].sym = copySym(s.ast[resultPos].sym, idgen)
     else:
@@ -157,9 +159,14 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) =
 
 proc methodDef*(g: ModuleGraph; idgen: IdGenerator; s: PSym) =
   var witness: PSym = nil
-  if s.typ[1].owner.getModule != s.getModule and vtables in g.config.features and not g.config.isDefined("nimInternalNonVtablesTesting"):
+  if s.typ.firstParamType.owner.getModule != s.getModule and vtables in g.config.features and not
+      g.config.isDefined("nimInternalNonVtablesTesting"):
     localError(g.config, s.info, errGenerated, "method `" & s.name.s &
-          "` can be defined only in the same module with its type (" & s.typ[1].typeToString() & ")")
+          "` can be defined only in the same module with its type (" & s.typ.firstParamType.typeToString() & ")")
+  if sfImportc in s.flags:
+    localError(g.config, s.info, errGenerated, "method `" & s.name.s &
+          "` is not allowed to have 'importc' pragmas")
+
   for i in 0..<g.methods.len:
     let disp = g.methods[i].dispatcher
     case sameMethodBucket(disp, s, multimethods = optMultiMethods in g.config.globalOptions)
@@ -179,10 +186,10 @@ proc methodDef*(g: ModuleGraph; idgen: IdGenerator; s: PSym) =
       if witness.isNil: witness = g.methods[i].methods[0]
   # create a new dispatcher:
   # stores the id and the position
-  if s.typ[1].skipTypes(skipPtrs).itemId notin g.bucketTable:
-    g.bucketTable[s.typ[1].skipTypes(skipPtrs).itemId] = 1
+  if s.typ.firstParamType.skipTypes(skipPtrs).itemId notin g.bucketTable:
+    g.bucketTable[s.typ.firstParamType.skipTypes(skipPtrs).itemId] = 1
   else:
-    g.bucketTable.inc(s.typ[1].skipTypes(skipPtrs).itemId)
+    g.bucketTable.inc(s.typ.firstParamType.skipTypes(skipPtrs).itemId)
   g.methods.add((methods: @[s], dispatcher: createDispatcher(s, g, idgen)))
   #echo "adding ", s.info
   if witness != nil:
@@ -203,7 +210,7 @@ proc relevantCol*(methods: seq[PSym], col: int): bool =
 
 proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int =
   result = 0
-  for col in 1..<a.typ.len:
+  for col in FirstParamAt..<a.typ.signatureLen:
     if contains(relevantCols, col):
       var aa = skipTypes(a.typ[col], skipPtrs)
       var bb = skipTypes(b.typ[col], skipPtrs)
@@ -233,13 +240,13 @@ proc sortBucket*(a: var seq[PSym], relevantCols: IntSet) =
 proc genIfDispatcher*(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet; idgen: IdGenerator): PSym =
   var base = methods[0].ast[dispatcherPos].sym
   result = base
-  var paramLen = base.typ.len
+  var paramLen = base.typ.signatureLen
   var nilchecks = newNodeI(nkStmtList, base.info)
   var disp = newNodeI(nkIfStmt, base.info)
   var ands = getSysMagic(g, unknownLineInfo, "and", mAnd)
   var iss = getSysMagic(g, unknownLineInfo, "of", mOf)
   let boolType = getSysType(g, unknownLineInfo, tyBool)
-  for col in 1..<paramLen:
+  for col in FirstParamAt..<paramLen:
     if contains(relevantCols, col):
       let param = base.typ.n[col].sym
       if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
@@ -248,7 +255,7 @@ proc genIfDispatcher*(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet;
   for meth in 0..high(methods):
     var curr = methods[meth]      # generate condition:
     var cond: PNode = nil
-    for col in 1..<paramLen:
+    for col in FirstParamAt..<paramLen:
       if contains(relevantCols, col):
         var isn = newNodeIT(nkCall, base.info, boolType)
         isn.add newSymNode(iss)
@@ -263,7 +270,7 @@ proc genIfDispatcher*(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet;
           cond = a
         else:
           cond = isn
-    let retTyp = base.typ[0]
+    let retTyp = base.typ.returnType
     let call = newNodeIT(nkCall, base.info, retTyp)
     call.add newSymNode(curr)
     for col in 1..<paramLen:
@@ -292,7 +299,7 @@ proc genIfDispatcher*(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet;
 proc generateIfMethodDispatchers*(g: ModuleGraph, idgen: IdGenerator) =
   for bucket in 0..<g.methods.len:
     var relevantCols = initIntSet()
-    for col in 1..<g.methods[bucket].methods[0].typ.len:
+    for col in FirstParamAt..<g.methods[bucket].methods[0].typ.signatureLen:
       if relevantCol(g.methods[bucket].methods, col): incl(relevantCols, col)
       if optMultiMethods notin g.config.globalOptions:
         # if multi-methods are not enabled, we are interested only in the first field