summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJason Beetham <beefers331@gmail.com>2022-01-15 01:24:23 -0700
committerGitHub <noreply@github.com>2022-01-15 09:24:23 +0100
commit7bdfeb78190ca9ff6a0cf702c6ec202f379bff2f (patch)
treed5a68938e8277fe36a1963aa787f767df3a8cbaf
parenta93f6e7acc9e02deb40a864d345e4c715346a98c (diff)
downloadNim-7bdfeb78190ca9ff6a0cf702c6ec202f379bff2f.tar.gz
Fixed concept constraints for static types (#19391)
-rw-r--r--compiler/sigmatch.nim9
-rw-r--r--tests/generics/tstatic_constrained.nim87
2 files changed, 71 insertions, 25 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 4d8e03fe9..e1195d04a 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -1634,6 +1634,15 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
           bindConcreteTypeToUserTypeClass(matched, a)
           if doBind: put(c, f, matched)
           result = isGeneric
+        elif a.len > 0 and a.lastSon == f:
+          # Needed for checking `Y` == `Addable` in the following
+          #[
+            type 
+              Addable = concept a, type A
+                a + a is A
+              MyType[T: Addable; Y: static T] = object
+          ]#
+          result = isGeneric
         else:
           result = isNone
 
diff --git a/tests/generics/tstatic_constrained.nim b/tests/generics/tstatic_constrained.nim
index 07318d1bd..3c9201548 100644
--- a/tests/generics/tstatic_constrained.nim
+++ b/tests/generics/tstatic_constrained.nim
@@ -2,41 +2,78 @@ 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)]
+tstatic_constrained.nim(44, 22) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(30, 5)]
 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)]
+tstatic_constrained.nim(44, 22) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(30, 5)]
 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)]
+tstatic_constrained.nim(44, 31) Error: object constructor needs an object type [proxy]
+tstatic_constrained.nim(44, 31) Error: expression '' has no type (or is ambiguous)
+tstatic_constrained.nim(45, 22) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(30, 5)]
 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)]
+tstatic_constrained.nim(45, 22) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(30, 5)]
 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)
+tstatic_constrained.nim(45, 34) Error: object constructor needs an object type [proxy]
+tstatic_constrained.nim(45, 34) Error: expression '' has no type (or is ambiguous)
+tstatic_constrained.nim(77, 14) Error: cannot instantiate MyType [type declared in tstatic_constrained.nim(71, 5)]
+got: <typedesc[float], float64>
+but expected: <T: MyConstraint, Y>
 '''
 """
+block:
+  type 
+    MyType[T; X: static T] = object
+      data: T
+    MyOtherType[T: float or string, Y: static T] = object
 
-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)
 
-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]()
 
-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]()
\ No newline at end of file
+block:
+  type
+    Moduloable = concept m, type M
+      m mod m is M
+    Addable = concept a, type A
+      a + a is A
+    Modulo[T: Moduloable; Mod: static T] = distinct T
+    ModuloAdd[T: Moduloable or Addable; Mod: static T] = distinct T
+    ModuAddable = Addable or Moduloable
+    ModdAddClass[T: ModuAddable; Mod: static T] = distinct T
+
+  proc toMod[T](val: T, modVal: static T): Modulo[T, modVal] =
+    mixin `mod`
+    Modulo[T, modVal](val mod modVal)
+  var
+    a = 3231.toMod(10)
+    b = 5483.toMod(10)
+  discard ModuloAdd[int, 3](0)
+  discard ModdAddClass[int, 3](0)
+
+block:
+  type
+    MyConstraint = int or string
+    MyOtherConstraint[T] = object
+    MyType[T: MyConstraint; Y: static T] = object
+    MyOtherType[T: MyOtherConstraint; Y: static T] = object
+
+  var 
+    a: MyType[int, 10]
+    b: MyType[string, "hello"]
+    c: MyType[float, 10d]
+    d: MyOtherType[MyOtherConstraint[float],MyOtherConstraint[float]()]
+    e: MyOtherType[MyOtherConstraint[int], MyOtherConstraint[int]()]
\ No newline at end of file