diff options
author | Jason Beetham <beefers331@gmail.com> | 2021-10-26 03:29:07 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-26 11:29:07 +0200 |
commit | 8d5a27518929bd4c54f4beb7e40a5fc382d3dd05 (patch) | |
tree | 2280f8122f8e5daad73e93e3faee1db865258bd5 /compiler | |
parent | 83a2515af7aeb9a1c12015321243399a0d1f4c95 (diff) | |
download | Nim-8d5a27518929bd4c54f4beb7e40a5fc382d3dd05.tar.gz |
Fixed distinct composite type class proc borrowing (#18904)
* Fixed composite type class proc borrowing * Moved borrow search into transf * added borrow check to symbol flag
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semcall.nim | 13 | ||||
-rw-r--r-- | compiler/seminst.nim | 6 | ||||
-rw-r--r-- | compiler/transf.nim | 8 |
3 files changed, 24 insertions, 3 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim index a3064788e..36658d472 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -703,7 +703,16 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = call.add(newIdentNode(fn.name, fn.info)) for i in 1..<fn.typ.n.len: let param = fn.typ.n[i] - let t = skipTypes(param.typ, abstractVar-{tyTypeDesc, tyDistinct}) + const desiredTypes = abstractVar + {tyCompositeTypeClass} - {tyTypeDesc, tyDistinct} + #[. + # We only want the type not any modifiers such as `ptr`, `var`, `ref` ... + # tyCompositeTypeClass is here for + # when using something like: + type Foo[T] = distinct int + proc `$`(f: Foo): string {.borrow.} + # We want to skip the `Foo` to get `int` + ]# + let t = skipTypes(param.typ, desiredTypes) if t.kind == tyDistinct or param.typ.kind == tyDistinct: hasDistinct = true var x: PType if param.typ.kind == tyVar: @@ -721,4 +730,4 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = result = nil elif result.magic in {mArrPut, mArrGet}: # cannot borrow these magics for now - result = nil + result = nil \ No newline at end of file diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 456e40a94..6fae0583d 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -145,7 +145,11 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) = if sfGenSym in param.flags: idTablePut(symMap, params[i].sym, result.typ.n[param.position+1].sym) freshGenSyms(c, b, result, orig, symMap) - b = semProcBody(c, b) + + if sfBorrow notin orig.flags: + # We do not want to generate a body for generic borrowed procs. + # As body is a sym to the borrowed proc. + b = semProcBody(c, b) result.ast[bodyPos] = hloBody(c, b) excl(result.flags, sfForward) trackProc(c, result, result.ast[bodyPos]) diff --git a/compiler/transf.nim b/compiler/transf.nim index 89fa89701..edb8d3573 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -124,6 +124,14 @@ proc transformSymAux(c: PTransf, n: PNode): PNode = var tc = c.transCon if sfBorrow in s.flags and s.kind in routineKinds: # simply exchange the symbol: + var s = s + while true: + # Skips over all borrowed procs getting the last proc symbol without an implementation + let body = getBody(c.graph, s) + if body.kind == nkSym and sfBorrow in body.sym.flags and getBody(c.graph, body.sym).kind == nkSym: + s = body.sym + else: + break b = getBody(c.graph, s) if b.kind != nkSym: internalError(c.graph.config, n.info, "wrong AST for borrowed symbol") b = newSymNode(b.sym, n.info) |