summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorLemonBoy <LemonBoy@users.noreply.github.com>2018-07-09 20:05:53 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-07-09 20:05:53 +0200
commit5c5388c0a66c35319e2f360744ab0b9183ca5160 (patch)
tree379130781a2b3ec8e3687acf748afa329f8b33a9
parent854aa3958faa3603ab4ebfc72ea4c275e025a70c (diff)
downloadNim-5c5388c0a66c35319e2f360744ab0b9183ca5160.tar.gz
Handle subtype relations for converter parameters (#8248)
Fixes #7098
-rw-r--r--compiler/sigmatch.nim9
-rw-r--r--tests/converter/t7098.nim31
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(@[])