Skip to content

Commit bfe544a

Browse files
authored
Fixed generic inheritances dispatch (nim-lang#5)
Using inherited generics does not dispatch properly and just takes the generic's base. This properly dispatches on the generic types so procs can overide based of inherited parameters. Making the following work: ```nim type A[T] {.inheritable.} = object B = object of A[int] C = object of A[float] proc doStuff(a: A[int]) = discard proc doStuff(a: A[float) = discard doStuff(B()) doStuff(C()) ```
1 parent 6bb8a65 commit bfe544a

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

compiler/sigmatch.nim

+4
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
14121412
let origF = f
14131413
var f = if prev == nil: f else: prev
14141414

1415+
if a.len > 0:
1416+
let skippedA = a.skipTypesOrNil({tyObject}) # Skips if it's inheriting from a generic
1417+
if skippedA != nil:
1418+
a = skippedA
14151419
let roota = a.skipGenericAlias
14161420
let rootf = f.skipGenericAlias
14171421

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
discard """
2+
action: reject
3+
cmd: '''nim check --hints:off $options $file'''
4+
nimoutFull: true
5+
nimout: '''
6+
tinheritance_generic_dispatch.nim(43, 5) Error: type mismatch: got <U>
7+
but expected one of:
8+
proc test(u: Union[string, RootObj])
9+
first type mismatch at position: 1
10+
required type for u: Union[system.string, system.RootObj]
11+
but expression 'U()' is of type: U
12+
expression: test(U())
13+
tinheritance_generic_dispatch.nim(45, 6) Error: type mismatch: got <T>
14+
but expected one of:
15+
proc test2(u: Union[int, float])
16+
first type mismatch at position: 1
17+
required type for u: Union[system.int, system.float]
18+
but expression 'T()' is of type: T
19+
expression: test2(T())
20+
tinheritance_generic_dispatch.nim(47, 6) Error: type mismatch: got <Union[system.string, system.RootObj]>
21+
but expected one of:
22+
proc test2(u: Union[int, float])
23+
first type mismatch at position: 1
24+
required type for u: Union[system.int, system.float]
25+
but expression 'Union[string, RootObj]()' is of type: Union[system.string, system.RootObj]
26+
expression: test2(Union[string, RootObj]())
27+
'''
28+
"""
29+
30+
type
31+
Union[T, U] = object of RootObj
32+
33+
U = object of Union[int, float]
34+
T = object of Union[string, RootObj]
35+
36+
proc test(u: Union[string, RootObj]) = discard
37+
proc test2(u: Union[int, float]) = discard
38+
39+
test(T())
40+
test(U())
41+
test(Union[string, RootObj]())
42+
test2(T())
43+
test2(U())
44+
test2(Union[string, RootObj]())

0 commit comments

Comments
 (0)