www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What is this error message telling me?

reply Anonymous <nomail mail.com> writes:
I was watching a dconf presentation from last year and wanted to 
try this out: https://github.com/luismarques/parnas72. It doesn't 
compile / run as it is and the problem seems to be in the 
function below.

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"]]);
}


More specifically, icmp doesn't seem to be allowed as the 
predicate for sort:

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[][])


My question is, how do I begin to understand error messages like 
the above? I looked at the signature for sort and icmp and don't 
get what the problem is.

Thanks.
Apr 11 2017
next sibling parent bluecat <1bluecat7 gmail.com> writes:
On Tuesday, 11 April 2017 at 14:51:44 UTC, Anonymous wrote:
 I was watching a dconf presentation from last year and wanted 
 to try this out: https://github.com/luismarques/parnas72. It 
 doesn't compile / run as it is and the problem seems to be in 
 the function below.

 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"]]);
 }


 More specifically, icmp doesn't seem to be allowed as the 
 predicate for sort:

 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[][])


 My question is, how do I begin to understand error messages 
 like the above? I looked at the signature for sort and icmp and 
 don't get what the problem is.

 Thanks.
The following code gives you the output you want: //code starts import std.algorithm: joiner, map, sort, cmp; import std.array: array; auto alpha(T)(T[][] range) { return range .map!(line => line.joiner(" ")) .array .sort!((a,b) => cmp(a, b) < 0); } void main() { import std.stdio; auto a = alpha!string([["foo", "bar"], ["baz"]]); a.writeln; } //code ends I really don't know why your program gave you any errors, but I can tell you my thinking process. Immediately the first thing I noticed was that your function parameters didn't look explicit at all, so I tried to make them more explicit here. Next, i noticed the use of icmp was the problem in the error message. I thought maybe that function was outdated or something, so i decided to use the comparison function in std.algorithm. Third, I used selective importing in case the compiler got confused what functions to use. All and all, for me, I read the error messages from the bottom up. Also I usually use functions found in std.algorithm because they seem for stable for me.
Apr 11 2017
prev sibling next sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, April 11, 2017 14:51:44 Anonymous via Digitalmars-d-learn wrote:
 I was watching a dconf presentation from last year and wanted to
 try this out: https://github.com/luismarques/parnas72. It doesn't
 compile / run as it is and the problem seems to be in the
 function below.

 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"]]);
 }


 More specifically, icmp doesn't seem to be allowed as the
 predicate for sort:

 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[][])


 My question is, how do I begin to understand error messages like
 the above? I looked at the signature for sort and icmp and don't
 get what the problem is.
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. https://issues.dlang.org/ - Jonathan M Davis
Apr 11 2017
prev sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, April 11, 2017 8:41:21 AM CEST Jonathan M Davis via Digitalmars-
d-learn wrote:
 So, this should be reported as a bug in icmp.

 https://issues.dlang.org/
https://issues.dlang.org/show_bug.cgi?id=17372 https://github.com/dlang/phobos/pull/5361 - Jonathan M Davis
May 05 2017