diff options
author | LemonBoy <LemonBoy@users.noreply.github.com> | 2018-07-09 20:05:53 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-07-09 20:05:53 +0200 |
commit | 5c5388c0a66c35319e2f360744ab0b9183ca5160 (patch) | |
tree | 379130781a2b3ec8e3687acf748afa329f8b33a9 | |
parent | 854aa3958faa3603ab4ebfc72ea4c275e025a70c (diff) | |
download | Nim-5c5388c0a66c35319e2f360744ab0b9183ca5160.tar.gz |
Handle subtype relations for converter parameters (#8248)
Fixes #7098
-rw-r--r-- | compiler/sigmatch.nim | 9 | ||||
-rw-r--r-- | tests/converter/t7098.nim | 31 |
2 files changed, 38 insertions, 2 deletions
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(@[]) |