[Issue 17319] New: icmp - cannot use in sort with string array arguments - compilation fails

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Tue Apr 11 09:32:36 PDT 2017


https://issues.dlang.org/show_bug.cgi?id=17319

          Issue ID: 17319
           Summary: icmp - cannot use in sort with string array arguments
                    - compilation fails
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Windows
            Status: NEW
          Severity: regression
          Priority: P1
         Component: phobos
          Assignee: nobody at puremagic.com
          Reporter: furrymurray780 at gmail.com

The following code will not compile:

import std.algorithm;
import std.range;
import std.uni;
/// Performs [["foo", "bar"], ["baz"]] -> ["baz", "foo bar"]
auto alphabetized(Range)(Range range)
{
     return range
          .map!(line => line.joiner(" "))
          .array
          .sort!((a, b) => icmp(a, b) < 0);
}

void main()
{
   auto a = alphabetized([["foo", "bar"], ["baz"]]);
}

Here's the error message I get:
>
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\uni.d(7082): Error:
> function 'std.algorithm.searching.skipOver!(Result,
> dstring).skipOver' is not nothrow
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\uni.d(7055): Error:
> nothrow function 'std.uni.fullCasedCmp!(Result).fullCasedCmp' may
> throw
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\uni.d(7136): Error:
> template instance std.uni.fullCasedCmp!(Result) error
> instantiating
> test.d(14):        instantiated from here: icmp!(Result, Result)
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\sorting.d(1851):
>   instantiated from here: __lambda3!(Result, Result) test.d(14):
> instantiated from here: sort!((a, b) =>
> icmp(a, b) < 0, cast(SwapStrategy)0, Result[])
> test.d(19):        instantiated from here:
> alphabetized!(string[][])
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\sorting.d(1863):
> Error: static assert  "Invalid predicate passed to sort: __lambda3"
> test.d(14):        instantiated from here: sort!((a, b) =>
> icmp(a, b) < 0, cast(SwapStrategy)0, Result[])
> test.d(19):        instantiated from here:
> alphabetized!(string[][])

This is the explanation I got on dlang.learn
(http://forum.dlang.org/post/mailman.1574.1491925305.31550.digitalmars-d-learn@puremagic.com):

Well, it's telling you that skipOver isn't nothrow, which only matters if it's
being called from a nothrow function. It's then telling you that fullCasedCmp
can't compile, because it's marked as nothrow, and it's calling a function that
isn't nothrow (and thus could throw) - since it's calling skipOver. In turn,
it's telling you that it can't instantiate fullCasedCmp (since it couldn't
compile it, because it's nothrow but is calling a function that can throw).
It's then telling you that fullCaseCmp was instantiated inside of icmp and that
icmp was instantiated inside of a lambda that's at line 14 of test.d. At that
point, you see a line in your code, so you know where in your code things went
wrong, but it continues on, indicating that that means that sort won't compile
and then that alphabetized won't compile.

So, the problem here at the root of all of this is that when icmp is compiled
with the ranges that you gave it, skipOver is inferred to _not_ be nothrow,
whereas fullCasedCmp which is calling skipOver and in turn is called from icmp
is marked as nothrow. So, the ranges that you're passing to icmp have functions
which are called in skipOver which are not nothrow (probably front and
popFront).

This is a bug with fullCasedCmp (which is a private function calle by icmp).
Someone decided to mark it as nothrow when it should _not_ have been marked as
nothrow. It's also marked as @trusted and pure - both of which are also wrong.
The code is incorrectly assuming that the ranges that will be passed in have
pure and nothrow functions and that they're not doing anything @system which
can't be assumed to be @trusted. That will be true for some ranges but not
others. In general, marking templated functions with attributes is a problem
for exactly this reason. They must correctly apply to _all_ valid template
arguments, or they shouldn't be there.

So, this should be reported as a bug in icmp.

--


More information about the Digitalmars-d-bugs mailing list