From 484617cc67ce82fc1584431886997175f39f332d Mon Sep 17 00:00:00 2001 From: demotomohiro Date: Tue, 19 May 2026 07:45:25 +0900 Subject: [PATCH] fixes 25826; var type class parameter matches lvalues --- compiler/sigmatch.nim | 7 +++++- tests/typerel/tvar_type_class_param.nim | 23 ++++++++++++++++++++ tests/typerel/tvar_type_class_param_fail.nim | 10 +++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/typerel/tvar_type_class_param.nim create mode 100644 tests/typerel/tvar_type_class_param_fail.nim diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index bf9c2d20503ae..72fbae2694210 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1907,6 +1907,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, return isNone if doBind: put(c, f, a) return isGeneric + elif targetKind == tyVar: + # always matches. + # The argument is checked if it is lvalue or not outside of this proc. + if doBind: put(c, f, if aOrig.kind == tyVar: aOrig else: makeVarType(c.c, a)) + return isGeneric else: return isNone of tyUserTypeClassInst, tyUserTypeClass: @@ -2863,7 +2868,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int else: noMatch() - if formal.typ.kind in {tyVar}: + if formal.typ.kind in {tyVar} or (formal.typ.kind == tyBuiltInTypeClass and formal.typ[0].kind == tyVar): let argConverter = if arg.kind == nkHiddenDeref: arg[0] else: arg if argConverter.kind == nkHiddenCallConv: if argConverter.typ.kind notin {tyVar}: diff --git a/tests/typerel/tvar_type_class_param.nim b/tests/typerel/tvar_type_class_param.nim new file mode 100644 index 0000000000000..f7bfdd6adbf8f --- /dev/null +++ b/tests/typerel/tvar_type_class_param.nim @@ -0,0 +1,23 @@ +# issue #25826 + +proc foo(x: var) = x = 123 + +block: + var a = 0 + foo(a) + doAssert a == 123 + +proc bar(x: var int) = + foo(x) + +block: + var a = 0 + bar(a) + doAssert a == 123 + +proc baz(x: var int): var int = x + +block: + var a = 0 + foo(baz(a)) + doAssert a == 123 diff --git a/tests/typerel/tvar_type_class_param_fail.nim b/tests/typerel/tvar_type_class_param_fail.nim new file mode 100644 index 0000000000000..67f67c5b3db30 --- /dev/null +++ b/tests/typerel/tvar_type_class_param_fail.nim @@ -0,0 +1,10 @@ +discard """ + action: "reject" + errormsg: "type mismatch: got " +""" +# issue #25826 + +proc foo(x: var) = x = 123 + +let a = 0 +foo(a)