From e4e6c4843ffe215005720c1293cee7320a7c8047 Mon Sep 17 00:00:00 2001 From: "Andrey R (cooldome)" Date: Sat, 14 Nov 2020 21:47:00 +0000 Subject: [PATCH 1/8] fix #15958 --- compiler/ccgtypes.nim | 2 +- tests/lent/tbasic_lent_check.nim | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index e3f832d686632..d9a0dd20dbb07 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -282,7 +282,7 @@ proc ccgIntroducedPtr(conf: ConfigRef; s: PSym, retType: PType): bool = result = false # first parameter and return type is 'lent T'? --> use pass by pointer if s.position == 0 and retType != nil and retType.kind == tyLent: - result = pt.kind != tyVar + result = pt.kind notin {tyVar, tyArray} proc fillResult(conf: ConfigRef; param: PNode) = fillLoc(param.sym.loc, locParam, param, ~"Result", diff --git a/tests/lent/tbasic_lent_check.nim b/tests/lent/tbasic_lent_check.nim index 4389cbc6e5e6d..9f9903635f764 100644 --- a/tests/lent/tbasic_lent_check.nim +++ b/tests/lent/tbasic_lent_check.nim @@ -1,4 +1,5 @@ discard """ + targets: "c cpp" output: "1" """ @@ -14,3 +15,13 @@ proc main = doAssert(not compiles(passToVar(viewInto(x)))) main() + + +#------------------------------------------------------------------------------ +# issue #15958 + +block: + proc byLent[T](a: T): lent T = a + let a = [11,12] + doAssert byLent(a) == [11,12] + doAssert byLent(a).unsafeAddr == a.unsafeAddr \ No newline at end of file From 4645763046faf75d7442637d67f1da15cbf5ddcb Mon Sep 17 00:00:00 2001 From: "Andrey R (cooldome)" Date: Sun, 15 Nov 2020 18:30:52 +0000 Subject: [PATCH 2/8] also cover openArray and VarArgs --- compiler/ccgtypes.nim | 2 +- tests/lent/tbasic_lent_check.nim | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index d9a0dd20dbb07..ff05719226930 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -282,7 +282,7 @@ proc ccgIntroducedPtr(conf: ConfigRef; s: PSym, retType: PType): bool = result = false # first parameter and return type is 'lent T'? --> use pass by pointer if s.position == 0 and retType != nil and retType.kind == tyLent: - result = pt.kind notin {tyVar, tyArray} + result = pt.kind notin {tyVar, tyArray, tyOpenArray, tyVarargs} proc fillResult(conf: ConfigRef; param: PNode) = fillLoc(param.sym.loc, locParam, param, ~"Result", diff --git a/tests/lent/tbasic_lent_check.nim b/tests/lent/tbasic_lent_check.nim index 9f9903635f764..f8cf106968063 100644 --- a/tests/lent/tbasic_lent_check.nim +++ b/tests/lent/tbasic_lent_check.nim @@ -24,4 +24,16 @@ block: proc byLent[T](a: T): lent T = a let a = [11,12] doAssert byLent(a) == [11,12] - doAssert byLent(a).unsafeAddr == a.unsafeAddr \ No newline at end of file + doAssert byLent(a).unsafeAddr == a.unsafeAddr + + proc byLent2[T](a: openarray[T]): lent T = a[0] + doAssert byLent2(a) == 11 + doAssert byLent2(a).unsafeAddr == a[0].unsafeAddr + + proc byLent3[T](a: varargs[T]): lent T = a[1] + let + x = 10 + y = 20 + z = 30 + doAssert byLent3(x, y, z) == 20 + From e4bfa99ec2e2ca1d648a6a2230c48e79f133c2f1 Mon Sep 17 00:00:00 2001 From: "Andrey R (cooldome)" Date: Sun, 15 Nov 2020 18:33:05 +0000 Subject: [PATCH 3/8] more tests --- tests/lent/tbasic_lent_check.nim | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/lent/tbasic_lent_check.nim b/tests/lent/tbasic_lent_check.nim index f8cf106968063..ce09ecf7fa542 100644 --- a/tests/lent/tbasic_lent_check.nim +++ b/tests/lent/tbasic_lent_check.nim @@ -23,12 +23,18 @@ main() block: proc byLent[T](a: T): lent T = a let a = [11,12] + let b = @[21,23] doAssert byLent(a) == [11,12] doAssert byLent(a).unsafeAddr == a.unsafeAddr + doAssert byLent(b) == @[21,23] + doAssert byLent(b).unsafeAddr == b.unsafeAddr proc byLent2[T](a: openarray[T]): lent T = a[0] doAssert byLent2(a) == 11 doAssert byLent2(a).unsafeAddr == a[0].unsafeAddr + doAssert byLent2(b) == 21 + doAssert byLent2(b).unsafeAddr == b[0].unsafeAddr + proc byLent3[T](a: varargs[T]): lent T = a[1] let From 2ca1b07a0ef95a7b83824e519819303f4e934cfa Mon Sep 17 00:00:00 2001 From: "Andrey R (cooldome)" Date: Sun, 15 Nov 2020 21:04:19 +0000 Subject: [PATCH 4/8] cover even more types --- tests/lent/tbasic_lent_check.nim | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/lent/tbasic_lent_check.nim b/tests/lent/tbasic_lent_check.nim index ce09ecf7fa542..2f8afed9fd9a0 100644 --- a/tests/lent/tbasic_lent_check.nim +++ b/tests/lent/tbasic_lent_check.nim @@ -29,13 +29,20 @@ block: doAssert byLent(b) == @[21,23] doAssert byLent(b).unsafeAddr == b.unsafeAddr + let r = new(float) + r[] = 10.0 + doAssert byLent(r)[] == 10.0 + + let p = create(float) + p[] = 20.0 + doAssert byLent(p)[] == 20.0 + proc byLent2[T](a: openarray[T]): lent T = a[0] doAssert byLent2(a) == 11 doAssert byLent2(a).unsafeAddr == a[0].unsafeAddr doAssert byLent2(b) == 21 doAssert byLent2(b).unsafeAddr == b[0].unsafeAddr - proc byLent3[T](a: varargs[T]): lent T = a[1] let x = 10 From cc8463fc7897025462d620a0934a8171573d0a08 Mon Sep 17 00:00:00 2001 From: "Andrey R (cooldome)" Date: Sun, 15 Nov 2020 21:04:42 +0000 Subject: [PATCH 5/8] cover even more types --- compiler/ccgtypes.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index ff05719226930..4b2cae2eb573c 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -282,7 +282,7 @@ proc ccgIntroducedPtr(conf: ConfigRef; s: PSym, retType: PType): bool = result = false # first parameter and return type is 'lent T'? --> use pass by pointer if s.position == 0 and retType != nil and retType.kind == tyLent: - result = pt.kind notin {tyVar, tyArray, tyOpenArray, tyVarargs} + result = pt.kind notin {tyVar, tyArray, tyOpenArray, tyVarargs, tyRef, tyPtr, tyPointer} proc fillResult(conf: ConfigRef; param: PNode) = fillLoc(param.sym.loc, locParam, param, ~"Result", From 437345589d536c68aae65e20a128879a93f3b2e3 Mon Sep 17 00:00:00 2001 From: "Andrey R (cooldome)" Date: Mon, 16 Nov 2020 09:42:43 +0000 Subject: [PATCH 6/8] Trigger build From 80ca1abec080c59e4f0a46d5b48469fe69faa69b Mon Sep 17 00:00:00 2001 From: "Andrey R (cooldome)" Date: Wed, 18 Nov 2020 09:21:53 +0000 Subject: [PATCH 7/8] Trigger build From f5b6c6d54f7e8d735e204745e02b5a327498e7f1 Mon Sep 17 00:00:00 2001 From: "Andrey R (cooldome)" Date: Wed, 18 Nov 2020 18:58:48 +0000 Subject: [PATCH 8/8] cover sets passed as arrays --- compiler/ccgtypes.nim | 3 ++- tests/lent/tbasic_lent_check.nim | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 4b2cae2eb573c..142fec05699f2 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -282,7 +282,8 @@ proc ccgIntroducedPtr(conf: ConfigRef; s: PSym, retType: PType): bool = result = false # first parameter and return type is 'lent T'? --> use pass by pointer if s.position == 0 and retType != nil and retType.kind == tyLent: - result = pt.kind notin {tyVar, tyArray, tyOpenArray, tyVarargs, tyRef, tyPtr, tyPointer} + result = not (pt.kind in {tyVar, tyArray, tyOpenArray, tyVarargs, tyRef, tyPtr, tyPointer} or + pt.kind == tySet and mapSetType(conf, pt) == ctArray) proc fillResult(conf: ConfigRef; param: PNode) = fillLoc(param.sym.loc, locParam, param, ~"Result", diff --git a/tests/lent/tbasic_lent_check.nim b/tests/lent/tbasic_lent_check.nim index 2f8afed9fd9a0..e22f7bb5088ea 100644 --- a/tests/lent/tbasic_lent_check.nim +++ b/tests/lent/tbasic_lent_check.nim @@ -23,11 +23,14 @@ main() block: proc byLent[T](a: T): lent T = a let a = [11,12] - let b = @[21,23] + let b = @[21,23] + let ss = {1, 2, 3, 5} doAssert byLent(a) == [11,12] doAssert byLent(a).unsafeAddr == a.unsafeAddr doAssert byLent(b) == @[21,23] doAssert byLent(b).unsafeAddr == b.unsafeAddr + doAssert byLent(ss) == {1, 2, 3, 5} + doAssert byLent(ss).unsafeAddr == ss.unsafeAddr let r = new(float) r[] = 10.0