mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-06 07:38:24 +00:00
fixes #25677; fixes #25678 This pull request introduces both a bug fix to the type checking logic in the compiler and new test cases for lent types involving procedures and tables. The most significant change is a refinement in how type flags are handled for procedure and function types in the compiler, which improves correctness in type allowance checks. Additionally, the test suite is expanded to cover more complex scenarios with lent types and table lookups. **Compiler improvements:** * Refined the handling of type flags in `typeAllowedAux` for procedure and function types by introducing `innerFlags`, which removes certain flags (`taObjField`, `taTupField`, `taIsOpenArray`) before recursing into parameter and return types. This ensures more accurate type checking and prevents inappropriate flag propagation. **Testing enhancements:** * Added new test blocks in `tests/lent/tlents.nim` to cover lent procedure types stored in objects and used as table values, including a function that retrieves such procedures from a table by key. * Introduced a test case for an object containing a lent procedure field, ensuring correct behavior when accessing and using these fields.
This commit is contained in:
@@ -99,12 +99,13 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||
if isInlineIterator(typ) and kind in {skVar, skLet, skConst, skParam, skResult}:
|
||||
# only closure iterators may be assigned to anything.
|
||||
result = t
|
||||
let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags
|
||||
let innerFlags = flags - {taObjField, taTupField, taIsOpenArray}
|
||||
let f = if kind in {skProc, skFunc}: innerFlags+{taNoUntyped} else: innerFlags
|
||||
for _, a in t.paramTypes:
|
||||
if result != nil: break
|
||||
result = typeAllowedAux(marker, a, skParam, c, f-{taIsOpenArray})
|
||||
result = typeAllowedAux(marker, a, skParam, c, f)
|
||||
if result.isNil and t.returnType != nil:
|
||||
result = typeAllowedAux(marker, t.returnType, skResult, c, flags)
|
||||
result = typeAllowedAux(marker, t.returnType, skResult, c, innerFlags)
|
||||
of tyTypeDesc:
|
||||
if kind in {skVar, skLet, skConst} and taProcContextIsNotMacro in flags:
|
||||
result = t
|
||||
|
||||
@@ -23,3 +23,25 @@ block:
|
||||
doAssert x(a) == 1
|
||||
doAssert y(a) == 1
|
||||
|
||||
|
||||
import std/tables
|
||||
|
||||
block:
|
||||
type
|
||||
R = proc(): lent O {.nimcall.}
|
||||
F = object
|
||||
schema: R
|
||||
O = object
|
||||
fields: Table[string, F]
|
||||
|
||||
func f(o: O, key: string): R =
|
||||
if key in o.fields: o.fields[key].schema
|
||||
else: nil
|
||||
|
||||
block:
|
||||
type
|
||||
R = proc(): lent O
|
||||
O = object
|
||||
r: R
|
||||
|
||||
func f(o: O): int = 42
|
||||
|
||||
Reference in New Issue
Block a user