Bug 12150 – Regression (2.063): char[] implicitly converts to string in .dup expression
Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-02-13T02:10:00Z
Last change time
2014-02-13T07:42:50Z
Keywords
accepts-invalid
Assigned to
nobody
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2014-02-13T02:10:17Z
-----
int foo(string arg)
{
return foo(arg.dup); // calls itself, stack overflow!
}
void main()
{
foo("foo");
}
-----
Note that storing the .dup to a variable first avoids the accepts-invalid:
-----
int foo(string arg)
{
auto duped = arg.dup;
return foo(duped); // NG, caught at compile-time
}
void main()
{
foo("foo");
}
-----
Comment #1 by andrej.mitrovich — 2014-02-13T02:12:32Z
Here's the slightly reduced example code of where I ran into the issue:
-----
import std.file;
int parseCode(string code)
{
return parseCode(code.dup);
}
int parseCode(ubyte[] code)
{
return 0;
}
void main()
{
parseCode(cast(ubyte[])std.file.read("test.d")); // ok
parseCode("foo"); // stack overflow
}
-----
Comment #2 by k.hara.pg — 2014-02-13T07:01:39Z
This is an intended change. See issue 9656.
Comment #3 by andrej.mitrovich — 2014-02-13T07:28:15Z
But the regression is likely unintended. Did anyone actually request for the feature in Issue 9656? Magical built-in behavior is something we should avoid IMHO, exactly because of issues like this..
Comment #4 by bearophile_hugs — 2014-02-13T07:31:38Z
(In reply to comment #3)
> Magical built-in behavior is something we should avoid
> IMHO, exactly because of issues like this..
On the other hand the change of Issue 9656 seems useful.
Comment #5 by jakobovrum — 2014-02-13T07:35:19Z
(In reply to comment #3)
> But the regression is likely unintended. Did anyone actually request for the
> feature in Issue 9656? Magical built-in behavior is something we should avoid
> IMHO, exactly because of issues like this..
I might be missing something, but where is the regression? The example you posted doesn't seem to be a regression because char[] isn't implicitly convertible to either `string` or `ubyte[]`, so surely the code would simply not compile.
Comment #6 by k.hara.pg — 2014-02-13T07:37:52Z
(In reply to comment #3)
> But the regression is likely unintended. Did anyone actually request for the
> feature in Issue 9656? Magical built-in behavior is something we should avoid
> IMHO, exactly because of issues like this..
That is not magic. It is consistent with the implicit conversion for the returned value from pure function.
E[] dup(E)(const(E)[] src) pure
{
E[] r;
r.reserve(src.length);
foreach (ref e; src)
r ~= e;
return r;
}
int foo(string arg)
{
return foo(dup(arg));
// returned char[] is implicitly convertible to string
}
void main()
{
foo("foo");
}
Comment #7 by andrej.mitrovich — 2014-02-13T07:42:50Z
(In reply to comment #5)
> I might be missing something, but where is the regression? The example you
> posted doesn't seem to be a regression because char[] isn't implicitly
> convertible to either `string` or `ubyte[]`, so surely the code would simply
> not compile.
Ah I thought it would compile, after I added an explicit cast to avoid the recursive call it ended up compiling, but it wouldn't otherwise even though I thought it would. So you're right.
There's no regression here. The below test-case works properly:
-----
int foo(string arg)
{
return foo(arg.dup); // calls second overload
}
int foo(char[] b)
{
assert(0);
}
void main()
{
auto x = foo("");
}
-----