mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 18:02:05 +00:00
Generic parameters now can constrain statics in type definitions (#19362)
* Parameters now can constrain static in type definitions
resolved regression with generic procedures
* Update compiler/sigmatch.nim
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
(cherry picked from commit a93f6e7acc)
This commit is contained in:
@@ -1739,11 +1739,22 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
let prev = PType(idTableGet(c.bindings, f))
|
||||
if prev == nil:
|
||||
if aOrig.kind == tyStatic:
|
||||
if f.base.kind != tyNone:
|
||||
if f.base.kind notin {tyNone, tyGenericParam}:
|
||||
result = typeRel(c, f.base, a, flags)
|
||||
if result != isNone and f.n != nil:
|
||||
if not exprStructuralEquivalent(f.n, aOrig.n):
|
||||
result = isNone
|
||||
elif f.base.kind == tyGenericParam:
|
||||
# Handling things like `type A[T; Y: static T] = object`
|
||||
if f.base.len > 0: # There is a constraint, handle it
|
||||
result = typeRel(c, f.base.lastSon, a, flags)
|
||||
else:
|
||||
# No constraint
|
||||
if tfGenericTypeParam in f.flags:
|
||||
result = isGeneric
|
||||
else:
|
||||
# for things like `proc fun[T](a: static[T])`
|
||||
result = typeRel(c, f.base, a, flags)
|
||||
else:
|
||||
result = isGeneric
|
||||
if result != isNone: put(c, f, aOrig)
|
||||
@@ -1993,7 +2004,6 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
|
||||
arg = argSemantized
|
||||
a = a
|
||||
c = m.c
|
||||
|
||||
if tfHasStatic in fMaybeStatic.flags:
|
||||
# XXX: When implicit statics are the default
|
||||
# this will be done earlier - we just have to
|
||||
|
||||
42
tests/generics/tstatic_constrained.nim
Normal file
42
tests/generics/tstatic_constrained.nim
Normal file
@@ -0,0 +1,42 @@
|
||||
discard """
|
||||
cmd: "nim check --hints:off --warnings:off $file"
|
||||
action: "reject"
|
||||
nimout:'''
|
||||
tstatic_constrained.nim(41, 20) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(27, 3)]
|
||||
got: <typedesc[int], int literal(10)>
|
||||
but expected: <T: float or string, Y>
|
||||
tstatic_constrained.nim(41, 20) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(27, 3)]
|
||||
got: <typedesc[int], int literal(10)>
|
||||
but expected: <T: float or string, Y>
|
||||
tstatic_constrained.nim(41, 29) Error: object constructor needs an object type [proxy]
|
||||
tstatic_constrained.nim(41, 29) Error: expression '' has no type (or is ambiguous)
|
||||
tstatic_constrained.nim(42, 20) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(27, 3)]
|
||||
got: <typedesc[byte], uint8>
|
||||
but expected: <T: float or string, Y>
|
||||
tstatic_constrained.nim(42, 20) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(27, 3)]
|
||||
got: <typedesc[byte], uint8>
|
||||
but expected: <T: float or string, Y>
|
||||
tstatic_constrained.nim(42, 32) Error: object constructor needs an object type [proxy]
|
||||
tstatic_constrained.nim(42, 32) Error: expression '' has no type (or is ambiguous)
|
||||
'''
|
||||
"""
|
||||
|
||||
type
|
||||
MyType[T; X: static T] = object
|
||||
data: T
|
||||
MyOtherType[T: float or string, Y: static T] = object
|
||||
|
||||
func f[T,X](a: MyType[T,X]): MyType[T,X] =
|
||||
when T is string:
|
||||
MyType[T,X](data: a.data & X)
|
||||
else:
|
||||
MyType[T,X](data: a.data + X)
|
||||
|
||||
discard MyType[int, 2](data: 1)
|
||||
discard MyType[string, "Helelello"](data: "Hmmm")
|
||||
discard MyType[int, 2](data: 1).f()
|
||||
discard MyType[string, "Helelello"](data: "Hmmm").f()
|
||||
discard MyOtherType[float, 1.3]()
|
||||
discard MyOtherType[string, "Hello"]()
|
||||
discard MyOtherType[int, 10]()
|
||||
discard MyOtherType[byte, 10u8]()
|
||||
Reference in New Issue
Block a user