www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9630] New: DMD git: can't access array field properties from static method

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630

           Summary: DMD git: can't access array field properties from
                    static method
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: rejects-valid
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: thecybershadow gmail.com


--- Comment #0 from Vladimir Panteleev <thecybershadow gmail.com> 2013-03-02
06:47:21 EET ---
struct S
{
    int i[1];

    static void foo()
    {
        assert(0 < i[0].max);
    }
}

I assume this code is valid, as the problem appears with e.g. arrays of ints,
but not ints.

Works in 2.062, breaks in DMD git master (d0e1476c1).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com


--- Comment #1 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-03-01
20:50:55 PST ---
AFAIK it was done on purpose by this:
https://github.com/D-Programming-Language/dmd/pull/1687

The change needs to be more visible though, even for those using git-head.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #2 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-03-01
20:52:02 PST ---
Workaround:

assert(0 < typeof(i[0]).max);

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #3 from Vladimir Panteleev <thecybershadow gmail.com> 2013-03-02
06:53:14 EET ---
You mean it was accidentally broken by that pull? It certainly does not look
intentional.

Another workaround is: typeof(this).init.i[0].max

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #4 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-03-01
20:54:14 PST ---
(In reply to comment #3)
 You mean it was accidentally broken by that pull? It certainly does not look
 intentional.
 
 Another workaround is: typeof(this).init.i[0].max

Kenji mentioned it was going to break code (I don't know if it applies for this case though). I suggested keeping a list of pulls like that in a file so we can deliver a better change log for 2.063. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #5 from Vladimir Panteleev <thecybershadow gmail.com> 2013-03-02
06:57:24 EET ---
Well, the observable effect is inconsistent and makes no sense:
someInt.max works, but someArrayOfInt[0].max doesn't.
The tests included with the pull do not test attributes of array elements, only
of individual fields and concatenation with arrays, so I'm quite sure it's a
bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #6 from Kenji Hara <k.hara.pg gmail.com> 2013-03-01 21:49:19 PST ---
(In reply to comment #5)
 Well, the observable effect is inconsistent and makes no sense:
 someInt.max works, but someArrayOfInt[0].max doesn't.
 The tests included with the pull do not test attributes of array elements, only
 of individual fields and concatenation with arrays, so I'm quite sure it's a
 bug.

That is mostly intended. The introduced rule by pull 1687 is: 1. In expr.aStaticMember exists, if expr is just a variable that needs this, it is specially treated as typeof(expr).someStaticMember. This is useful for Type.field.init, Type.field.offsetof, etc. 2. In expr.aFieldVariable, if expr is just a variable that needs this, the "need this" error for aFieldVariable access is specially delayed. This is more specialized 'exception' than #1. The chain of field access like following would be accepted by this. Type.field1.field2.field3.staticFieldOrFunction #2 is introduced by dawgfoto's comment. https://github.com/D-Programming-Language/dmd/pull/1687#issuecomment-14090801 In original code, index access `i[0]` does not fit to above rule. So it will raise "need this" error normally. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #7 from Vladimir Panteleev <thecybershadow gmail.com> 2013-03-02
07:54:14 EET ---
 Now, the unreal variable access doesn't make errors if it is not actually used.

But i[0] is not used as well. I guess you mean to say that the behavior is "intended", as in it has been deemed an acceptable flaw? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #8 from Kenji Hara <k.hara.pg gmail.com> 2013-03-01 22:03:52 PST ---
If `i[0].max` should be accepted, how about this?

struct S
{
    int[] arr;

    static void foo()
    {
        auto x = arr.map!(x => x*2).filter!(x > 4).array[0].max;
    }
}

The part expression `arr.map!(x => x*2).filter!(x > 4).array[0]` is never
evaluated, because it is just used for calculate its type. It looks much weird
to me. I think such *implicit typeof* feature is not good. Instead:

        auto x = typeof(arr.map!(x => x*2).filter!(x > 4).array[0]).max;

is much better. I think language should enforce the latter.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #9 from Kenji Hara <k.hara.pg gmail.com> 2013-03-01 22:07:26 PST ---
(In reply to comment #7)
 Now, the unreal variable access doesn't make errors if it is not actually used.

But i[0] is not used as well. I guess you mean to say that the behavior is "intended", as in it has been deemed an acceptable flaw?

Because i[0] is _not_ a variable. `i[0]` should be evaluated in runtime but it is impossible, so compiler reports "need this" error. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #10 from Vladimir Panteleev <thecybershadow gmail.com> 2013-03-02
08:09:16 EET ---
 auto x = typeof(arr.map!(x => x*2).filter!(x > 4).array[0]).max;

Well, I don't know about how this fits with backwards compatibility and such, but the above line looks wrong to me as well, since it's passing a non-existent variable (arr) to a function (map). This is as much "runtime evaluated" as taking its index. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #11 from Kenji Hara <k.hara.pg gmail.com> 2013-03-01 22:15:23 PST
---
(In reply to comment #6)
 2. In expr.aFieldVariable, if expr is just a variable that needs this, the
 "need this" error for aFieldVariable access is specially delayed.
 
   This is more specialized 'exception' than #1.
   The chain of field access like following would be accepted by this.
 
   Type.field1.field2.field3.staticFieldOrFunction

Why it is explicitly allowed? The reason of rule #2 is "a variable access can be regarded as a symbol access". For example, symbol access is already allowed in template argument. template X(alias symbol) {} struct S { T field1; struct T { int field2; } } void main() { alias x = X!(S.field1.field2); // access symbol S.T.field2 auto y = S.field1.field2.offsetof; // access symbol S.T.field2 } This is consistent behavior. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #12 from Vladimir Panteleev <thecybershadow gmail.com> 2013-03-02
08:17:28 EET ---
OK, I'm clearly in over my head so I'll take your word for it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #13 from Kenji Hara <k.hara.pg gmail.com> 2013-03-01 22:27:27 PST
---
(In reply to comment #10)
 auto x = typeof(arr.map!(x => x*2).filter!(x > 4).array[0]).max;

Well, I don't know about how this fits with backwards compatibility and such, but the above line looks wrong to me as well, since it's passing a non-existent variable (arr) to a function (map). This is as much "runtime evaluated" as taking its index.

Using non-static variable directly under the typeof should be allowed. If you use 'typeof', you means "I want to just get the type of specified expression, and does not consider whether the expression can be evaluate in runtime." In this point, D accepts it explicitly. Moreover, that is necessary for the use at out of function scope. struct S { int field1; typeof(field1) field2; // field1 access has no "valid this", but allowed static void foo() { typeof(field1) x; // field1 access has no "valid this", but allowed } } This is also consistent behavior. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID


--- Comment #14 from Kenji Hara <k.hara.pg gmail.com> 2013-03-01 22:29:36 PST
---
(In reply to comment #12)
 OK, I'm clearly in over my head so I'll take your word for it.

Thanks. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 01 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc


--- Comment #15 from bearophile_hugs eml.cc 2013-03-02 05:31:13 PST ---
(In reply to comment #2)

 Workaround:
 
 assert(0 < typeof(i[0]).max);

This is acceptable. This program: struct Foo { int i[1]; static void bar() { assert(0 < i[0].max); } } Currently gives: temp.d(4): Error: need 'this' for i type int[1u]. But is it possible for the error message to suggest your solution to fix the error? temp.d(4): Error: need 'this' for i type int[1]. Use typeof(i[0]).max instead -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #16 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-03-02
07:24:23 PST ---
(In reply to comment #15)
 Currently gives:
 
 temp.d(4): Error: need 'this' for i type int[1u].

This is already a bad message. 'i' should be quoted and the wording should be improved:
 temp.d(4): Error: need 'this' for 'i' of type int[1u]. 

Feel free to open an enhancement for these. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 02 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9630



--- Comment #17 from bearophile_hugs eml.cc 2013-03-02 12:08:43 PST ---
(In reply to comment #16)

 Feel free to open an enhancement for these.

OK, filed as Issue 9635 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 02 2013