Thread overview
[Issue 8657] New: TypeInfo generated for const/immutable static arrays not transitive
Sep 14, 2012
Rainer Schuetze
Sep 16, 2012
Kenji Hara
Sep 16, 2012
Rainer Schuetze
September 14, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8657

           Summary: TypeInfo generated for const/immutable static arrays
                    not transitive
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: r.sagitario@gmx.de


--- Comment #0 from Rainer Schuetze <r.sagitario@gmx.de> 2012-09-14 01:29:37 PDT ---
This test program

import std.stdio;

void test(T)()
{
    T p;
    writeln("==============");
    writeln("p: ", typeid(p));
    TypeInfo ti = typeid(p);
    TypeInfo_Const cti = cast(TypeInfo_Const)ti;
    writeln("p[0] : ", typeid(p[0]));
    writeln("ti.next : ", cast(TypeInfo)ti.next); // cannot write
const(TypeInfo)
    writeln("cti.base : ", cti.next);
}

void testMod(T)()
{
    test!(const(T))();
    test!(immutable(T))();
    test!(shared(T))();
}

void main()
{
    testMod!(int*)();
    testMod!(int[])();
    testMod!(int[2])();
//    testMod!(int[2][3])();
}

outputs:
==============
p: const(const(int)*)
p[0] : const(int)
ti.next : const(int)
cti.base : const(int)*
==============
p: immutable(immutable(int)*)
p[0] : immutable(int)
ti.next : immutable(int)
cti.base : immutable(int)*
==============
p: shared(shared(int)*)
p[0] : shared(int)
ti.next : shared(int)
cti.base : shared(int)*
==============
p: const(const(int)[])
p[0] : const(int)
ti.next : const(int)
cti.base : const(int)[]
==============
p: immutable(immutable(int)[])
p[0] : immutable(int)
ti.next : immutable(int)
cti.base : immutable(int)[]
==============
p: shared(shared(int)[])
p[0] : shared(int)
ti.next : shared(int)
cti.base : shared(int)[]
==============
p: const(int[2])
p[0] : const(int)
ti.next : int
cti.base : int[2]
==============
p: immutable(int[2])
p[0] : immutable(int)
ti.next : int
cti.base : int[2]
==============
p: shared(shared(int)[2])
p[0] : shared(int)
ti.next : shared(int)
cti.base : shared(int)[2]

It shows that the next and base properties of the TypeInfo generated for
const(int[2]) and immutable(int[2]) lose the qualifier. This does not happen
for "shared".

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 16, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8657



--- Comment #1 from Kenji Hara <k.hara.pg@gmail.com> 2012-09-16 04:47:16 PDT ---
(In reply to comment #0)
[snip]
> It shows that the next and base properties of the TypeInfo generated for
> const(int[2]) and immutable(int[2]) lose the qualifier. This does not happen
> for "shared".

I think this is expected behavior, because const(int[2]) is value type.

TypeInfo_Const.next specifies the TypeInfo object of the type that removed head
const qualifier from original type.
And, Removing const from const(int[2]) is int[2], not const(int)[2].
It's just same as std.traits.Unqual.

  pragma(msg, Unqual!(const(int[2])));  // prints const(int)[]
  pragma(msg, Unqual!(const(int[2])));  // prints int[2]

Additionally, const(int)[2] is same as const(int[2]). There is just a
syntactically difference.

  alias const(int)[2] T1;
  alias const(int[2]) T2;
  static assert(is(T1 == T2));  // they are same
  pragma(msg, T1);   // prints const(int[2])
  pragma(msg, T2);   // prints const(int[2])

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 16, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8657



--- Comment #2 from Rainer Schuetze <r.sagitario@gmx.de> 2012-09-16 10:23:53 PDT ---
(In reply to comment #1)
> (In reply to comment #0)
> [snip]
> TypeInfo_Const.next specifies the TypeInfo object of the type that removed head
> const qualifier from original type.

Please note the difference between base and next (as used in object_.d, see also issue 8656 for naming confusion). What you describe is "TypeInfo_Const.base", though called "next" in object.di. As can be seen from the other types, TypeInfo.next does the indirection and yields the type of the element pointed to or in the array.

> And, Removing const from const(int[2]) is int[2], not const(int)[2].
> It's just same as std.traits.Unqual.
> 
>   pragma(msg, Unqual!(const(int[2])));  // prints const(int)[]
>   pragma(msg, Unqual!(const(int[2])));  // prints int[2]

I fail to spot the difference between the two statement ;-) I guess you meant to remove the 2 in the first line.

> 
> Additionally, const(int)[2] is same as const(int[2]). There is just a
> syntactically difference.

That could also support my point of view: I'd very much expect
(cast(TypeInfo)typeid(const(int)[2])).next to be typeid(const(int)). Maybe the
runtime type information of a static array should be typed that way to start
with.

Even if I cannot convince you: What do you think about the transitivity of the shared modifier in the example. Is it wrong then?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------