diff options
-rw-r--r-- | compiler/ic/ic.nim | 3 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/magicsys.nim | 7 | ||||
-rw-r--r-- | compiler/semdata.nim | 7 | ||||
-rw-r--r-- | compiler/transf.nim | 19 | ||||
-rw-r--r-- | tests/arc/titeration_doesnt_copy.nim | 56 |
6 files changed, 84 insertions, 10 deletions
diff --git a/compiler/ic/ic.nim b/compiler/ic/ic.nim index 2f03ffb43..b12db194c 100644 --- a/compiler/ic/ic.nim +++ b/compiler/ic/ic.nim @@ -1089,7 +1089,8 @@ proc needsRecompile(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache else: result = optForceFullMake in conf.globalOptions # check its dependencies: - for dep in g[m].fromDisk.imports: + let imp = g[m].fromDisk.imports + for dep in imp: let fid = toFileIndex(dep, g[m].fromDisk, conf) # Warning: we need to traverse the full graph, so # do **not use break here**! diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 4870ca1a3..7a64790c2 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -211,6 +211,8 @@ proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string; inferredFr m.add " a 'sink' parameter" m.add "; routine: " m.add c.owner.name.s + #m.add "\n\n" + #m.add renderTree(c.body, {renderIds}) localError(c.graph.config, ri.info, errGenerated, m) proc makePtrType(c: var Con, baseType: PType): PType = diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index dcde49bff..b365a3a19 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -103,6 +103,13 @@ proc addSonSkipIntLit*(father, son: PType; id: IdGenerator) = father.add(s) propagateToOwner(father, s) +proc makeVarType*(owner: PSym; baseType: PType; idgen: IdGenerator; kind = tyVar): PType = + if baseType.kind == kind: + result = baseType + else: + result = newType(kind, idgen, owner) + addSonSkipIntLit(result, baseType, idgen) + proc getCompilerProc*(g: ModuleGraph; name: string): PSym = let ident = getIdent(g.cache, name) result = strTableGet(g.compilerprocs, ident) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index a24fa4fb5..b1ffbec49 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -424,13 +424,6 @@ proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType = result = newTypeS(kind, c) addSonSkipIntLit(result, baseType, c.idgen) -proc makeVarType*(owner: PSym, baseType: PType; idgen: IdGenerator; kind = tyVar): PType = - if baseType.kind == kind: - result = baseType - else: - result = newType(kind, idgen, owner) - addSonSkipIntLit(result, baseType, idgen) - proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode = let typedesc = newTypeS(tyTypeDesc, c) incl typedesc.flags, tfCheckedForDestructor diff --git a/compiler/transf.nim b/compiler/transf.nim index 65b4c6c3b..edae6b847 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -614,7 +614,7 @@ proc transformConv(c: PTransf, n: PNode): PNode = type TPutArgInto = enum paDirectMapping, paFastAsgn, paFastAsgnTakeTypeFromArg - paVarAsgn, paComplexOpenarray + paVarAsgn, paComplexOpenarray, paViaIndirection proc putArgInto(arg: PNode, formal: PType): TPutArgInto = # This analyses how to treat the mapping "formal <-> arg" in an @@ -634,6 +634,7 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto = result = paDirectMapping of nkDotExpr, nkDerefExpr, nkHiddenDeref, nkAddr, nkHiddenAddr: result = putArgInto(arg[0], formal) + #if result == paViaIndirection: result = paFastAsgn of nkCurly, nkBracket: for i in 0..<arg.len: if putArgInto(arg[i], formal) != paDirectMapping: @@ -646,6 +647,9 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto = if putArgInto(a, formal) != paDirectMapping: return paFastAsgn result = paDirectMapping + of nkBracketExpr: + if skipTypes(formal, abstractInst).kind in {tyVar, tyLent}: result = paVarAsgn + else: result = paViaIndirection else: if skipTypes(formal, abstractInst).kind in {tyVar, tyLent}: result = paVarAsgn else: result = paFastAsgn @@ -765,13 +769,24 @@ proc transformFor(c: PTransf, n: PNode): PNode = t = arg.typ # generate a temporary and produce an assignment statement: var temp = newTemp(c, t, formal.info) + #incl(temp.sym.flags, sfCursor) addVar(v, temp) stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg, true)) idNodeTablePut(newC.mapping, formal, temp) of paVarAsgn: - assert(skipTypes(formal.typ, abstractInst).kind in {tyVar}) + assert(skipTypes(formal.typ, abstractInst).kind in {tyVar, tyLent}) idNodeTablePut(newC.mapping, formal, arg) # XXX BUG still not correct if the arg has a side effect! + of paViaIndirection: + let t = formal.typ + let vt = makeVarType(t.owner, t, c.idgen) + vt.flags.incl tfVarIsPtr + var temp = newTemp(c, vt, formal.info) + addVar(v, temp) + var addrExp = newNodeIT(nkHiddenAddr, formal.info, makeVarType(t.owner, t, c.idgen, tyPtr)) + addrExp.add(arg) + stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, addrExp, true)) + idNodeTablePut(newC.mapping, formal, newDeref(temp)) of paComplexOpenarray: # arrays will deep copy here (pretty bad). var temp = newTemp(c, arg.typ, formal.info) diff --git a/tests/arc/titeration_doesnt_copy.nim b/tests/arc/titeration_doesnt_copy.nim new file mode 100644 index 000000000..e1cdb6166 --- /dev/null +++ b/tests/arc/titeration_doesnt_copy.nim @@ -0,0 +1,56 @@ +discard """ + output: "true" +""" + +type + Idx = object + i: int + Node = object + n: int + next: seq[Idx] + FooBar = object + s: seq[Node] + +proc `=copy`(dest: var Idx; source: Idx) {.error.} +proc `=copy`(dest: var Node; source: Node) {.error.} +proc `=copy`(dest: var FooBar; source: FooBar) {.error.} + +proc doSomething(ss: var seq[int], s: FooBar) = + for i in 0 .. s.s.len-1: + for elm in items s.s[i].next: + ss.add s.s[elm.i].n + +when isMainModule: + const foo = FooBar(s: @[Node(n: 1, next: @[Idx(i: 0)])]) + var ss: seq[int] + doSomething(ss, foo) + echo ss == @[1] + +from sequtils import mapIt +from strutils import join + +proc toBinSeq*(b: uint8): seq[uint8] = + ## Return binary sequence from each bits of uint8. + runnableExamples: + from sequtils import repeat + doAssert 0'u8.toBinSeq == 0'u8.repeat(8) + doAssert 0b1010_1010.toBinSeq == @[1'u8, 0, 1, 0, 1, 0, 1, 0] + result = @[] + var c = b + for i in 1..8: + result.add (uint8(c and 0b1000_0000) shr 7) + c = c shl 1 + +proc toBinString*(data: openArray[uint8], col: int): string = + ## Return binary string from each bits of uint8. + runnableExamples: + doAssert @[0b0000_1111'u8, 0b1010_1010].toBinString(8) == "0000111110101010" + doAssert @[0b1000_0000'u8, 0b0000_0000].toBinString(1) == "10" + result = "" + for b in items data.mapIt(it.toBinSeq.mapIt(it.`$`[0].char)): + for i, c in b: + if i < col: + result.add c + +doAssert @[0b0000_1111'u8, 0b1010_1010].toBinString(8) == "0000111110101010" +doAssert @[0b1000_0000'u8, 0b0000_0000].toBinString(1) == "10" |