www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5889] New: Struct construction should be rvalue

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

           Summary: Struct construction should be rvalue
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: k.hara.pg gmail.com



This issue is combined issue 5178 and 5769, etc.

Following code should be passed.
----
struct S1{  }
struct S2{ int n; }
struct S3{ this(int n){} }

struct X1(T){  }
struct X2(T){ int n; }
struct X3(T){ this(int n){} }

bool isRvalue(T)(auto ref T t){ return !__traits(isRef, t); }
template Fn(string code){ mixin(code); }

void main()
{
    // 1.
    assert(isRvalue(S1(  )));       // now false, expect true
    assert(isRvalue(S2(12)));       // now false, expect true
    assert(isRvalue(S3(13)));       // now false, expect true

    // 2.
    static assert(!__traits(compiles, Fn!`ref S1 get1(){return S1(  );}`));    
        // now OK, expect NG
    static assert(!__traits(compiles, Fn!`ref S2 get2(){return S2(22);}`));    
        // now OK, expect NG
    static assert(!__traits(compiles, Fn!`ref S3 get3(){return S3(23);}`));    
        // now OK, expect NG

    static assert(!__traits(compiles, Fn!`ref X1!int get(){ return X1!int(  );
}`));    // now OK, expect NG
    static assert(!__traits(compiles, Fn!`ref X2!int get(){ return X2!int(32);
}`));    // now OK, expect NG
    static assert(!__traits(compiles, Fn!`ref X3!int get(){ return X3!int(33);
}`));    // now OK, expect NG

    // 3.
    void getref(T)(ref T t){}
    static assert(!__traits(compiles, getref(S1(  ))));         // now OK,
expect NG
    static assert(!__traits(compiles, getref(S2(42))));         // now OK,
expect NG
    static assert(!__traits(compiles, getref(S3(43))));         // now OK,
expect NG

    static assert(!__traits(compiles, getref(X1!int(  ))));     // now OK,
expect NG
    static assert(!__traits(compiles, getref(X2!int(10))));     // now OK,
expect NG
    static assert(!__traits(compiles, getref(X3!int(10))));     // now OK,
expect NG

    void getrefS1(ref S1 t){}
    void getrefS2(ref S2 t){}
    void getrefS3(ref S3 t){}
    static assert(!__traits(compiles, getrefS1(S1(  ))));       // now OK,
expect NG
    static assert(!__traits(compiles, getrefS2(S2(10))));       // now OK,
expect NG
    static assert(!__traits(compiles, getrefS3(S3(10))));       // now OK,
expect NG

    void getrefX1(ref X1!int t){}
    void getrefX2(ref X2!int t){}
    void getrefX3(ref X3!int t){}
    static assert(!__traits(compiles, getrefX1(X1!int(  ))));   // now OK,
expect NG
    static assert(!__traits(compiles, getrefX2(X2!int(10))));   // now OK,
expect NG
    static assert(!__traits(compiles, getrefX3(X3!int(10))));   // now OK,
expect NG
}
----

1. struct literal/construction should make rvalue.
2. returning struct literal/construction ref is invalid.
3. implicit conversion struct literal/construction to lvalue is invalid.
   (At least on ref parameter.)

My patch is here:
https://github.com/9rnsr/dmd/tree/rvalue-struct-literal

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 26 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889




Send pull request:
https://github.com/D-Programming-Language/dmd/pull/41

After pull requested, I thought this request may be too early to fix. This fix
may break some existing codes.

Example:
----
struct S {
  int val;
  bool opEquals(ref const(S) rhs) const {
    return val == rhs.val;
  }
}
void main() {
  S s = S(10);
  assert(s == S(10));  // if S(10) changes from lvalue to rvalue,
                       // this line makes error.
}
----

Should fix struct opEquals signature problem before fixing this issue.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 29 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889


kennytm gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kennytm gmail.com




 Send pull request:
 https://github.com/D-Programming-Language/dmd/pull/41
 
 After pull requested, I thought this request may be too early to fix. This fix
 may break some existing codes.
 
 Example:
 ----
 struct S {
   int val;
   bool opEquals(ref const(S) rhs) const {
     return val == rhs.val;
   }
 }
 void main() {
   S s = S(10);
   assert(s == S(10));  // if S(10) changes from lvalue to rvalue,
                        // this line makes error.
 }
 ----
 
 Should fix struct opEquals signature problem before fixing this issue.
