summary refs log tree commit diff stats
path: root/tests/tuples/t18125_1.nim
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-01-18 23:19:29 +0300
committerGitHub <noreply@github.com>2024-01-18 21:19:29 +0100
commitcfd69bad1a1071345cfcd145a7e7f906304f265f (patch)
treed1d2dbbb902a553a4f8c19e393590f3f9aba8d1e /tests/tuples/t18125_1.nim
parent3ab8b6b2cf4488c114284aa5ad5b7af0d4055312 (diff)
downloadNim-cfd69bad1a1071345cfcd145a7e7f906304f265f.tar.gz
fix wrong subtype relation in tuples & infer some conversions (#23228)
fixes #18125

Previously a tuple type like `(T, int)` would match an expected tuple
type `(U, int)` if `T` is a subtype of `U`. This is wrong since the
codegen does not handle type conversions of individual tuple elements in
a type conversion of an entire tuple. For this reason the compiler
already does not accept `(float, int)` for a matched type `(int, int)`,
however the code that checked for which relations are unacceptable
checked for `< isSubtype` rather than `<= isSubtype`, so subtypes were
not included in the unacceptable relations.

Update: Now only considered unacceptable when inheritance is used, as in
[`paramTypesMatch`](https://github.com/nim-lang/Nim/blob/3379d26629f30e6be8d303a36e220d1039eb4551/compiler/sigmatch.nim#L2252-L2254).
Ideally subtype relations that don't need conversions, like `nil`,
`seq[empty]`, `range[0..5]` etc would be their own relation
`isConcreteSubtype` (which would also allow us to differentiate with
`openArray[T]`), but this is too big of a refactor for now.

To compensate for this making things like `let x: (Parent, int) =
(Child(), 0)` not compile (they would crash codegen before anyway but
should still work in principle), type inference for tuple constructors
is updated such that they call `fitNode` on the fields and their
expected types, so a type conversion is generated for the individual
subtype element.
Diffstat (limited to 'tests/tuples/t18125_1.nim')
-rw-r--r--tests/tuples/t18125_1.nim14
1 files changed, 14 insertions, 0 deletions
diff --git a/tests/tuples/t18125_1.nim b/tests/tuples/t18125_1.nim
new file mode 100644
index 000000000..74fdfe8f5
--- /dev/null
+++ b/tests/tuples/t18125_1.nim
@@ -0,0 +1,14 @@
+# issue #18125 solved with type inference
+
+type
+  Parent = ref object of RootObj
+
+  Child = ref object of Parent
+    c: char
+
+func foo(c: char): (Parent, int) =
+  # Works if you use (Parent(Child(c: c)), 0)
+  (Child(c: c), 0)
+
+let x = foo('x')[0]
+doAssert Child(x).c == 'x'