summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ccgexprs.nim8
-rw-r--r--compiler/ccgtypes.nim6
-rw-r--r--compiler/cgmeth.nim4
-rw-r--r--compiler/evalffi.nim6
-rw-r--r--compiler/jsgen.nim6
-rw-r--r--compiler/jstypes.nim2
-rw-r--r--compiler/sem.nim4
-rw-r--r--compiler/semexprs.nim8
-rw-r--r--compiler/semstmts.nim4
-rw-r--r--compiler/semtypes.nim22
-rw-r--r--compiler/sigmatch.nim13
-rw-r--r--compiler/types.nim17
12 files changed, 61 insertions, 39 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index a4ba412a4..eda0d23bc 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -780,7 +780,7 @@ proc genSeqElem(p: BProc, e: PNode, d: var TLoc) =
   initLocExpr(p, e.sons[1], b)
   var ty = skipTypes(a.t, abstractVarRange)
   if ty.kind in {tyRef, tyPtr}:
-    ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check:
+    ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check:
   if optBoundsCheck in p.options:
     if ty.kind == tyString:
       linefmt(p, cpsStmts,
@@ -1121,7 +1121,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
   while t.kind in {tyVar, tyPtr, tyRef}:
     if t.kind != tyVar: nilCheck = r
     r = rfmt(nil, "(*$1)", r)
-    t = skipTypes(t.sons[0], typedescInst)
+    t = skipTypes(t.lastSon, typedescInst)
   if gCmd != cmdCompileToCpp:
     while (t.kind == tyObject) and (t.sons[0] != nil):
       app(r, ~".Sup")
@@ -1737,7 +1737,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
     while t.kind in {tyVar, tyPtr, tyRef}:
       if t.kind != tyVar: nilCheck = r
       r = ropef("(*$1)", [r])
-      t = skipTypes(t.sons[0], abstractInst)
+      t = skipTypes(t.lastSon, abstractInst)
     if gCmd != cmdCompileToCpp:
       while t.kind == tyObject and t.sons[0] != nil:
         app(r, ".Sup")
@@ -1885,7 +1885,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
   of nkHiddenAddr, nkAddr: genAddr(p, n, d)
   of nkBracketExpr:
     var ty = skipTypes(n.sons[0].typ, abstractVarRange)
-    if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
+    if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
     case ty.kind
     of tyArray, tyArrayConstr: genArrayElem(p, n, d)
     of tyOpenArray, tyVarargs: genOpenArrayElem(p, n, d)
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 319d6a5c5..f51e66897 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -183,7 +183,7 @@ proc mapType(typ: PType): TCTypeKind =
       else: internalError("mapType")
   of tyRange: result = mapType(typ.sons[0])
   of tyPtr, tyVar, tyRef:
-    var base = skipTypes(typ.sons[0], typedescInst)
+    var base = skipTypes(typ.lastSon, typedescInst)
     case base.kind
     of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctPtrToArray
     else: result = ctPtr
@@ -269,7 +269,7 @@ proc fillResult(param: PSym) =
 proc getParamTypeDesc(m: BModule, t: PType, check: var TIntSet): PRope =
   when false:
     if t.Kind in {tyRef, tyPtr, tyVar}:
-      var b = skipTypes(t.sons[0], typedescInst)
+      var b = skipTypes(t.lastson, typedescInst)
       if b.kind == tySet and mapSetType(b) == ctArray:
         return getTypeDescAux(m, b, check)
   result = getTypeDescAux(m, t, check)
@@ -530,7 +530,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope =
     # C type generation into an analysis and a code generation phase somehow.
   case t.kind
   of tyRef, tyPtr, tyVar: 
-    et = getUniqueType(t.sons[0])
+    et = getUniqueType(t.lastSon)
     if et.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}: 
       # this is correct! sets have no proper base type, so we treat
       # ``var set[char]`` in `getParamTypeDesc`
diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim
index 1c5ce7a21..948541302 100644
--- a/compiler/cgmeth.nim
+++ b/compiler/cgmeth.nim
@@ -59,8 +59,8 @@ proc sameMethodBucket(a, b: PSym): bool =
       aa = skipTypes(aa, {tyGenericInst})
       bb = skipTypes(bb, {tyGenericInst})
       if (aa.kind == bb.kind) and (aa.kind in {tyVar, tyPtr, tyRef}): 
-        aa = aa.sons[0]
-        bb = bb.sons[0]
+        aa = aa.lastSon
+        bb = bb.lastSon
       else: 
         break 
     if sameType(aa, bb) or
diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim
index db78da714..f798a43ac 100644
--- a/compiler/evalffi.nim
+++ b/compiler/evalffi.nim
@@ -116,7 +116,7 @@ proc packSize(v: PNode, typ: PType): int =
     if v.kind in {nkNilLit, nkPtrLit}:
       result = sizeof(pointer)
     else:
