Bug 15711 – Incorrect type inferring of [char]/string when passed via recursive template, extracting it from a structure field
Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2016-02-21T09:11:51Z
Last change time
2021-11-05T11:41:49Z
Keywords
pull, rejects-valid
Assigned to
No Owner
Creator
Alexander Tumin
Comments
Comment #0 by iamtakingiteasy — 2016-02-21T09:11:51Z
Hello, having a snip main.d like this:
--->3---
struct Quu {
string val;
}
string[] result = foo!(0, [Quu(['z']), Quu("")]);
template foo(size_t i, Quu[] data, string[] results = []) {
static if (i < data.length) {
enum def = data[i];
enum foo = foo!(i+1, data, results ~ def.val);
} else {
enum foo = results;
}
}
--->3---
which is supposed to be a recursive template implementation, converting Quu[] to string[] by extracting Quu's member 'val' at compile-time, it fails on current dmd's HEAD of git master: eb8c2c7a48404495d3a62ee5bd58e28a654e99d5 as well as on current 2.070.0 release with the folliwng message:
--->3---
main.d(9): Error: cannot implicitly convert expression ([['z'], ""]) of type const(char)[][] to string[]
main.d(9): Error: template instance main.foo!(1LU, [Quu(['z']), Quu("")], [['z']]) error instantiating
main.d(5): instantiated from here: foo!(0LU, [Quu(['z']), Quu("")], [])
--->3---
and i wasn't able to find any cast()ing or to!()-converting workaround at this point, so this why i consider severity as 'blocker', as it prevents me from proceeding at my coding task, please correct me if i am wrongfully considered it so.
Comment #1 by iamtakingiteasy — 2016-02-21T09:21:31Z
I think it also worth mentioning that without an intermediate structure (not possbile in my actual case, but theoretically):
--->3---
string[] result = foo!(0, cast(string[])([['z'], ""]));
template foo(size_t i, string[] data, string[] results = []) {
static if (i < data.length) {
enum def = data[i];
enum foo = foo!(i+1, data, results ~ def);
} else {
enum foo = results;
}
}
--->3---
it compiles both on 2.070.0 release and current git master.
Comment #2 by iamtakingiteasy — 2016-02-24T22:46:31Z
According to cast table from https://dlang.org/spec/const3.html this is not bug at all and should be the defined behavior; const(char)[], what ['z'] is, cannot be implicitly converted to immutable(char)[], which what the string is.
The solution to this case is simply wrap ['z'] into cast(string)(['z']) and all should work just fine. I'm sorry, this should be closed as not a bug.
Comment #3 by ag0aep6g — 2016-02-25T17:04:00Z
(In reply to Alexander Tumin from comment #2)
> According to cast table from https://dlang.org/spec/const3.html this is not
> bug at all and should be the defined behavior; const(char)[], what ['z'] is,
> cannot be implicitly converted to immutable(char)[], which what the string
> is.
`['z']` is an array literal, though. They're more flexible than that.
For example, dmd accepts these:
----
immutable(int)[] a = [1, 2, 3];
string s = ['z'];
Quu q = Quu(['z']);
----
I see no reason why the code in the description should be rejected when `Quu(['z'])` is accepted usually. Reopening.
Comment #4 by dlang-bot — 2021-11-05T07:55:12Z
@BorisCarvajal created dlang/dmd pull request #13268 "Fix Issue 15711 - Incorrect type inferring of [char]/string when passed via recursive template" fixing this issue:
- Fix Issue 15711 - Incorrect type inferring of [char]/string when passed via recursive template, extracting it from a structure field
https://github.com/dlang/dmd/pull/13268
Comment #5 by dlang-bot — 2021-11-05T11:41:49Z
dlang/dmd pull request #13268 "Fix Issue 15711 - Incorrect type inferring of [char]/string when passed via recursive template" was merged into master:
- dff64d487d4114106a6cd91f02b835c7d1199e9a by Boris Carvajal:
Fix Issue 15711 - Incorrect type inferring of [char]/string when passed via recursive template, extracting it from a structure field
https://github.com/dlang/dmd/pull/13268