diff options
author | metagn <metagngn@gmail.com> | 2024-01-18 23:19:29 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-18 21:19:29 +0100 |
commit | cfd69bad1a1071345cfcd145a7e7f906304f265f (patch) | |
tree | d1d2dbbb902a553a4f8c19e393590f3f9aba8d1e /tests/tuples/t18125_1.nim | |
parent | 3ab8b6b2cf4488c114284aa5ad5b7af0d4055312 (diff) | |
download | Nim-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.nim | 14 |
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' |