diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 7e7499e458..8488748101 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 18cfcf6b21..b6644642e9 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 b81b17f30b..bf70e70c39 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()