summary refs log tree commit diff stats
path: root/tests/generics/tfakecovariance.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/generics/tfakecovariance.nim')
-rw-r--r--tests/generics/tfakecovariance.nim51
1 files changed, 48 insertions, 3 deletions
diff --git a/tests/generics/tfakecovariance.nim b/tests/generics/tfakecovariance.nim
index 835acd9d3..bca285283 100644
--- a/tests/generics/tfakecovariance.nim
+++ b/tests/generics/tfakecovariance.nim
@@ -1,11 +1,56 @@
+template accept(x) =
+  static: assert(compiles(x))
+
+template reject(x) =
+  static: assert(not compiles(x))
+
 type
   BaseObj = object of RootObj
   DerivedObj = object of BaseObj
+  NonDerivedObj = object
 
   Container[T] = object
 
-proc doSomething(c: Container[BaseObj or DerivedObj]) = discard
+var base: BaseObj
+var derived: DerivedObj
+var nonDerived: NonDerivedObj
+
+var baseContainer: Container[BaseObj]
+var derivedContainer: Container[DerivedObj]
+var nonDerivedContainer: Container[NonDerivedObj]
+
+# We can fake covariance by listing some specific derived types that
+# will be allowed with our overload. This is not a real covariance,
+# because there will be multiple instantiations of the proc, but for
+# many purposes, it will suffice:
+
+proc wantsSpecificContainers(c: Container[BaseObj or DerivedObj]) = discard
+
+accept wantsSpecificContainers(baseContainer)
+accept wantsSpecificContainers(derivedContainer)
+
+reject wantsSpecificContainers(nonDerivedContainer)
+reject wantsSpecificContainers(derived)
+
+# Now, let's make a more general solution able to catch all derived types:
+
+type
+  DerivedFrom[T] = concept type A
+    var derived: ref A
+    var base: ref T = derived
+
+proc wantsDerived(x: DerivedFrom[BaseObj]) = discard
+
+accept wantsDerived(base)
+accept wantsDerived(derived)
+
+reject wantsDerived(nonDerived)
+reject wantsDerived(baseContainer)
+
+proc wantsDerivedContainer(c: Container[DerivedFrom[BaseObj]]) = discard
+
+accept wantsDerivedContainer(baseContainer)
+accept wantsDerivedContainer(derivedContainer)
 
-var t: Container[DerivedObj]
-doSomething t
+reject wantsDerivedContainer(nonDerivedContainer)