-      result = sizeof(pointer) + packSize(v.sons[0], typ.sons[0])
+      result = sizeof(pointer) + packSize(v.sons[0], typ.lastSon)
   of tyDistinct, tyGenericInst:
     result = packSize(v, typ.sons[0])
   of tyArray, tyArrayConstr:
@@ -219,7 +219,7 @@ proc pack(v: PNode, typ: PType, res: pointer) =
         packRecCheck = 0
         globalError(v.info, "cannot map value to FFI " & typeToString(v.typ))
       inc packRecCheck
-      pack(v.sons[0], typ.sons[0], res +! sizeof(pointer))
+      pack(v.sons[0], typ.lastSon, res +! sizeof(pointer))
       dec packRecCheck
       awr(pointer, res +! sizeof(pointer))
   of tyArray, tyArrayConstr:
@@ -371,7 +371,7 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
       awi(nkPtrLit, cast[TAddress](p))
     elif n != nil and n.len == 1:
       internalAssert n.kind == nkRefTy
-      n.sons[0] = unpack(p, typ.sons[0], n.sons[0])
+      n.sons[0] = unpack(p, typ.lastSon, n.sons[0])
       result = n
     else:
       globalError(n.info, "cannot map value from FFI " & typeToString(typ))
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 0cbd4c364..a34d8f123 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -111,7 +111,7 @@ proc mapType(typ: PType): TJSTypeKind =
   let t = skipTypes(typ, abstractInst)
   case t.kind
   of tyVar, tyRef, tyPtr: 
-    if skipTypes(t.sons[0], abstractInst).kind in MappedToObject: 
+    if skipTypes(t.lastSon, abstractInst).kind in MappedToObject: 
       result = etyObject
     else: 
       result = etyBaseIndex
@@ -912,7 +912,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
 
 proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) = 
   var ty = skipTypes(n.sons[0].typ, abstractVarRange)
-  if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
+  if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
   case ty.kind
   of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
      tyVarargs:
@@ -957,7 +957,7 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
     genFieldAddr(p, n, r)
   of nkBracketExpr:
     var ty = skipTypes(n.sons[0].typ, abstractVarRange)
-    if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
+    if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
     case ty.kind
     of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
        tyVarargs:
diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim
index 6d14076e1..009fc7935 100644
--- a/compiler/jstypes.nim
+++ b/compiler/jstypes.nim
@@ -134,7 +134,7 @@ proc genTypeInfo(p: PProc, typ: PType): PRope =
               [result, toRope(ord(t.kind))])
     prepend(p.g.typeInfo, s)
     appf(p.g.typeInfo, "$1.base = $2;$n", 
-         [result, genTypeInfo(p, typ.sons[0])])
+         [result, genTypeInfo(p, typ.lastSon)])
   of tyArrayConstr, tyArray: 
     var s = ropef(
       "var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
diff --git a/compiler/sem.nim b/compiler/sem.nim
index b34972219..e7bff0665 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -118,8 +118,8 @@ proc commonType*(x, y: PType): PType =
     if a.kind in {tyRef, tyPtr}:
       k = a.kind
       if b.kind != a.kind: return x
-      a = a.sons[0]
-      b = b.sons[0]
+      a = a.lastSon
+      b = b.lastSon
     if a.kind == tyObject and b.kind == tyObject:
       result = commonSuperclass(a, b)
       # this will trigger an error later:
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 9b3b2d73e..6c1721bdd 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -155,8 +155,8 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus =
   var d = skipTypes(castDest, abstractVar)
   var s = skipTypes(src, abstractVar-{tyTypeDesc})
   while (d != nil) and (d.kind in {tyPtr, tyRef}) and (d.kind == s.kind):
-    d = base(d)
-    s = base(s)
+    d = d.lastSon
+    s = s.lastSon
   if d == nil:
     result = convNotLegal
   elif d.kind == tyObject and s.kind == tyObject:
@@ -930,7 +930,7 @@ proc makeDeref(n: PNode): PNode =
     var a = result
     result = newNodeIT(nkHiddenDeref, n.info, t.sons[0])
     addSon(result, a)
-    t = skipTypes(t.sons[0], {tyGenericInst})
+    t = skipTypes(t.lastSon, {tyGenericInst})
 
 const
   tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
@@ -1072,7 +1072,7 @@ proc semDeref(c: PContext, n: PNode): PNode =
   result = n
   var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar})
   case t.kind
-  of tyRef, tyPtr: n.typ = t.sons[0]
+  of tyRef, tyPtr: n.typ = t.lastSon
   else: result = nil
   #GlobalError(n.sons[0].info, errCircumNeedsPointer) 
 
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index c31a8a06d..2429e4183 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -817,8 +817,8 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
       var st = s.typ
       if st.kind == tyGenericBody: st = st.lastSon
       internalAssert st.kind in {tyPtr, tyRef}
