concept patch: inheritance (#25317)

adds some inheritance support

---------

Co-authored-by: Andreas Rumpf <araq4k@proton.me>
This commit is contained in:
Ryan McConnell
2025-12-03 11:51:18 -05:00
committed by GitHub
parent 1da0dc74d9
commit 86bbc73b3a
3 changed files with 39 additions and 0 deletions

View File

@@ -263,6 +263,22 @@ proc conceptsMatch(c: PContext, fc, ac: PType; m: var MatchCon): MatchKind =
return mkNoMatch
return mkSubset
proc isObjectSubtype(f, a: PType): bool =
var t = a
result = false
while t != nil:
t = t.baseClass
if t == nil:
break
t = t.skipTypes({tyPtr,tyRef})
if t == nil:
break
if t.kind != tyObject:
break
if sameObjectTypes(f, t):
result = true
break
proc matchType(c: PContext; fo, ao: PType; m: var MatchCon): bool =
## The heart of the concept matching process. 'f' is the formal parameter of some
## routine inside the concept that we're looking for. 'a' is the formal parameter
@@ -327,6 +343,8 @@ proc matchType(c: PContext; fo, ao: PType; m: var MatchCon): bool =
result = a.base.sym == f.sym
else:
result = sameType(f, a)
if not result and f.kind == tyObject and a.kind == tyObject:
result = isObjectSubtype(f, a)
of tyEmpty, tyString, tyCstring, tyPointer, tyNil, tyUntyped, tyTyped, tyVoid:
result = a.skipTypes(ignorableForArgType).kind == f.kind
of tyBool, tyChar, tyInt..tyUInt64:

View File

@@ -3008,6 +3008,12 @@ is more specific
2. if the concept is being compared with another concept the result is deferred to [Concept subset matching]
3. in any other case the concept is less specific then it's competitor
Currently, the concept evaluation mechanism evaluates to a successful match on the first acceptable candidate
for each defined binding. This has a couple of notable effects:
- generic parameters are fulfilled by the first candidate match even if other candidates would also match and bind different parameters
- inheritable objects match as they do in normal overload resolution except the "depth" is not accounted for, because that would require calculating the minimum depth of any matching binding
Concept subset matching
-------------------------

View File

@@ -585,3 +585,18 @@ block:
discard
assert (ref AObj[int]) is C
block:
type
C = concept
proc x(a:Self, x: int)
StreamObj = object of RootObj
Stream = ref StreamObj
MemMapFileStreamObj = object of Stream
MemMapFileStream = ref MemMapFileStreamObj
proc x(a: Stream, x: int) = discard
proc spring(x: C) = discard
let test = MemMapFileStream()
spring(test)