D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5442 - std.algorithm.sort problem with struct with char[10]
Summary: std.algorithm.sort problem with struct with char[10]
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: x86 Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2011-01-10 10:43 UTC by bearophile_hugs
Modified: 2014-02-16 14:26 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2011-01-10 10:43:13 UTC
This D2 program tries to sort in-place a dynamic array of Foo according to just the first int x field (the third sort works on the whole structs), but when T is a char the program doesn't compile:


import std.algorithm: sort, schwartzSort;
alias char T; // doesn't work
//alias int T; // works
struct Foo {
    int x;
    T[10] a;
}
void main() {
    auto array = new Foo[10];
    sort!("a.x > b.x")(array);
    static bool myComp(Foo f1, Foo f2) { return f1.x < f2.x; }
    sort!(myComp)(array);
    sort(array);
}



DMD 2.051 prints:
...\dmd\src\phobos\std\conv.d(99): Error: template std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) matches more than one template declaration, ...\dmd\src\phobos\std\conv.d(114):toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) and ...\dmd\src\phobos\std\conv.d(224):toImpl(T,S) if (isStaticArray!(S))
Comment 1 SomeDude 2012-04-22 14:40:11 UTC
dmd 2.059 gives:

PS E:\DigitalMars\dmd2\samples> rdmd bug.d
E:\DigitalMars\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(6802): Error: static assert  "Invalid predicate passed to sort: a < b"
bug.d(16):        instantiated from here: sort!("a < b",cast(SwapStrategy)0,Foo[])
PS E:\DigitalMars\dmd2\samples>

Which is a correct message for sort(array), as we didn't pass a comparison method for Foo structs.
If we comment out this line, everything compiles fine (but doesn't run as I expected, though), due to this :
import std.stdio;

struct Foo {
    int x;
    this(int x){this.x = x;}
}
void main() {
    auto array = new Foo[10];
    //for(int i = array.length; i > 1; i--) { array[i].x = i; }
    auto i = array.length;
    foreach(Foo f; array) { f.x = --i; write(f.x);}
    writeln();
    foreach(Foo f; array) { write(f.x);}
}

giving that:
PS E:\DigitalMars\dmd2\samples> rdmd -O bug.d
9876543210
0000000000
Comment 2 SomeDude 2012-04-22 14:59:01 UTC
(In reply to comment #1)
> (but doesn't run as I
> expected, though), due to this :
> import std.stdio;
> 
> struct Foo {
>     int x;
>     this(int x){this.x = x;}
> }
> void main() {
>     auto array = new Foo[10];
>     //for(int i = array.length; i > 1; i--) { array[i].x = i; }
>     auto i = array.length;
>     foreach(Foo f; array) { f.x = --i; write(f.x);}
>     writeln();
>     foreach(Foo f; array) { write(f.x);}
> }
> 
> giving that:
> PS E:\DigitalMars\dmd2\samples> rdmd -O bug.d
> 9876543210
> 0000000000

Never mind this part of the message, it's wrong code.
Comment 3 Xinok 2013-12-27 11:07:29 UTC
(In reply to comment #0)
> This D2 program tries to sort in-place a dynamic array of Foo according to just
> the first int x field (the third sort works on the whole structs), but when T
> is a char the program doesn't compile:
> 
> 
> import std.algorithm: sort, schwartzSort;
> alias char T; // doesn't work
> //alias int T; // works
> struct Foo {
>     int x;
>     T[10] a;
> }
> void main() {
>     auto array = new Foo[10];
>     sort!("a.x > b.x")(array);
>     static bool myComp(Foo f1, Foo f2) { return f1.x < f2.x; }
>     sort!(myComp)(array);
>     sort(array);
> }
> 

Tested in DMD 2.064.2 and I'm unable to reproduce the bug. The final line fails to compile because Foo doesn't define opCmp, but everything else is fine. The default predicate for sort is "a < b" and comparing two structs using less-than requires defining opCmp.

Unless somebody else can reproduce this issue, I think we can close this bug report.
Comment 4 Peter Alexander 2014-02-16 12:17:31 UTC
Are you happy this is fixed bearophile?
Comment 5 bearophile_hugs 2014-02-16 12:42:05 UTC
(In reply to comment #4)
> Are you happy this is fixed bearophile?

Yes, closed. The error message is clear:

...\dmd2\src\phobos\std\functional.d-mixin-102(102,1): Error: need member function opCmp() for struct Foo to compare
Comment 6 Peter Alexander 2014-02-16 14:26:12 UTC
Changed to WORKSFORME so that it doesn't appear in the changelog for next update.