-      internalAssert st.sons[0].sym == nil
-      st.sons[0].sym = newSym(skType, getIdent(s.name.s & ":ObjectType"),
+      internalAssert st.lastSon.sym == nil
+      st.lastSon.sym = newSym(skType, getIdent(s.name.s & ":ObjectType"),
                               getCurrOwner(), s.info)
 
 proc semTypeSection(c: PContext, n: PNode): PNode =
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index a563cf06c..679a01699 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -120,15 +120,23 @@ proc semVarargs(c: PContext, n: PNode, prev: PType): PType =
   else:
     localError(n.info, errXExpectsOneTypeParam, "varargs")
     addSonSkipIntLit(result, errorType(c))
-  
-proc semAnyRef(c: PContext, n: PNode, kind: TTypeKind, prev: PType): PType = 
-  if sonsLen(n) == 1:
+
+proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
+  if n.len < 1:
+    result = newConstraint(c, kind)
+  else:
+    let n = if n[0].kind == nkBracket: n[0] else: n
+    checkMinSonsLen(n, 1)
     result = newOrPrevType(kind, prev, c)
-    var base = semTypeNode(c, n.sons[0], nil)
+    # check every except the last is an object:
+    for i in 0 .. n.len-2:
+      let region = semTypeNode(c, n[i], nil)
+      if region.skipTypes({tyGenericInst}).kind notin {tyError, tyObject}:
+        message n[i].info, errGenerated, "region needs to be an object type"
+      addSonSkipIntLit(result, region)
+    var base = semTypeNode(c, n.lastSon, nil)
     addSonSkipIntLit(result, base)
-  else:
-    result = newConstraint(c, kind)
-  
+
 proc semVarType(c: PContext, n: PNode, prev: PType): PType = 
   if sonsLen(n) == 1: 
     result = newOrPrevType(tyVar, prev, c)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index b83c27d22..a713fc0e2 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -740,8 +740,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
           result = isNone     # BUGFIX!
   of tyPtr: 
     case a.kind
-    of tyPtr: 
-      result = typeRel(c, base(f), base(a))
+    of tyPtr:
+      for i in 0..min(f.len, a.len)-2:
+        if typeRel(c, f.sons[i], a.sons[i]) == isNone: return isNone
+      result = typeRel(c, f.lastSon, a.lastSon)
       if result <= isConvertible: result = isNone
       elif tfNotNil in f.flags and tfNotNil notin a.flags:
         result = isNilConversion
@@ -750,6 +752,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
   of tyRef: 
     case a.kind
     of tyRef:
+      for i in 0..min(f.len, a.len)-2:
+        if typeRel(c, f.sons[i], a.sons[i]) == isNone: return isNone
       result = typeRel(c, base(f), base(a))
       if result <= isConvertible: result = isNone
       elif tfNotNil in f.flags and tfNotNil notin a.flags:
@@ -792,8 +796,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
     of tyNil: result = f.allowsNil
     of tyString: result = isConvertible
     of tyPtr:
-      if a.sons[0].kind == tyChar: result = isConvertible
-    of tyArray: 
+      # ptr[Tag, char] is not convertible to 'cstring' for now:
+      if a.len == 1 and a.sons[0].kind == tyChar: result = isConvertible
+    of tyArray:
       if (firstOrd(a.sons[0]) == 0) and
           (skipTypes(a.sons[0], {tyRange}).kind in {tyInt..tyInt64}) and
           (a.sons[1].kind == tyChar): 
diff --git a/compiler/types.nim b/compiler/types.nim
index c80f6ff35..1de0fc103 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -508,7 +508,16 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
         if i < sonsLen(t) - 1: add(result, ", ")
     add(result, ']')
   of tyPtr, tyRef, tyVar, tyMutable, tyConst: 
-    result = typeToStr[t.kind] & typeToString(t.sons[0])
+    result = typeToStr[t.kind]
+    if t.len >= 2:
+      setLen(result, result.len-1)
+      result.add '['
+      for i in countup(0, sonsLen(t) - 1): 
+        add(result, typeToString(t.sons[i]))
+        if i < sonsLen(t) - 1: add(result, ", ")
+      result.add ']'
+    else:
+      result.add typeToString(t.sons[0])
   of tyRange:
     result = "range " & rangeToStr(t.n)
     if prefer != preferExported:
@@ -1082,9 +1091,9 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind,
         typeAllowedAux(marker, t.sons[1], skVar, flags)
   of tyRef:
     if kind == skConst: return false
-    result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
+    result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
   of tyPtr:
-    result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
+    result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
   of tyArrayConstr, tySet, tyConst, tyMutable, tyIter:
     for i in countup(0, sonsLen(t) - 1):
       result = typeAllowedAux(marker, t.sons[i], kind, flags)
@@ -1293,7 +1302,7 @@ proc baseOfDistinct*(t: PType): PType =
     var it = result
     while it.kind in {tyPtr, tyRef}:
       parent = it
-      it = it.sons[0]
+      it = it.lastSon
     if it.kind == tyDistinct:
       internalAssert parent != nil
       parent.sons[0] = it.sons[0]