mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-11 22:08:54 +00:00
concept patch: inheritance (#25317)
adds some inheritance support --------- Co-authored-by: Andreas Rumpf <araq4k@proton.me>
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
-------------------------
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user