diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index efeaf91f6d..538ad974eb 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -784,11 +784,15 @@ proc procParamTypeRel(c: var TCandidate; f, a: PType): TTypeRelation = # if f is metatype. result = typeRel(c, f, a) - if result == isEqual and - not containsGenericType(f) and not containsGenericType(a) and - not containsUnresolvedType(f) and not containsUnresolvedType(a) and - not sameBackendTypePickyAliases(f, a): - result = isNone + if result == isEqual: + # Ensure types that are semantically equal also match at the backend level. + # E.g. reject assigning proc(csize_t) to proc(uint) since these map to + # different C types (size_t vs unsigned long long). + let fCheck = concreteType(c, f) + let aCheck = concreteType(c, a) + if fCheck != nil and aCheck != nil and + not sameBackendTypePickyAliases(fCheck, aCheck): + result = isNone if result <= isSubrange or inconsistentVarTypes(f, a): result = isNone diff --git a/tests/concepts/tconcepts_issues.nim b/tests/concepts/tconcepts_issues.nim index c6d0267c5c..02d9d25bf1 100644 --- a/tests/concepts/tconcepts_issues.nim +++ b/tests/concepts/tconcepts_issues.nim @@ -176,6 +176,42 @@ block t6462: var s = SeqGen[int](fil: FilterMixin[int](test: nil, trans: nil)) doAssert s.test() == nil +block concept_with_cint: + # Generic proc matching through concepts with cint should still work + type + FilterMixin[T] = ref object + test: (T) -> bool + trans: (T) -> T + + SeqGen[T] = ref object + fil: FilterMixin[T] + + WithFilter[T] = concept a + a.fil is FilterMixin[T] + + proc test[T](a: WithFilter[T]): (T) -> bool = + a.fil.test + + var s = SeqGen[cint](fil: FilterMixin[cint](test: nil, trans: nil)) + doAssert s.test() == nil + +block concept_with_int: + type + FilterMixin[T] = ref object + test: (T) -> bool + trans: (T) -> T + + SeqGen[T] = ref object + fil: FilterMixin[T] + + WithFilter[T] = concept a + a.fil is FilterMixin[T] + + proc test[T](a: WithFilter[T]): (T) -> bool = + a.fil.test + + var s = SeqGen[int](fil: FilterMixin[int](test: nil, trans: nil)) + doAssert s.test() == nil block t6770: diff --git a/tests/proc/tbackendtypealias.nim b/tests/proc/tbackendtypealias.nim new file mode 100644 index 0000000000..eaae0c2917 --- /dev/null +++ b/tests/proc/tbackendtypealias.nim @@ -0,0 +1,44 @@ +# bug #25617 +# Ensure that proc types with backend type alias mismatches +# (e.g. uint vs csize_t) are rejected at the Nim level rather +# than producing invalid C code. + +discard """ + cmd: "nim check --hints:off --warnings:off --errorMax:0 $file" + action: "reject" + nimout: ''' +tbackendtypealias.nim(21, 7) Error: type mismatch: got but expected 'proc (len: uint){.closure.}' +tbackendtypealias.nim(28, 7) Error: type mismatch: got but expected 'proc (len: csize_t){.closure.}' +''' +""" + +block direct_assignment: + # Direct proc variable assignment with backend type alias mismatch + var + a: proc (len: uint) + b: proc (len: csize_t) + c = a + c = b + +block direct_assignment_reverse: + var + a: proc (len: csize_t) + b: proc (len: uint) + c = a + c = b + +block same_backend_type: + # Same backend type should still work + var + a: proc (len: uint) + b: proc (len: uint) + c = a + c = b + +block cint_same_type: + # cint to cint should work + var + a: proc (len: cint) + b: proc (len: cint) + c = a + c = b