gedaiu / fluent-asserts

DLang fluent assertions done right
http://fluentasserts.szabobogdan.com/
MIT License
43 stars 6 forks source link

Compilation fails for arrays of structs/classes with member functions #21

Closed AntonMeep closed 7 years ago

AntonMeep commented 7 years ago

Test case:

unittest {
    struct S {
        void f() {}
    }
    [S()].should.equal([S()]);
}

Fails with:

/usr/include/dlang/dmd/object.d(3756,5): Error: static assert  "Cannot implicitly convert type S to immutable in idup."
../../../.dub/packages/fluent-asserts-0.6.5/fluent-asserts/core/fluentasserts/core/array.d(20,35):        instantiated from here: idup!(S)
../../../.dub/packages/fluent-asserts-0.6.5/fluent-asserts/core/fluentasserts/core/array.d(194,39):        instantiated from here: __ctor!(S[], const(S)[])
../../../.dub/packages/fluent-asserts-0.6.5/fluent-asserts/core/fluentasserts/core/base.d(263,14):        instantiated from here: ShouldList!(S[])
fatestcase.d(16,6):        instantiated from here: should!(S[])

Same for classes:

unittest {
    class C {
        void f() {}
    }
    [new C()].should.equal([new C()]);
}

Which fails with:

/usr/include/dlang/dmd/std/format.d(3460,13): Error: template instance std.format.formatObject!(Appender!string, const(S), char) does not match template declaration formatObject(Writer, T, Char)(ref Writer w, ref T val, ref const FormatSpec!Char f) if (hasToString!(T, Char))
/usr/include/dlang/dmd/std/format.d(3190,16): Error: template instance std.format.formatValue!(Appender!string, const(S), char) error instantiating
/usr/include/dlang/dmd/std/format.d(2969,30):        instantiated from here: formatElement!(Appender!string, const(S), char)
/usr/include/dlang/dmd/std/format.d(2671,20):        instantiated from here: formatRange!(Appender!string, const(S)[], char)
/usr/include/dlang/dmd/std/conv.d(137,24):        instantiated from here: formatValue!(Appender!string, const(S)[], char)
/usr/include/dlang/dmd/std/conv.d(974,23):        ... (3 instantiations, -v to show) ...
../../../.dub/packages/fluent-asserts-0.6.5/fluent-asserts/core/fluentasserts/core/base.d(263,14):        instantiated from here: ShouldList!(S[])
fatestcase.d(16,11):        instantiated from here: should!(S[])
/usr/include/dlang/dmd/object.d(3756,5): Error: static assert  "Cannot implicitly convert type S to immutable in idup."
../../../.dub/packages/fluent-asserts-0.6.5/fluent-asserts/core/fluentasserts/core/array.d(20,35):        instantiated from here: idup!(S)
../../../.dub/packages/fluent-asserts-0.6.5/fluent-asserts/core/fluentasserts/core/array.d(194,39):        instantiated from here: __ctor!(S[], const(S)[])
../../../.dub/packages/fluent-asserts-0.6.5/fluent-asserts/core/fluentasserts/core/base.d(263,14):        instantiated from here: ShouldList!(S[])
fatestcase.d(16,11):        instantiated from here: should!(S[])

I tested it with:

$ dmd --version 
DMD64 D Compiler v2.075.0
Copyright (c) 1999-2017 by Digital Mars written by Walter Bright
$ ldc2 --version
LDC - the LLVM D compiler (1.3.0):
  based on DMD v2.073.2 and LLVM 4.0.0
  built with LDC - the LLVM D compiler (1.3.0)
  Default target: x86_64-unknown-linux-gnu
  Host CPU: silvermont
$ gdc --version 
gdc (gdcproject.org 20161225-v2.068.2_gcc4.8) 4.8.5

Also, looks like it happens only if struct/class is defined inside unittest block. I discovered this issue when worked on my code, but in my code struct is defined outside unittest block and it still fails. So, I am not sure that this is fluent-asserts' bug, probably this is the bug in compiler.

UPD: So, it isn't a bug in the compiler

gedaiu commented 7 years ago
[new C()].should.equal([new C()]);

Will not be equal in your case because they are not equal. I think that in order to get this to work you need to override some operators like opEquals and maybe toString.

Anyway I fixed the compiler errors and it should work with the next release.

Thanks, for the issue!