summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2023-04-18 00:31:47 +0800
committerGitHub <noreply@github.com>2023-04-18 00:31:47 +0800
commit65223e6f59ddef9f04fb15bd39bf5dae3abb2e39 (patch)
tree682e685e29a69bfdeb04b9c8b95ab5ef70d1d728
parent91e4381a20a5b1af0f633ee8c7d0255a1530d082 (diff)
downloadNim-65223e6f59ddef9f04fb15bd39bf5dae3abb2e39.tar.gz
fixes #21674; `lent` can be used in the fields or the cast type as a parameter (#21684)
* fixes #21674; `lent` can be used in the fields or the cast type as a parameter

* add a test case

* fix the test
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/typeallowed.nim4
-rw-r--r--tests/views/tviews1.nim16
3 files changed, 20 insertions, 2 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 7e7499e45..848874810 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -261,7 +261,7 @@ proc isCastable(c: PContext; dst, src: PType, info: TLineInfo): bool =
     return false
   elif srcSize < 0:
     return false
-  elif typeAllowed(dst, skParam, c) != nil:
+  elif typeAllowed(dst, skParam, c, {taIsCastable}) != nil:
     return false
   elif dst.kind == tyProc and dst.callConv == ccClosure:
     return src.kind == tyProc and src.callConv == ccClosure
diff --git a/compiler/typeallowed.nim b/compiler/typeallowed.nim
index 18cfcf6b2..b6644642e 100644
--- a/compiler/typeallowed.nim
+++ b/compiler/typeallowed.nim
@@ -25,6 +25,7 @@ type
     taNoUntyped
     taIsTemplateOrMacro
     taProcContextIsNotMacro
+    taIsCastable
 
   TTypeAllowedFlags* = set[TTypeAllowedFlag]
 
@@ -63,7 +64,8 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
     elif taIsOpenArray in flags:
       result = t
     elif t.kind == tyLent and ((kind != skResult and views notin c.features) or
-                              kind == skParam): # lent can't be used as parameters.
+      (kind == skParam and {taIsCastable, taField} * flags == {})): # lent cannot be used as parameters.
+                                                       # except in the cast environment and as the field of an object
       result = t
     elif isOutParam(t) and kind != skParam:
       result = t
diff --git a/tests/views/tviews1.nim b/tests/views/tviews1.nim
index b81b17f30..bf70e70c3 100644
--- a/tests/views/tviews1.nim
+++ b/tests/views/tviews1.nim
@@ -77,3 +77,19 @@ type Inner = object
 var o = Outer(value: 1234)
 var v = Inner(owner: o).owner.value
 doAssert v == 1234
+
+block: # bug #21674
+  type
+    Lent = object
+      data: lent int
+
+  proc foo(s: Lent) =
+    var m = 12
+    discard cast[lent int](m)
+
+  proc main =
+    var m1 = 123
+    var x = Lent(data: m1)
+    foo(x)
+
+  main()