So, it depends on bug 3659? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 30 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Depends on|                            |3659




 So, it depends on bug 3659?
Yes. I change 'Depends on' status. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 30 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889




bug4843 (and its duplication bug6201) is part of this issue.

FuncDeclaration::overloadResolve use TypeStruct::defaultInit, but it makes
lvalue.
So ref and non-ref overloads make ambiguous.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 24 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au



I'm not convinced about this bug. Why do you think that struct literals should
become rvalues (rather than non-modifiable lvalues)? It's a breaking change.

You've mentioned opEquals, but it's much broader than that. Fairly obviously it
also affects opCmp, but in fact, any function which takes a struct by const ref
will currently accept a struct literal.

Also, what about member functions? 'this' is passed by reference, yet you can
use CTFE on member functions of struct literals.

It's clearly a bug to allow a struct literal to be passed by non-const
reference, but as to making them rvalues, I'm not sure. This needs confirmation
from Walter.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 29 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889





'Literal is rvalue' is very important semantics for strict typed languages.
A literal is not referenced from any other places, so it is _unique_ and
_thread_local_. This is necessary for good resource management.
(e.g. Unique!T, Scoped!T, etc.)

But now, In D we cannot create rvalue struct object 'in place'.
(Note: Returned rvalue from function might be moved, so it is not 'in place'.)
It looks to me like a serious flaw.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 29 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889






 'Literal is rvalue' is very important semantics for strict typed languages.
 A literal is not referenced from any other places, so it is _unique_ and
 _thread_local_. This is necessary for good resource management.
 (e.g. Unique!T, Scoped!T, etc.)
But that's true of immutable as well. In reality, any struct literal which exists at run time is stored in the executable as if it were immutable (just as for a string literal).
 But now, In D we cannot create rvalue struct object 'in place'.
 (Note: Returned rvalue from function might be moved, so it is not 'in place'.)
 It looks to me like a serious flaw.
-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 29 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889





 But that's true of immutable as well. In reality, any struct literal which
 exists at run time is stored in the executable as if it were immutable (just as
 for a string literal).
??? I'm not speaking about object const-ness. Yes, immutable struct literal will be stored in data-segment, but that is binary level issue, and definitely different from language semantics level. Give you an example. https://github.com/9rnsr/scrap/blob/master/typecons/unique.d This is my prototype code to improve std.typecons.Unique. In it, by receiving only rvalues for its initializing and assignment, Unique type can keep the uniqueness of stored object. Similar improvements will be able on Scoped!T. By receiving only rvalue for initializing, we can separate the struct object that allocated on stack and others not. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 30 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com



00:43:08 PDT ---
I appreciate what you're trying to do, but I tend to agree with Don. I'm not
sure this is a correct thing to do.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 30 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889




---
OK. Here's another advantage of that.

----
struct S1{ int n; }
struct S2{ this(int n){} }
struct S3{ int n; void opAssign(S3 rhs){} }

void main()
{
    S1(0) = S1(0);  // Line 7
    S2(0) = S2(0);  // Line 8
    S3(0) = S3(0);  // Line 9 
}
----

Line 7 and 8 are no effect codes. We can reject them by making struct literal
as rvalue.
Line 9 is an exception. S3.opAssign can have effect, so it is legal.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 30 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889




---
Another example.
In C++0x (gcc-4.5.1), following code prints "1".
It seems to me that the S() makes rvalue instead of lvalue.
----
#include <stdio.h>

struct S {};

int f(S&&){ return 1; }
int f(const S&){ return 2; }

int main()
{
  printf("%d\n", f(S()));
  return 0;
}
----

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 30 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei metalanguage.com



---
*** Issue 7100 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 12 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889




*** Issue 5178 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 30 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889




Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/907c94de34b9d99438e7e244c556903224a0c094


Issue 5889 - Struct literal/construction should be rvalue

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 20 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889


Walter Bright <bugzilla digitalmars.com> changed:

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


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 21 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dsimcha yahoo.com



---
*** Issue 4843 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 22 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5889




---
*** Issue 5769 has been marked as a duplicate of this issue. ***

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