From 645e13173942999ed98c1e545ae241af44b1da50 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Fri, 29 May 2026 13:58:23 +0800 Subject: [PATCH] fixes #25796; fixes procParamTypeRel to ensure backend type consistency (#25798) fixes #25796 This pull request addresses a subtle type-matching issue in the Nim compiler related to backend type compatibility, particularly for procedures returning `lent` types. It also adds new test cases to ensure correct handling of these scenarios. **Compiler type-checking fix:** * Updated `procParamTypeRel` in `compiler/sigmatch.nim` to skip wrappers like `tyVar`, `tyLent`, `tySink`, and `tyOwned` before comparing backend types, ensuring more accurate type equivalence checks for procedure parameters and return types. **Test coverage improvements:** * Added multiple blocks in `tests/proc/tproc.nim` to test procedure types returning `lent` objects, including cases with constants, variables, and union parameter types, verifying that the compiler now correctly handles these cases. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- compiler/sigmatch.nim | 4 +++- compiler/types.nim | 3 ++- tests/proc/tproc.nim | 27 +++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index bf9c2d2050..db06d3e427 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -791,8 +791,10 @@ proc procParamTypeRel(c: var TCandidate; f, a: PType): TTypeRelation = # different C types (size_t vs unsigned long long). let fCheck = concreteType(c, f) let aCheck = concreteType(c, a) + # Note that `result` is equal; now check whether they have the same + # backend type. if fCheck != nil and aCheck != nil and - not sameBackendTypePickyAliases(fCheck, aCheck): + not sameBackendTypePickyAliases(fCheck, aCheck, {IgnoreFlags}): result = isNone if result <= isSubrange or inconsistentVarTypes(f, a): diff --git a/compiler/types.nim b/compiler/types.nim index de24471e7d..f4c7e74bc5 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1069,9 +1069,10 @@ proc sameBackendTypeIgnoreRange*(x, y: PType): bool = c.cmp = dcEqIgnoreDistinct result = sameTypeAux(x, y, c) -proc sameBackendTypePickyAliases*(x, y: PType): bool = +proc sameBackendTypePickyAliases*(x, y: PType, flags: TTypeCmpFlags = {}): bool = var c = initSameTypeClosure() c.flags.incl {IgnoreTupleFields, IgnoreRangeShallow, PickyCAliases, PickyBackendAliases} + c.flags.incl flags c.cmp = dcEqIgnoreDistinct result = sameTypeAux(x, y, c) diff --git a/tests/proc/tproc.nim b/tests/proc/tproc.nim index d7f8619917..564f9be31b 100644 --- a/tests/proc/tproc.nim +++ b/tests/proc/tproc.nim @@ -29,3 +29,30 @@ block tnestprc: result = x + y result = add(x, 3) doAssert Add3(7) == 10 + +block: + type A = object + c: int + type H = proc(): lent A {.nimcall.} + const u = A(c: 0) + proc e(T: typedesc): lent A = u + proc y(T: typedesc): H = + proc(): lent A {.nimcall.} = T.e + discard y(int) + +block: + type A = object + c: int + type H = proc(): lent A {.nimcall.} + let u = A(c: 0) + proc y(_: int | int): H = + proc(): lent A {.nimcall.} = u + discard y(0) + +block: + type A = object + c: int + type H = proc(): lent A {.nimcall.} + let u = A() + let _: H = proc(): lent A {.nimcall.} = u +