Skip to content

Commit

Permalink
Fixed generic inheritances dispatch (nim-lang#5)
Browse files Browse the repository at this point in the history
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())
```
  • Loading branch information
beef331 authored Oct 25, 2021
1 parent 6bb8a65 commit bfe544a
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
4 changes: 4 additions & 0 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1412,6 +1412,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
let origF = f
var f = if prev == nil: f else: prev

if a.len > 0:
let skippedA = a.skipTypesOrNil({tyObject}) # Skips if it's inheriting from a generic
if skippedA != nil:
a = skippedA
let roota = a.skipGenericAlias
let rootf = f.skipGenericAlias

Expand Down
44 changes: 44 additions & 0 deletions tests/types/tinheritance_generic_dispatch.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
discard """
action: reject
cmd: '''nim check --hints:off $options $file'''
nimoutFull: true
nimout: '''
tinheritance_generic_dispatch.nim(43, 5) Error: type mismatch: got <U>
but expected one of:
proc test(u: Union[string, RootObj])
first type mismatch at position: 1
required type for u: Union[system.string, system.RootObj]
but expression 'U()' is of type: U
expression: test(U())
tinheritance_generic_dispatch.nim(45, 6) Error: type mismatch: got <T>
but expected one of:
proc test2(u: Union[int, float])
first type mismatch at position: 1
required type for u: Union[system.int, system.float]
but expression 'T()' is of type: T
expression: test2(T())
tinheritance_generic_dispatch.nim(47, 6) Error: type mismatch: got <Union[system.string, system.RootObj]>
but expected one of:
proc test2(u: Union[int, float])
first type mismatch at position: 1
required type for u: Union[system.int, system.float]
but expression 'Union[string, RootObj]()' is of type: Union[system.string, system.RootObj]
expression: test2(Union[string, RootObj]())
'''
"""

type
Union[T, U] = object of RootObj

U = object of Union[int, float]
T = object of Union[string, RootObj]

proc test(u: Union[string, RootObj]) = discard
proc test2(u: Union[int, float]) = discard

test(T())
test(U())
test(Union[string, RootObj]())
test2(T())
test2(U())
test2(Union[string, RootObj]())

0 comments on commit bfe544a

Please sign in to comment.