From 07d50cedf012ff8ca39c61c0ba5c43e5d588e630 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Mon, 19 Jun 2017 23:01:41 +0300 Subject: [PATCH] Fix #5983 --- compiler/semexprs.nim | 5 ++++- compiler/types.nim | 6 ++++++ tests/concepts/t5983.nim | 22 ++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tests/concepts/t5983.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 8169e359a8..08a2e2ce9a 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 2b4ba12d15..dc7cd52dbb 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 0000000000..e696474483 --- /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 +