Jump to page: 1 2
Thread overview
[Issue 5889] New: Struct construction should be rvalue
Apr 26, 2011
Kenji Hara
[Issue 5889] Struct literal/construction should be rvalue
Apr 30, 2011
Kenji Hara
Apr 30, 2011
kennytm@gmail.com
Apr 30, 2011
Kenji Hara
Jun 24, 2011
Kenji Hara
Jun 30, 2011
Don
Jun 30, 2011
Kenji Hara
Jun 30, 2011
Don
Jun 30, 2011
Kenji Hara
Jun 30, 2011
Walter Bright
Jun 30, 2011
Kenji Hara
Jun 30, 2011
Kenji Hara
Dec 13, 2011
Kenji Hara
[Issue 5889] Struct literal/construction should be rvalue (it binds to ref parameters)
Jan 31, 2012
yebblies
Feb 21, 2012
Walter Bright
Apr 22, 2012
Kenji Hara
Apr 23, 2012
Kenji Hara
April 26, 2011
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


--- Comment #0 from Kenji Hara <k.hara.pg@gmail.com> 2011-04-26 00:31:19 PDT ---
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: -------
April 30, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5889



--- Comment #1 from Kenji Hara <k.hara.pg@gmail.com> 2011-04-29 21:27:14 PDT ---
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: -------
April 30, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5889


kennytm@gmail.com changed:

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


--- Comment #2 from kennytm@gmail.com 2011-04-30 03:44:08 PDT ---
(In reply to comment #1)
> 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: -------
April 30, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5889


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

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


--- Comment #3 from Kenji Hara <k.hara.pg@gmail.com> 2011-04-30 03:53:31 PDT ---
(In reply to comment #2)
> 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: -------
June 24, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5889



--- Comment #4 from Kenji Hara <k.hara.pg@gmail.com> 2011-06-24 04:52:32 PDT ---
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: -------
June 30, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5889


Don <clugdbug@yahoo.com.au> changed:

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


--- Comment #5 from Don <clugdbug@yahoo.com.au> 2011-06-29 17:47:15 PDT ---
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: -------
June 30, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5889



--- Comment #6 from Kenji Hara <k.hara.pg@gmail.com> 2011-06-29 18:11:03 PDT ---
(In reply to comment #5)
'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: -------
June 30, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5889



--- Comment #7 from Don <clugdbug@yahoo.com.au> 2011-06-29 23:28:22 PDT ---
(In reply to comment #6)
> (In reply to comment #5)
> '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: -------
June 30, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5889



--- Comment #8 from Kenji Hara <k.hara.pg@gmail.com> 2011-06-30 00:14:51 PDT ---
(In reply to comment #7)
> 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: -------
June 30, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5889


Walter Bright <bugzilla@digitalmars.com> changed:

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


--- Comment #9 from Walter Bright <bugzilla@digitalmars.com> 2011-06-30 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: -------
« First   ‹ Prev
1 2