mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-24 21:59:52 +00:00
fixes lent tuple codegen error (#25782)
ref https://github.com/nim-lang/Nim/pull/25783 This pull request addresses an issue with addressability of tuple elements of type `lent` or `var` in Nim, ensuring that expressions involving these types are handled correctly during type changes. The main changes introduce a check to prevent attempting to change the type of tuple elements that are views (`var` or `lent`), and a new test is added to verify the correct error is raised when trying to take the address of such elements. Type system and semantic analysis improvements: * Added the `isViewTarget` template in `semexprs.nim` to check if a type is a view (`var` or `lent`), and updated `changeType` to skip type changes for tuple elements that are views. This prevents invalid addressability operations on these types. [[1]](diffhunk://#diff-539da3a63df08fa987f1b0c67d26cdc690753843d110b6bf0805a685eeaffd40R655-R657) [[2]](diffhunk://#diff-539da3a63df08fa987f1b0c67d26cdc690753843d110b6bf0805a685eeaffd40R686-R693) Testing: * Added a new test `tlent_tuple_address.nim` to verify that attempting to take the address of tuple elements of type `lent` correctly produces an "expression has no address" error.
This commit is contained in:
@@ -652,6 +652,9 @@ proc overloadedCallOpr(c: PContext, n: PNode): PNode =
|
||||
result = semExpr(c, result, flags = {efNoUndeclared})
|
||||
|
||||
proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
|
||||
template isViewTarget(t: PType): bool =
|
||||
t.skipTypes({tyGenericInst, tyAlias, tySink}).kind in {tyVar, tyLent}
|
||||
|
||||
case n.kind
|
||||
of nkCurly:
|
||||
for i in 0..<n.len:
|
||||
@@ -680,12 +683,15 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
|
||||
if f == nil:
|
||||
globalError(c.config, m.info, "unknown identifier: " & m.sym.name.s)
|
||||
return
|
||||
changeType(c, n[i][1], f.typ, check)
|
||||
if not isViewTarget(f.typ):
|
||||
changeType(c, n[i][1], f.typ, check)
|
||||
else:
|
||||
changeType(c, n[i][1], tup[i], check)
|
||||
if not isViewTarget(tup[i]):
|
||||
changeType(c, n[i][1], tup[i], check)
|
||||
else:
|
||||
for i in 0..<n.len:
|
||||
changeType(c, n[i], tup[i], check)
|
||||
if not isViewTarget(tup[i]):
|
||||
changeType(c, n[i], tup[i], check)
|
||||
when false:
|
||||
var m = n[i]
|
||||
var a = newNodeIT(nkExprColonExpr, m.info, newType[i])
|
||||
@@ -708,6 +714,7 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
|
||||
localError(c.config, n.info, "cannot convert '" & n.sym.name.s &
|
||||
"' to '" & typeNameAndDesc(newType) & "'")
|
||||
else: discard
|
||||
|
||||
n.typ = newType
|
||||
|
||||
proc arrayConstrType(c: PContext, n: PNode): PType =
|
||||
|
||||
12
tests/lent/tlent_tuple_address.nim
Normal file
12
tests/lent/tlent_tuple_address.nim
Normal file
@@ -0,0 +1,12 @@
|
||||
discard """
|
||||
errormsg: "expression has no address"
|
||||
"""
|
||||
|
||||
iterator foo(x: int): (lent int, lent int) =
|
||||
yield (x, x + 1)
|
||||
|
||||
|
||||
var x = 12
|
||||
for i in foo(x):
|
||||
echo i[0]
|
||||
echo i[1]
|
||||
Reference in New Issue
Block a user