dmd 2.064.2 on linux x86_64
module bug;
import std.stdio;
void foo() {
bool b;
readf("%s", b);
}
/home/jlquinn/dmd2/linux/bin64/dmd -g -c readf.bug.d
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/format.d(3938): Error: template std.conv.parse does not match any function template declaration. Candidates are:
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/conv.d(1943): std.conv.parse(Target, Source)(ref Source s) if (isSomeChar!(ElementType!Source) && isIntegral!Target && !is(Target == enum))
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/conv.d(2203): std.conv.parse(Target, Source)(ref Source s, uint radix) if (isSomeChar!(ElementType!Source) && isIntegral!Target && !is(Target == enum))
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/conv.d(2299): std.conv.parse(Target, Source)(ref Source s) if (isExactSomeString!Source && is(Target == enum))
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/conv.d(2358): std.conv.parse(Target, Source)(ref Source p) if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) && isFloatingPoint!Target && !is(Target == enum))
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/conv.d(2834): std.conv.parse(Target, Source)(ref Source s) if (isExactSomeString!Source && staticIndexOf!(Unqual!Target, dchar, Unqual!(ElementEncodingType!Source)) >= 0)
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/format.d(3938): ... (7 more, -v to show) ...
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/format.d(3938): Error: template std.conv.parse(Target, Source)(ref Source s) if (isSomeChar!(ElementType!Source) && isIntegral!Target && !is(Target == enum)) cannot deduce template function from argument types !(bool)(LockingTextReader)
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/format.d(582): Error: template instance std.format.unformatValue!(bool, LockingTextReader, char) error instantiating
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/stdio.d(1005): instantiated from here: formattedRead!(LockingTextReader, char, bool*)
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/stdio.d(2130): instantiated from here: readf!(bool*)
readf.bug.d(8): instantiated from here: readf!(bool*)
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/stdio.d(1005): Error: template instance std.format.formattedRead!(LockingTextReader, char, bool*) error instantiating
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/stdio.d(2130): instantiated from here: readf!(bool*)
readf.bug.d(8): instantiated from here: readf!(bool*)
/home/jlquinn/dmd2/linux/bin64/../../src/phobos/std/stdio.d(2130): Error: template instance std.stdio.File.readf!(bool*) error instantiating
readf.bug.d(8): instantiated from here: readf!(bool*)
readf.bug.d(8): Error: template instance std.stdio.readf!(bool*) error instantiating
Comment #1 by jlquinn — 2013-12-06T23:20:16Z
Tracking this down further, the issue appears to be that formattedRead(range, "%s", &bool) calls unformatValue!bool(range, formatSpec) which calls parse!bool(range).
However, parse!bool doesn't seem to accept an input range:
import std.conv;
import std.range;
void foo() {
string s = "1";
auto ir = inputRangeObject(s);
int i = parse!int(ir); // OK
string sb = "true";
auto irb = inputRangeObject(sb);
bool b2 = parse!bool(irb); // Error
}
I *think* the problem is that
Target parse(Target, Source)(ref Source s)
if (isExactSomeString!Source &&
is(Unqual!Target == bool)) { ... }
requires a string rather than an input range. A version of parse!bool that accepts a range would fix the problem.
Comment #2 by jlquinn — 2013-12-07T14:06:08Z
Something like this?
Target parse(Target, Source)(ref Source s)
if (isSomeChar!(ElementType!Source) &&
is(Unqual!Target == bool))
{
if (skipOver!("std.ascii.toLower(a) == b")(s, "true"))
return true;
if (skipOver!("std.ascii.toLower(a) == b")(s, "false"))
return false;
throw convError!(Source, Target)(s);
}
Comment #3 by peter.alexander.au — 2014-03-08T11:53:36Z