summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-09-16 15:34:54 +0200
committerAraq <rumpf_a@web.de>2015-09-16 15:34:54 +0200
commit29a91669667344e3637dbff4fc2009c263af3e11 (patch)
tree4fed18f5de2a3b0682bcc3d981ba6b4e7297f926
parentc9a2fa54c7055c16892e9664dd64d8fc68918c07 (diff)
downloadNim-29a91669667344e3637dbff4fc2009c263af3e11.tar.gz
fixes the most pressing regressions introduced by the new handling of a[i] in the compiler
-rw-r--r--compiler/semgnrc.nim34
-rw-r--r--compiler/semmagic.nim25
-rw-r--r--lib/system.nim1
3 files changed, 45 insertions, 15 deletions
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index ed0244b0c..9c9281da0 100644
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -30,6 +30,13 @@ type
   GenericCtx = object
     toMixin: IntSet
     cursorInBody: bool # only for nimsuggest
+    bracketExpr: PNode
+
+template withBracketExpr(x, body: untyped) =
+  let old = ctx.bracketExpr
+  ctx.bracketExpr = x
+  body
+  ctx.bracketExpr = old
 
 type
   TSemGenericFlag = enum
@@ -227,6 +234,10 @@ proc semGenericStmt(c: PContext, n: PNode,
         discard
       of skProc, skMethod, skIterators, skConverter, skModule:
         result.sons[0] = symChoice(c, fn, s, scOption)
+        # do check of 's.magic==mRoof' here because it might be some
+        # other '^' but after overload resolution the proper one:
+        if ctx.bracketExpr != nil and n.len == 2 and s.name.s == "^":
+          result.add ctx.bracketExpr
         first = 1
       of skGenericParam:
         result.sons[0] = newSymNodeTypeDesc(s, fn.info)
@@ -251,12 +262,17 @@ proc semGenericStmt(c: PContext, n: PNode,
     let flags = if mixinContext: flags+{withinMixin} else: flags
     for i in countup(first, sonsLen(result) - 1):
       result.sons[i] = semGenericStmt(c, result.sons[i], flags, ctx)
-  of nkBracketExpr, nkCurlyExpr:
+  of nkCurlyExpr:
     result = newNodeI(nkCall, n.info)
-    result.add newIdentNode(getIdent(if n.kind == nkBracketExpr:"[]" else:"{}"),
-                            n.info)
+    result.add newIdentNode(getIdent("{}"), n.info)
     for i in 0 ..< n.len: result.add(n[i])
     result = semGenericStmt(c, result, flags, ctx)
+  of nkBracketExpr:
+    result = newNodeI(nkCall, n.info)
+    result.add newIdentNode(getIdent("[]"), n.info)
+    for i in 0 ..< n.len: result.add(n[i])
+    withBracketExpr n.sons[0]:
+      result = semGenericStmt(c, result, flags, ctx)
   of nkAsgn, nkFastAsgn:
     checkSonsLen(n, 2)
     let a = n.sons[0]
@@ -264,13 +280,19 @@ proc semGenericStmt(c: PContext, n: PNode,
 
     let k = a.kind
     case k
-    of nkBracketExpr, nkCurlyExpr:
+    of nkCurlyExpr:
       result = newNodeI(nkCall, n.info)
-      result.add newIdentNode(getIdent(if k == nkBracketExpr:"[]=" else:"{}="),
-                              n.info)
+      result.add newIdentNode(getIdent("{}="), n.info)
       for i in 0 ..< a.len: result.add(a[i])
       result.add(b)
       result = semGenericStmt(c, result, flags, ctx)
+    of nkBracketExpr:
+      result = newNodeI(nkCall, n.info)
+      result.add newIdentNode(getIdent("[]="), n.info)
+      for i in 0 ..< a.len: result.add(a[i])
+      result.add(b)
+      withBracketExpr a.sons[0]:
+        result = semGenericStmt(c, result, flags, ctx)
     else:
       for i in countup(0, sonsLen(n) - 1):
         result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index 65185f762..deef38ae3 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -32,6 +32,9 @@ type
 proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode
 proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode
 
+proc skipAddr(n: PNode): PNode {.inline.} =
+  (if n.kind == nkHiddenAddr: n.sons[0] else: n)
+
 proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
   result = newNodeI(nkBracketExpr, n.info)
   for i in 1..<n.len: result.add(n[i])
@@ -45,7 +48,8 @@ proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
 proc semArrPut(c: PContext; n: PNode; flags: TExprFlags): PNode =
   # rewrite `[]=`(a, i, x)  back to ``a[i] = x``.
   let b = newNodeI(nkBracketExpr, n.info)
-  for i in 1..n.len-2: b.add(n[i])
+  b.add(n[1].skipAddr)
+  for i in 2..n.len-2: b.add(n[i])
   result = newNodeI(nkAsgn, n.info, 2)
   result.sons[0] = b
   result.sons[1] = n.lastSon
@@ -179,25 +183,28 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
       if isNegative(n.sons[1]) or (n.len > 2 and isNegative(n.sons[2])):
         localError(n.info, "use '^' instead of '-'; negative indexing is obsolete")
   of mRoof:
-    # error correction:
-    result = n.sons[1]
-    if c.p.bracketExpr.isNil:
+    let bracketExpr = if n.len == 3: n.sons[2] else: c.p.bracketExpr
+    if bracketExpr.isNil:
       localError(n.info, "no surrounding array access context for '^'")
-    elif c.p.bracketExpr.checkForSideEffects != seNoSideEffect:
+      result = n.sons[1]
+    elif bracketExpr.checkForSideEffects != seNoSideEffect:
       localError(n.info, "invalid context for '^' as '$#' has side effects" %
-        renderTree(c.p.bracketExpr))
-    elif c.p.bracketExpr.typ.isStrangeArray:
+        renderTree(bracketExpr))
+      result = n.sons[1]
+    elif bracketExpr.typ.isStrangeArray:
       localError(n.info, "invalid context for '^' as len!=high+1 for '$#'" %
-        renderTree(c.p.bracketExpr))
+        renderTree(bracketExpr))
+      result = n.sons[1]
     else:
       # ^x  is rewritten to: len(a)-x
       let lenExpr = newNodeI(nkCall, n.info)
       lenExpr.add newIdentNode(getIdent"len", n.info)
-      lenExpr.add c.p.bracketExpr
+      lenExpr.add bracketExpr
       let lenExprB = semExprWithType(c, lenExpr)
       if lenExprB.typ.isNil or not isOrdinalType(lenExprB.typ):
         localError(n.info, "'$#' has to be of an ordinal type for '^'" %
           renderTree(lenExpr))
+        result = n.sons[1]
       else:
         result = newNodeIT(nkCall, n.info, getSysType(tyInt))
         result.add newSymNode(createMagic("-", mSubI), n.info)
diff --git a/lib/system.nim b/lib/system.nim
index 27c23e0bc..8f529b8c0 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -3465,6 +3465,7 @@ proc procCall*(x: expr) {.magic: "ProcCall", compileTime.} =
   ##   procCall someMethod(a, b)
   discard
 
+proc `^`*[T](x: int; y: openArray[T]): int {.noSideEffect, magic: "Roof".}
 proc `^`*(x: int): int {.noSideEffect, magic: "Roof".} =
   ## builtin `roof`:idx: operator that can be used for convenient array access.
   ## ``a[^x]`` is rewritten to ``a[a.len-x]``. However currently the ``a``