D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 20848 - Bug in formatValueImpl
Summary: Bug in formatValueImpl
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: x86_64 Linux
: P1 normal
Assignee: No Owner
URL:
Keywords: pull
Depends on:
Blocks:
 
Reported: 2020-05-19 19:12 UTC by Victor Porton
Modified: 2021-01-28 10:21 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Victor Porton 2020-05-19 19:12:46 UTC
Apaprently I found a bug in `Nullable`:

https://github.com/vporton/nullable-mofile-bug

///////////////////
import std.typecons;
import mofile;

Nullable!MoFile mo;
///////////////////

/snap/dmd/102/bin/../import/phobos/std/format.d(3217,9): Error: static assert:  "immutable(void)[] must be an InputRange"
/snap/dmd/102/bin/../import/phobos/std/format.d(1875,20):        instantiated from here: formatValueImpl!(Appender!string, immutable(void)[], char)
/snap/dmd/102/bin/../import/phobos/std/format.d(3749,16):        instantiated from here: formatValue!(Appender!string, immutable(void)[], char)
/snap/dmd/102/bin/../import/phobos/std/format.d(4451,30):        instantiated from here: formatElement!(Appender!string, immutable(void)[], char)
/snap/dmd/102/bin/../import/phobos/std/format.d(1875,20):        ... (2 instantiations, -v to show) ...
/snap/dmd/102/bin/../import/phobos/std/typecons.d(2791,17):        instantiated from here: toString!(Appender!string)
source/test.d(4,1):        instantiated from here: Nullable!(MoFile)
dmd failed with exit code 1.

$ dmd --version
DMD64 D Compiler v2.090.1
Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved written by Walter Bright
Comment 1 Victor Porton 2020-05-20 06:22:51 UTC
A simpler test case:

///////////////////////////////
import std.typecons;

struct MoFile {
    immutable(void)[] data;
}

Nullable!MoFile mo;
///////////////////////////////

$ dmd test.d 
/snap/dmd/102/bin/../import/phobos/std/format.d(3217): Error: static assert:  "immutable(void)[] must be an InputRange"
/snap/dmd/102/bin/../import/phobos/std/format.d(1875):        instantiated from here: formatValueImpl!(Appender!string, immutable(void)[], char)
/snap/dmd/102/bin/../import/phobos/std/format.d(3749):        instantiated from here: formatValue!(Appender!string, immutable(void)[], char)
/snap/dmd/102/bin/../import/phobos/std/format.d(4451):        instantiated from here: formatElement!(Appender!string, immutable(void)[], char)
/snap/dmd/102/bin/../import/phobos/std/format.d(1875):        ... (2 instantiations, -v to show) ...
/snap/dmd/102/bin/../import/phobos/std/typecons.d(2791):        instantiated from here: toString!(Appender!string)
test.d(7):        instantiated from here: Nullable!(MoFile)
Comment 2 Victor Porton 2020-05-20 06:42:22 UTC
The error is here (format.d from phobos):

private void formatValueImpl(Writer, T, Char)(auto ref Writer w, T obj, scope const ref FormatSpec!Char f)
if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
{
    static if (is(const(ArrayTypeOf!T) == const(void[])))
    {
        formatValueImpl(w, cast(const ubyte[]) obj, f);
    }
    else static if (!isInputRange!T)
    {
        alias U = Unqual!(ArrayTypeOf!T);
        static assert(isInputRange!U, U.stringof ~ " must be an InputRange");
        U val = obj;
        formatValueImpl(w, val, f);
    }
    else
    {
        formatRange(w, obj, f);
    }
}

In the above code the type immutable(void)[] is forgotten to be considered. Somebody, please fix it.
Comment 3 Dlang Bot 2020-07-13 21:47:57 UTC
@quickfur created dlang/phobos pull request #7556 "Fix issue 20848: format should work with immutable(void)[]" fixing this issue:

- Fix issue 20848: format should work with immutable(void)[]
  
  The bug is that if `T == immutable(void)[]`, then `const(T)` does not
  collapse to `const(void[])`, but is actually `const(immutable(void)[])`.
  So a strict type equality check will fail.
  
  However, `const(T)` *is* implicitly convertible to `const(void[])`,
  which serves our purpose just as well. So just use that check instead.

https://github.com/dlang/phobos/pull/7556
Comment 4 Dlang Bot 2021-01-28 10:21:56 UTC
dlang/phobos pull request #7556 "Fix issue 20848: format should work with immutable(void)[]" was merged into master:

- 7cc61dda2ce197c44fbb6d505f31d81e654f5054 by H. S. Teoh:
  Fix issue 20848: format should work with immutable(void)[]
  
  The bug is that if `T == immutable(void)[]`, then `const(T)` does not
  collapse to `const(void[])`, but is actually `const(immutable(void)[])`.
  So a strict type equality check will fail.
  
  However, `const(T)` *is* implicitly convertible to `const(void[])`,
  which serves our purpose just as well. So just use that check instead.

https://github.com/dlang/phobos/pull/7556