www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9489] New: writeln of scoped class instance

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

           Summary: writeln of scoped class instance
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc


--- Comment #0 from bearophile_hugs eml.cc 2013-02-09 04:52:58 PST ---
import std.stdio: writeln;
import std.conv: text;
import std.typecons: scoped;
class Foo {
    int x;
    this(int x_) { this.x = x_; }
    override string toString() { return text(x); }
}
void main() {
    auto f = scoped!Foo(100);
    writeln(f.x); // OK
    writeln(f); // Error
    typeof(scoped!Foo(1))[10] foos;
    foreach (i, ref fi; foos)
        fi.x = i * 10;
    writeln(foos); // Error
}



dmd 2.062beta gives:


...\dmd2\src\phobos\std\stdio.d(709): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\format.d(414): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\format.d(437): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\format.d(451): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\format.d(463): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\format.d(475): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\format.d(489): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\format.d(498): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\stdio.d(714): Error: template instance
std.format.formattedWrite!(LockingTextWriter, char, Scoped!(Foo)) error
instantiating
...\dmd2\src\phobos\std\stdio.d(1620):        instantiated from here:
write!(Scoped!(Foo),char)
temp.d(12):        instantiated from here: writeln!(Scoped!(Foo))
...\dmd2\src\phobos\std\stdio.d(714): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\stdio.d(1620): Error: template instance
std.stdio.File.write!(Scoped!(Foo),char) error instantiating
temp.d(12):        instantiated from here: writeln!(Scoped!(Foo))
...\dmd2\src\phobos\std\stdio.d(1620): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
temp.d(12): Error: template instance std.stdio.writeln!(Scoped!(Foo)) error
instantiating
temp.d(12): Error: struct std.typecons.scoped!(Foo,
int).scoped.Scoped!(Foo).Scoped is not copyable because it is annotated with
 disable
...\dmd2\src\phobos\std\format.d(1821): Error: static assert 
(isInputRange!(Scoped!(Foo)[])) is false
...\dmd2\src\phobos\std\format.d(1789):        instantiated from here:
formatValue!(LockingTextWriter, Scoped!(Foo)[], char)
...\dmd2\src\phobos\std\format.d(2953):        instantiated from here:
formatValue!(LockingTextWriter, Scoped!(Foo)[10u], char)
...\dmd2\src\phobos\std\format.d(416):        instantiated from here:
formatGeneric!(LockingTextWriter, Scoped!(Foo)[10u], char)
...\dmd2\src\phobos\std\stdio.d(735):        ... (1 instantiations, -v to show)
...
...\dmd2\src\phobos\std\stdio.d(1620):        instantiated from here:
write!(Scoped!(Foo)[10u],char)
temp.d(16):        instantiated from here: writeln!(Scoped!(Foo)[10u])

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


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com
            Summary|writeln of scoped class     |writeln of struct with
                   |instance                    |disabled copy ctor


--- Comment #1 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-02-09
05:44:27 PST ---
Unrelated to scoped classes, the root cause is that writeln() takes its
arguments by value:

import std.stdio;

struct S
{
     disable this(this);
}

void main()
{
    S s;
    writeln(s);  // error
}

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



--- Comment #2 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-02-18
20:10:35 PST ---
As a workaround you can use this:

import std.stdio;
import std.string;

struct Wrap(T)
{
    T* t;
    auto ref opDispatch(string s, T...)(T args)
    {
        mixin(format("return t.%s(args);", s));
    }
}

auto wrap(T)(T* t)
{
    return Wrap!T(t);
}

struct S
{
     disable this(this);
    int x;
    float y;

    string toString()
    {
        return format("S { x: %s, y: %s }", x, y);
    }
}

void main()
{
    S s = S(1, 2.0);
    writeln(wrap(&s));
}

(std.typecons.Proxy doesn't seem to help here, it won't work with pointers)

Generally speaking this is a gigantic problem to fix. Pretty much everything in
Phobos expects structs to be copyable. Phobos could try to take arguments by
ref (or rather auto ref for compatibility), but this would have to be applied
to all functions.

I think the safest thing we can do is ask the user to use this sort of wrapper
type.

Maybe writeln/format could be the exception to the rule and take all arguments
by auto ref and then internally use wrappers for  disable structs to pass them
to other internal formatting functions. This would make it convenient to print
 disable structs since it's common to print things..

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


hsteoh quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh quickfur.ath.cx


--- Comment #3 from hsteoh quickfur.ath.cx 2013-03-15 10:58:55 PDT ---
This issue is not just limited to printing. Structs that have  disabled
this(this) are currently highly-crippled, because almost everything in Phobos
assumes that structs can be passed by value. A struct range with  disabled
this(this) is unusable with any range function unless you do something really
ugly like (&range).cycle(), etc., which is a kind of hack (taking advantage of
D's automatic dereference when a pointer is used with the . operator).

Auto ref would solve a lot of these problems.

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