Thread overview
Bug in tuple comparison?
Mar 24, 2011
Magnus Lie Hetland
Mar 24, 2011
bearophile
Mar 24, 2011
Magnus Lie Hetland
Mar 24, 2011
Jonathan M Davis
Mar 24, 2011
bearophile
Mar 25, 2011
bearophile
March 24, 2011
I guess this is getting old by now ... but I've come across yet another bug :->

This one is a bit obscure, and deals with comparing tuples in contracts. It seems that some type information about the result is lost when entering an out-block, or something. At least, DMD (2.052, OS X) is unable to infer types properly, and is therefore unable to compare tuples in some cases. Sample program follows. (Similar behavior occurs for other comparison operators as well.)

import std.typecons;
T[] func(T)(T[] arg)
out(result) {
   auto a = result[0];
   auto b = arg[0];
   auto c = result[0];
   // assert(c < a); // Doesn't work
   // assert(a < c); // Doesn't work
   // assert(c < b); // Doesn't work
   assert(b < c); // Works
}
body {
   return arg;
}
void main() {
   alias Tuple!(real, uint) Entry;
   func(new Entry[100]);
}

The error (when uncommenting one of the lines that don't work, e.g., line 7) is:

tuplecmpbug.d(7): Error: template std.typecons.Tuple!(real,uint).Tuple.opCmp(R) if (isTuple!(R)) does not match any function template declaration
tuplecmpbug.d(7): Error: template std.typecons.Tuple!(real,uint).Tuple.opCmp(R) if (isTuple!(R)) cannot deduce template function from argument types !()(const(Tuple!(real,uint)))

I take it this is a bug (or am I just missing something)? Is it a known bug? (Sorry if it's in the tracker; it can be hard to find equivalents there...)

-- 
Magnus Lie Hetland
http://hetland.org

March 24, 2011
Magnus Lie Hetland:

> I guess this is getting old by now ... but I've come across yet another bug :->

The out(result) turns the result into a const, this causes some troubles you see in this simpler program:


import std.typecons;
void main() {
    alias Tuple!(int) T;
    const T t = T();
    bool b = t == t;
}


Further reduction:

struct Tuple(T) {
    bool opEquals(R)(R rhs) {
        return false;
    }
}
void main() {
    const Tuple!int t;
    bool b = t == t;
}

Bye,
bearophile
March 24, 2011
On 2011-03-24 18:25:30 +0100, bearophile said:

> Magnus Lie Hetland:
> 
>> I guess this is getting old by now ... but I've come across yet another bug :->
> 
> The out(result) turns the result into a const,

Riiight! Yes, I've seen that it's const, and (naughtily) cast away the constness (without modifying anything) in some cases. It didn't occur to me that that was the problem here. :) (In my original program, I didn't notice that I had gotten one of the values from outside the out-block, while the other was from the result. I guess I was "primed" to think that that wasn't the problem ;)

So the issue, then, I take it, is that you *can* compare a non-const tuple to a const-tuple, but you *cannot* compare a const-tuple to a non-const tuple (as per casting rules)?

Makes sense. Would have been nice with a slightly more obvious error message, but I guess that's always a problem with templates in any form ;)

Aanyway -- glad the bug was just in my code/brain :D Thanks for the help,

- M

-- 
Magnus Lie Hetland
http://hetland.org

March 24, 2011
> On 2011-03-24 18:25:30 +0100, bearophile said:
> > Magnus Lie Hetland:
> >> I guess this is getting old by now ... but I've come across yet another bug :->
> > 
> > The out(result) turns the result into a const,
> 
> Riiight! Yes, I've seen that it's const, and (naughtily) cast away the constness (without modifying anything) in some cases. It didn't occur to me that that was the problem here. :) (In my original program, I didn't notice that I had gotten one of the values from outside the out-block, while the other was from the result. I guess I was "primed" to think that that wasn't the problem ;)
> 
> So the issue, then, I take it, is that you *can* compare a non-const tuple to a const-tuple, but you *cannot* compare a const-tuple to a non-const tuple (as per casting rules)?
> 
> Makes sense. Would have been nice with a slightly more obvious error message, but I guess that's always a problem with templates in any form ;)
> 
> Aanyway -- glad the bug was just in my code/brain :D Thanks for the help,

If you const-ness affects comparison, that _is_ a bug. Currently, a struct's opEquals should take a "const ref Type rhs" and Tuple isn't doing that. So, that's a bug in Tuple. There are a number of const-correctness bugs in druntime and Phobos though - the mother of them all being http://d.puremagic.com/issues/show_bug.cgi?id=1824

Regardless, this _is_ a bug.

- Jonathan M Davis
March 24, 2011
Jonathan M Davis:

> Regardless, this _is_ a bug.

I agree. The second reduction I've written seems fit for Bugzila.

Bye,
bearophile
March 25, 2011
> I agree. The second reduction I've written seems fit for Bugzila.

http://d.puremagic.com/issues/show_bug.cgi?id=5783