www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Type Inference Bug?

reply "Meta" <jared771 gmail.com> writes:
shared const int i;

static if (is(typeof(i) T == shared U, U))
{
     //Prints "shared(const(int))"
     pragma(msg, U);
}

This seems like subtly wrong behaviour to me. If T == shared U, 
for some U, then shouldn't U be unshared? If T is 
shared(const(int)), and T is the same as the type U with the 
'shared' qualifier applied to it, then U should be of type 
const(int), not shared(const(int)).

I'm bringing this up partially because it seems wrong to me, and 
partially because we currently don't have a good why of "shaving" 
the outermost qualifier off a type, and this seemed the natural 
way to do it to me (I was surprised when it didn't work).
Nov 20 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Meta"  wrote in message news:wzczhiwokauvkkevtdxr forum.dlang.org...

 shared const int i;

 static if (is(typeof(i) T == shared U, U))
 {
      //Prints "shared(const(int))"
      pragma(msg, U);
 }

 This seems like subtly wrong behaviour to me. If T == shared U, for some 
 U, then shouldn't U be unshared? If T is shared(const(int)), and T is the 
 same as the type U with the 'shared' qualifier applied to it, then U 
 should be of type const(int), not shared(const(int)).

 I'm bringing this up partially because it seems wrong to me, and partially 
 because we currently don't have a good why of "shaving" the outermost 
 qualifier off a type, and this seemed the natural way to do it to me (I 
 was surprised when it didn't work).
It doesn't print anything for me. This code seems to have the desired effect: shared const int i; void main() { static if (is(typeof(i) : shared(U), U)) { //Prints "const(int)" pragma(msg, U); } }
Nov 20 2014
next sibling parent reply "Meta" <jared771 gmail.com> writes:
On Friday, 21 November 2014 at 07:40:31 UTC, Daniel Murphy wrote:
 It doesn't print anything for me.  This code seems to have the 
 desired effect:

 shared const int i;

 void main()
 {
    static if (is(typeof(i) : shared(U), U))
    {
         //Prints "const(int)"
         pragma(msg, U);
    }
 }
Hmm, do you know why is(typeof(i) == shared(U), U)) might fail? I wonder why : is required over ==... Doesn't the former check if T is a subtype of U, rather than check that they're the same type?
Nov 21 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Meta"  wrote in message news:tyfdmprlmreagrrnbuon forum.dlang.org...

 Hmm, do you know why is(typeof(i) == shared(U), U)) might fail? I wonder 
 why : is required over ==... Doesn't the former check if T is a subtype of 
 U, rather than check that they're the same type?
I have no idea, I tried == first, expecting it to work. And yes, it checks it's a subtype, but you could enforce exact type with something like if (typeof(i) == shared(U), U) && is(shared(U) == typeof(i))
Nov 21 2014
parent reply "Meta" <jared771 gmail.com> writes:
On Friday, 21 November 2014 at 15:29:05 UTC, Daniel Murphy wrote:
 but you could enforce exact type with something like
 if (typeof(i) == shared(U), U) && is(shared(U) == typeof(i))
I'm assuming you meant if (typeof(i): shared(U), U) && is(shared(U): typeof(i))).
Nov 21 2014
parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Meta"  wrote in message news:nwskxjncbwqndlkiebwb forum.dlang.org... 

 On Friday, 21 November 2014 at 15:29:05 UTC, Daniel Murphy wrote:
 but you could enforce exact type with something like
 if (typeof(i) == shared(U), U) && is(shared(U) == typeof(i))
I'm assuming you meant if (typeof(i): shared(U), U) && is(shared(U): typeof(i))).
Probably.
Nov 21 2014
prev sibling parent reply "Meta" <jared771 gmail.com> writes:
On Friday, 21 November 2014 at 07:40:31 UTC, Daniel Murphy wrote:
 It doesn't print anything for me.  This code seems to have the 
 desired effect:

 shared const int i;

 void main()
 {
    static if (is(typeof(i) : shared(U), U))
    {
         //Prints "const(int)"
         pragma(msg, U);
    }
 }
Now how about this one: alias Unshared(T: shared U, U) = U; pragma(msg, Unshared!(shared const int)); //Prints const(int) Does the `:` denote subtyping as well, or equality? I'm sure that in this case it's the latter, which makes me more strongly suspect that `is(T == shared U, U)` not working is a bug. Furthermore, I'm starting to get very confused: enum sameTypes(T, U) = is(T: U) && is(U: T); assert(sameTypes!(const int, immutable int)); //Ok, wtf? assert(sameTypes!(int, immutable int); //Ok, wtf? What in the world is going on here? Note that this is from Dpaste, so it's DMD 2.065, but I doubt there is that much difference between 2.065 and 2.066.
Nov 21 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Meta"  wrote in message news:szrhmjrinsymyihemduy forum.dlang.org...

 Now how about this one:

 alias Unshared(T: shared U, U) = U;
 pragma(msg, Unshared!(shared const int)); //Prints const(int)

 Does the `:` denote subtyping as well, or equality? I'm sure that
Neither. IIRC it's something close to type implicit conversion rules. alias A(T : long) = T; pragma(msg, A!int);
 in this case it's the latter, which makes me more strongly suspect that
 `is(T == shared U, U)` not working is a bug.
Probably. It looks like that matches only shared(U) and not const(shared(U)), so it could be intentional that it means exactly shared. I would guess it's an oversight.
 Furthermore, I'm starting to get very confused:

 enum sameTypes(T, U) = is(T: U) && is(U: T);

 assert(sameTypes!(const int, immutable int)); //Ok, wtf?
 assert(sameTypes!(int, immutable int); //Ok, wtf?
All of those types implicitly convert to each other.
Nov 21 2014
parent reply "Meta" <jared771 gmail.com> writes:
On Friday, 21 November 2014 at 19:19:20 UTC, Daniel Murphy wrote:
 Furthermore, I'm starting to get very confused:

 enum sameTypes(T, U) = is(T: U) && is(U: T);

 assert(sameTypes!(const int, immutable int)); //Ok, wtf?
 assert(sameTypes!(int, immutable int); //Ok, wtf?
All of those types implicitly convert to each other.
Yes, right, as they are POD value types. I'm not sure I like that, as it can't be guaranteed that T1 and T2 are the same type if is(T1: T2) && is(T2: T1) are true... I will submit a bug report regarding my original issue, anyway.
Nov 22 2014
parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Meta"  wrote in message news:wkhobsfnumjpyyrpdxkb forum.dlang.org...

 Yes, right, as they are POD value types. I'm not sure I like that, as it 
 can't be guaranteed that T1 and T2 are the same type if is(T1: T2) && 
 is(T2: T1) are true... I will submit a bug report regarding my original 
 issue, anyway.
I'd use is(Unqual!T1 == Unqual!T2) to check for type equality ignoring qualifiers.
Nov 22 2014