summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorLemonBoy <LemonBoy@users.noreply.github.com>2018-10-10 21:03:18 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-10-10 21:03:18 +0200
commit0ead36dae6ab0d4525d2318d19335147ffa0bd3d (patch)
treef5aae1163acc3da37ac0341c6e2fd8bc013de259 /compiler
parent0803b532f44fc7b0039e31187af76e36828ca89d (diff)
downloadNim-0ead36dae6ab0d4525d2318d19335147ffa0bd3d.tar.gz
Unchecked arrays now have their own type (#9267)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim6
-rw-r--r--compiler/ccgexprs.nim10
-rw-r--r--compiler/ccgtypes.nim12
-rw-r--r--compiler/condsyms.nim1
-rw-r--r--compiler/jsgen.nim4
-rw-r--r--compiler/semasgn.nim4
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semtypes.nim3
-rw-r--r--compiler/sigmatch.nim9
-rw-r--r--compiler/types.nim18
-rw-r--r--compiler/vmdeps.nim6
-rw-r--r--compiler/wordrecg.nim4
12 files changed, 60 insertions, 19 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index e158ab913..36c017358 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -363,7 +363,9 @@ type
     tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64,
     tyOptAsRef, tySink, tyLent,
     tyVarargs,
-    tyUnused,
+    tyUncheckedArray
+      # An array with boundaries [0,+∞]
+
     tyProxy # used as errornous type (for idetools)
 
     tyBuiltInTypeClass
@@ -657,7 +659,7 @@ type
     mNHint, mNWarning, mNError,
     mInstantiationInfo, mGetTypeInfo,
     mNimvm, mIntDefine, mStrDefine, mRunnableExamples,
-    mException, mBuiltinType, mSymOwner
+    mException, mBuiltinType, mSymOwner, mUncheckedArray
 
 # things that we can evaluate safely at compile time, even if not asked for it:
 const
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index b9a2a052e..68cfa8b50 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -856,6 +856,15 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
   else:
     genRecordField(p, e.sons[0], d)
 
+proc genUncheckedArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
+  var a, b: TLoc
+  initLocExpr(p, x, a)
+  initLocExpr(p, y, b)
+  var ty = skipTypes(a.t, abstractVarRange + abstractPtrs + tyUserTypeClasses)
+  d.inheritLocation(a)
+  putIntoDest(p, d, n, ropecg(p.module, "$1[$2]", rdLoc(a), rdCharLoc(b)),
+              a.storage)
+
 proc genArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
   var a, b: TLoc
   initLocExpr(p, x, a)
@@ -949,6 +958,7 @@ proc genBracketExpr(p: BProc; n: PNode; d: var TLoc) =
   var ty = skipTypes(n.sons[0].typ, abstractVarRange + tyUserTypeClasses)
   if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
   case ty.kind
+  of tyUncheckedArray: genUncheckedArrayElem(p, n, n.sons[0], n.sons[1], d)
   of tyArray: genArrayElem(p, n, n.sons[0], n.sons[1], d)
   of tyOpenArray, tyVarargs: genOpenArrayElem(p, n, n.sons[0], n.sons[1], d)
   of tySequence, tyString: genSeqElem(p, n, n.sons[0], n.sons[1], d)
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 8ae050605..3420a893d 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -139,7 +139,7 @@ proc mapType(conf: ConfigRef; typ: PType): TCTypeKind =
   of tyBool: result = ctBool
   of tyChar: result = ctChar
   of tySet: result = mapSetType(conf, typ)
-  of tyOpenArray, tyArray, tyVarargs: result = ctArray
+  of tyOpenArray, tyArray, tyVarargs, tyUncheckedArray: result = ctArray
   of tyObject, tyTuple: result = ctStruct
   of tyUserTypeClasses:
     doAssert typ.isResolvedUserTypeClass
@@ -161,7 +161,7 @@ proc mapType(conf: ConfigRef; typ: PType): TCTypeKind =
   of tyPtr, tyVar, tyLent, tyRef, tyOptAsRef:
     var base = skipTypes(typ.lastSon, typedescInst)
     case base.kind
-    of tyOpenArray, tyArray, tyVarargs: result = ctPtrToArray
+    of tyOpenArray, tyArray, tyVarargs, tyUncheckedArray: result = ctPtrToArray
     of tySet:
       if mapSetType(conf, base) == ctArray: result = ctPtrToArray
       else: result = ctPtr
@@ -747,6 +747,12 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
       else:
         result = rope("TGenericSeq")
     add(result, seqStar(m))
+  of tyUncheckedArray:
+    result = getTypeName(m, origTyp, sig)
+    m.typeCache[sig] = result
+    if not isImportedType(t):
+      let foo = getTypeDescAux(m, t.sons[0], check)
+      addf(m.s[cfsTypes], "typedef $1 $2[1];$n", [foo, result])
   of tyArray:
     var n: BiggestInt = lengthOrd(m.config, t)
     if n <= 0: n = 1   # make an array of at least one element
@@ -1218,7 +1224,7 @@ proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope =
     if m.config.selectedGC >= gcMarkAndSweep:
       let markerProc = genTraverseProc(m, origType, sig)
       addf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
-  of tyPtr, tyRange: genTypeInfoAux(m, t, t, result, info)
+  of tyPtr, tyRange, tyUncheckedArray: genTypeInfoAux(m, t, t, result, info)
   of tyArray: genArrayInfo(m, t, result, info)
   of tySet: genSetInfo(m, t, result, info)
   of tyEnum: genEnumInfo(m, t, result, info)
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 62c55de3d..f353196d8 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -82,6 +82,7 @@ proc initDefines*(symbols: StringTableRef) =
   defineSymbol("nimNoNilSeqs")
   defineSymbol("nimNoNilSeqs2")
   defineSymbol("nimHasUserErrors")
+  defineSymbol("nimUncheckedArrayTyp")
 
   defineSymbol("nimHasNilSeqs")
   for f in low(Feature)..high(Feature):
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 1be8629b9..7b30a0009 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -179,7 +179,7 @@ proc mapType(typ: PType): TJSTypeKind =
   of tyFloat..tyFloat128: result = etyFloat
   of tySet: result = etyObject # map a set to a table
   of tyString, tySequence, tyOpt: result = etySeq
-  of tyObject, tyArray, tyTuple, tyOpenArray, tyVarargs:
+  of tyObject, tyArray, tyTuple, tyOpenArray, tyVarargs, tyUncheckedArray:
     result = etyObject
   of tyNil: result = etyNull
   of tyGenericParam, tyGenericBody, tyGenericInvocation,
@@ -195,7 +195,7 @@ proc mapType(typ: PType): TJSTypeKind =
     else: result = etyNone
   of tyProc: result = etyProc
   of tyCString: result = etyString
-  of tyUnused, tyOptAsRef: doAssert(false, "mapType")
+  of tyOptAsRef: doAssert(false, "mapType")
 
 proc mapType(p: PProc; typ: PType): TJSTypeKind =
   result = mapType(typ)
diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim
index f781972a5..7d6ae70de 100644
--- a/compiler/semasgn.nim
+++ b/compiler/semasgn.nim
@@ -197,7 +197,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
   case t.kind
   of tyNone, tyEmpty, tyVoid: discard
   of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString,
-      tyPtr, tyRef, tyOpt:
+      tyPtr, tyRef, tyOpt, tyUncheckedArray:
     defaultOp(c, t, body, x, y)
   of tyArray:
     if {tfHasAsgn, tfUncheckedArray} * t.flags == {tfHasAsgn}:
@@ -260,7 +260,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
   of tyOrdinal, tyRange, tyInferred,
      tyGenericInst, tyStatic, tyVar, tyLent, tyAlias, tySink:
     liftBodyAux(c, lastSon(t), body, x, y)
-  of tyUnused, tyOptAsRef: internalError(c.c.config, "liftBodyAux")
+  of tyOptAsRef: internalError(c.c.config, "liftBodyAux")
 
 proc newProcType(info: TLineInfo; owner: PSym): PType =
   result = newType(tyProc, owner)
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index e683984c5..0516fb718 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1365,7 +1365,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
 
   case arr.kind
   of tyArray, tyOpenArray, tyVarargs, tySequence, tyString,
-     tyCString:
+     tyCString, tyUncheckedArray:
     if n.len != 2: return nil
     n.sons[0] = makeDeref(n.sons[0])
     for i in countup(1, sonsLen(n) - 1):
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 5e16b009a..a96b46baa 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -1511,6 +1511,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
     case s.magic
     of mArray: result = semArray(c, n, prev)
     of mOpenArray: result = semContainer(c, n, tyOpenArray, "openarray", prev)
+    of mUncheckedArray: result = semContainer(c, n, tyUncheckedArray, "uncheckedarray", prev)
     of mRange: result = semRange(c, n, prev)
     of mSet: result = semSet(c, n, prev)
     of mOrdinal: result = semOrdinal(c, n, prev)
@@ -1751,6 +1752,8 @@ proc processMagicType(c: PContext, m: PSym) =
     rawAddSon(m.typ, newTypeS(tyNone, c))
   of mSet:
     setMagicType(c.config, m, tySet, 0)
+  of mUncheckedArray:
+    setMagicType(c.config, m, tyUncheckedArray, 0)
   of mSeq:
     setMagicType(c.config, m, tySequence, 0)
     if c.config.selectedGc == gcDestructors:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index f97ae25b7..68d992791 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -186,7 +186,7 @@ proc sumGeneric(t: PType): int =
   var isvar = 1
   while true:
     case t.kind
-    of tyGenericInst, tyArray, tyRef, tyPtr, tyDistinct,
+    of tyGenericInst, tyArray, tyRef, tyPtr, tyDistinct, tyUncheckedArray,
         tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyGenericBody,
         tyLent:
       t = t.lastSon
@@ -1199,6 +1199,11 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
         if lengthOrd(c.c.config, fRange) != lengthOrd(c.c.config, aRange):
           result = isNone
     else: discard
+  of tyUncheckedArray:
+    if a.kind == tyUncheckedArray:
+      result = typeRel(c, base(f), base(a))
+      if result < isGeneric: result = isNone
+    else: discard
   of tyOpenArray, tyVarargs:
     # varargs[expr] is special too but handled earlier. So we only need to
     # handle varargs[stmt] which is the same as varargs[typed]:
@@ -1362,6 +1367,8 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
       if a.len == 1:
         let pointsTo = a.sons[0].skipTypes(abstractInst)
         if pointsTo.kind == tyChar: result = isConvertible
+        elif pointsTo.kind == tyUncheckedArray and pointsTo.sons[0].kind == tyChar:
+          result = isConvertible
         elif pointsTo.kind == tyArray and firstOrd(nil, pointsTo.sons[0]) == 0 and
             skipTypes(pointsTo.sons[0], {tyRange}).kind in {tyInt..tyInt64} and
             pointsTo.sons[1].kind == tyChar:
diff --git a/compiler/types.nim b/compiler/types.nim
index d0eec35cf..e4e0e95ea 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -396,7 +396,7 @@ const
     "float", "float32", "float64", "float128",
     "uint", "uint8", "uint16", "uint32", "uint64",
     "opt", "sink",
-    "lent", "varargs[$1]", "unused", "Error Type",
+    "lent", "varargs[$1]", "UncheckedArray[$1]", "Error Type",
     "BuiltInTypeClass", "UserTypeClass",
     "UserTypeClassInst", "CompositeTypeClass", "inferred",
     "and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor",
@@ -526,6 +526,8 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
     else:
       result = "array[" & typeToString(t.sons[0]) & ", " &
           typeToString(t.sons[1]) & ']'
+  of tyUncheckedArray:
+    result = "uncheckedArray[" & typeToString(t.sons[0]) & ']'
   of tySequence:
     result = "seq[" & typeToString(t.sons[0]) & ']'
   of tyOpt:
@@ -638,6 +640,8 @@ proc firstOrd*(conf: ConfigRef; t: PType): BiggestInt =
   of tyOrdinal:
     if t.len > 0: result = firstOrd(conf, lastSon(t))
     else: internalError(conf, "invalid kind for firstOrd(" & $t.kind & ')')
+  of tyUncheckedArray:
+    result = 0
   else:
     internalError(conf, "invalid kind for firstOrd(" & $t.kind & ')')
     result = 0
@@ -695,6 +699,8 @@ proc lastOrd*(conf: ConfigRef; t: PType; fixedUnsigned = false): BiggestInt =
   of tyOrdinal:
     if t.len > 0: result = lastOrd(conf, lastSon(t))
     else: internalError(conf, "invalid kind for lastOrd(" & $t.kind & ')')
+  of tyUncheckedArray:
+    result = high(BiggestInt)
   else:
     internalError(conf, "invalid kind for lastOrd(" & $t.kind & ')')
     result = 0
@@ -1030,7 +1036,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
     if result and {ExactGenericParams, ExactTypeDescValues} * c.flags != {}:
       result = a.sym.position == b.sym.position
   of tyGenericInvocation, tyGenericBody, tySequence,
-     tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyLent, tySink,
+     tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyLent, tySink, tyUncheckedArray,
      tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyOpt:
     cycleCheck()
     if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n
@@ -1054,7 +1060,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
     cycleCheck()
     result = sameTypeAux(a.lastSon, b.lastSon, c)
   of tyNone: result = false
-  of tyUnused, tyOptAsRef: result = false
+  of tyOptAsRef: result = false
 
 proc sameBackendType*(x, y: PType): bool =
   var c = initSameTypeClosure()
@@ -1210,7 +1216,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
     result = nil
   of tyOrdinal:
     if kind != skParam: result = t
-  of tyGenericInst, tyDistinct, tyAlias, tyInferred:
+  of tyGenericInst, tyDistinct, tyAlias, tyInferred, tyUncheckedArray:
     result = typeAllowedAux(marker, lastSon(t), kind, flags)
   of tyRange:
     if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
@@ -1252,7 +1258,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
     # for now same as error node; we say it's a valid type as it should
     # prevent cascading errors:
     result = nil
-  of tyUnused, tyOptAsRef: result = t
+  of tyOptAsRef: result = t
 
 proc typeAllowed*(t: PType, kind: TSymKind; flags: TTypeAllowedFlags = {}): PType =
   # returns 'nil' on success and otherwise the part of the type that is
@@ -1430,6 +1436,8 @@ proc computeSizeAux(conf: ConfigRef; typ: PType, a: var BiggestInt): BiggestInt
   of tyStatic:
     result = if typ.n != nil: computeSizeAux(conf, typ.lastSon, a)
              else: szUnknownSize
+  of tyUncheckedArray:
+    result = 0
   else:
     #internalError("computeSizeAux()")
     result = szUnknownSize
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim
index 52e4aab74..b39f85b50 100644
--- a/compiler/vmdeps.nim
+++ b/compiler/vmdeps.nim
@@ -98,6 +98,10 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
   of tyStmt: result = atomicType("stmt", mStmt)
   of tyVoid: result = atomicType("void", mVoid)
   of tyEmpty: result = atomicType("empty", mNone)
+  of tyUncheckedArray:
+    result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
+    result.add atomicType("uncheckedArray", mUncheckedArray)
+    result.add mapTypeToAst(t.sons[0], info)
   of tyArray:
     result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
     result.add atomicType("array", mArray)
@@ -289,7 +293,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
       result.add atomicType("static", mNone)
       if t.n != nil:
         result.add t.n.copyTree
-  of tyUnused, tyOptAsRef: assert(false, "mapTypeToAstX")
+  of tyOptAsRef: assert(false, "mapTypeToAstX")
 
 proc opMapTypeToAst*(cache: IdentCache; t: PType; info: TLineInfo): PNode =
   result = mapTypeToAstX(cache, t, info, false, true)
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index 91b527e02..800b5dc18 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -84,7 +84,7 @@ type
     wStdIn, wStdOut, wStdErr,
 
     wInOut, wByCopy, wByRef, wOneWay,
-    wBitsize,
+    wBitsize
 
   TSpecialWords* = set[TSpecialWord]
 
@@ -173,7 +173,7 @@ const
     "stdin", "stdout", "stderr",
 
     "inout", "bycopy", "byref", "oneway",
-    "bitsize",
+    "bitsize"
     ]
 
 proc findStr*(a: openArray[string], s: string): int =