Thread overview
Type Inference Bug?
Nov 20, 2014
Meta
Nov 21, 2014
Daniel Murphy
Nov 21, 2014
Meta
Nov 21, 2014
Daniel Murphy
Nov 21, 2014
Meta
Nov 21, 2014
Daniel Murphy
Nov 21, 2014
Meta
Nov 21, 2014
Daniel Murphy
Nov 22, 2014
Meta
Nov 22, 2014
Daniel Murphy
November 20, 2014
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).
November 21, 2014
"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);
   }
} 

November 21, 2014
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?
November 21, 2014
"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)) 

November 21, 2014
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))).
November 21, 2014
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.
November 21, 2014
"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.
November 21, 2014
"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.

November 22, 2014
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.
November 22, 2014
"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.