From 5c5388c0a66c35319e2f360744ab0b9183ca5160 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 9 Jul 2018 20:05:53 +0200 Subject: [PATCH] Handle subtype relations for converter parameters (#8248) Fixes #7098 --- compiler/sigmatch.nim | 9 +++++++-- tests/converter/t7098.nim | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/converter/t7098.nim diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 09f7f23b5..4bac3d3ea 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1801,7 +1801,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType, # 'f <- dest' in order to not break the unification: # see tests/tgenericconverter: let srca = typeRel(m, src, a) - if srca notin {isEqual, isGeneric}: continue + if srca notin {isEqual, isGeneric, isSubtype}: continue let destIsGeneric = containsGenericType(dest) if destIsGeneric: @@ -1814,7 +1814,12 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType, s.info = arg.info result = newNodeIT(nkHiddenCallConv, arg.info, dest) addSon(result, s) - addSon(result, copyTree(arg)) + var param: PNode = nil + if srca == isSubtype: + param = implicitConv(nkHiddenSubConv, src, copyTree(arg), m, c) + else: + param = copyTree(arg) + addSon(result, param) inc(m.convMatches) m.genericConverter = srca == isGeneric or destIsGeneric return result diff --git a/tests/converter/t7098.nim b/tests/converter/t7098.nim new file mode 100644 index 000000000..66e629fa8 --- /dev/null +++ b/tests/converter/t7098.nim @@ -0,0 +1,31 @@ +type + Byte* = uint8 + Bytes* = seq[Byte] + + BytesRange* = object + bytes: Bytes + ibegin, iend: int + +proc initBytesRange*(s: var Bytes, ibegin = 0, iend = -1): BytesRange = + let e = if iend < 0: s.len + iend + 1 + else: iend + assert ibegin >= 0 and e <= s.len + + shallow(s) + result.bytes = s + result.ibegin = ibegin + result.iend = e + +converter fromSeq*(s: Bytes): BytesRange = + var seqCopy = s + return initBytesRange(seqCopy) + +type + Reader* = object + data: BytesRange + position: int + +proc readerFromBytes*(input: BytesRange): Reader = + discard + +let r = readerFromBytes(@[])