summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2017-06-19 23:01:41 +0300
committerAndreas Rumpf <rumpf_a@web.de>2017-06-20 11:29:42 +0200
commit07d50cedf012ff8ca39c61c0ba5c43e5d588e630 (patch)
treeb9864682618a22350123b3a3ae3f61c52382d18d
parent21ce7b2af4163b2513f3c6cbf2f52929d684bcb3 (diff)
downloadNim-07d50cedf012ff8ca39c61c0ba5c43e5d588e630.tar.gz
Fix #5983
-rw-r--r--compiler/semexprs.nim5
-rw-r--r--compiler/types.nim6
-rw-r--r--tests/concepts/t5983.nim22
3 files changed, 32 insertions, 1 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 8169e359a..08a2e2ce9 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -106,7 +106,10 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus =
       result = convNotNeedeed
     return
   var d = skipTypes(castDest, abstractVar)
-  var s = skipTypes(src, abstractVar-{tyTypeDesc})
+  var s = src
+  if s.kind in tyUserTypeClasses and s.isResolvedUserTypeClass:
+    s = s.lastSon
+  s = skipTypes(s, abstractVar-{tyTypeDesc})
   var pointers = 0
   while (d != nil) and (d.kind in {tyPtr, tyRef}) and (d.kind == s.kind):
     d = d.lastSon
diff --git a/compiler/types.nim b/compiler/types.nim
index 2b4ba12d1..dc7cd52db 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -424,6 +424,12 @@ template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) =
   tc.sons.safeAdd concrete
   tc.flags.incl tfResolved
 
+# TODO: It would be a good idea to kill the special state of a resolved
+# concept by switching to tyAlias within the instantiated procs.
+# Currently, tyAlias is always skipped with lastSon, which means that
+# we can store information about the matched concept in another position.
+# Then builtInFieldAccess can be modified to properly read the derived
+# consts and types stored within the concept.
 template isResolvedUserTypeClass*(t: PType): bool =
   tfResolved in t.flags
 
diff --git a/tests/concepts/t5983.nim b/tests/concepts/t5983.nim
new file mode 100644
index 000000000..e69647448
--- /dev/null
+++ b/tests/concepts/t5983.nim
@@ -0,0 +1,22 @@
+discard """
+  output: "20.0 USD"
+"""
+
+import typetraits
+
+const currencies = ["USD", "EUR"] # in real code 120 currencies
+
+type USD* = distinct float # in real code 120 types generates using macro
+type EUR* = distinct float
+
+type CurrencyAmount = concept c
+  type t = c.type
+  const name = c.type.name
+  name in currencies
+
+proc `$`(x: CurrencyAmount): string =
+  $float(x) & " " & x.name
+
+let amount = 20.USD
+echo amount
+