Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,16 @@ proc procParamTypeRel(c: var TCandidate; f, a: PType): TTypeRelation =
# if f is metatype.
result = typeRel(c, f, a)

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

Expand Down
2 changes: 1 addition & 1 deletion compiler/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
c.flags = oldFlags

if x == y: return true
let aliasSkipSet = maybeSkipRange({tyAlias})
let aliasSkipSet = maybeSkipRange({tyAlias, tyInferred})
var a = skipTypes(x, aliasSkipSet)
while a.kind == tyUserTypeClass and tfResolved in a.flags:
a = skipTypes(a.last, aliasSkipSet)
Expand Down
36 changes: 36 additions & 0 deletions tests/concepts/tconcepts_issues.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
44 changes: 44 additions & 0 deletions tests/proc/tbackendtypealias.nim
Original file line number Diff line number Diff line change
@@ -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 <proc (len: csize_t){.closure.}> but expected 'proc (len: uint){.closure.}'
tbackendtypealias.nim(28, 7) Error: type mismatch: got <proc (len: uint){.closure.}> 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