www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12194] New: Constructor prevents static opCall regression?

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

           Summary: Constructor prevents static opCall regression?
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: Jesse.K.Phillips+D gmail.com



11:02:49 PST ---
In 2.064 the following code worked as expected, with 2.065rc1 this fails to
compile with a hidden static opCall message. Structs can't have a default
constructor; is this approach deprecated in favor of the factory method?

I'd like to note that by removing the static opCall, the compilation succeeds
but runtime will fail; this of course means tracking down the places which need
fixed is not helped by the compiler.

void main() {
    assert(Struct() == Struct(2));
}

struct Struct {
    int a;
    this(int a) {
        this.a = a;
    }

    static Struct opCall() {
        return Struct(2);
    }
}

--------
test.d(10): Error: struct test.Struct static opCall is hidden by constructors
and can never be called
test.d(10):        Please use a factory method instead, or replace all
constructors with static opCall.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 18 2014
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12194


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

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



12:36:05 PST ---
I knew this was going to be a problem as soon I saw the pull implementing the
change. But some pople insist on destroying any means of defining a default
ctor even though everybody else demands it.

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




12:36:24 PST ---

 I knew this was going to be a problem as soon I saw the pull implementing the
 change. But some pople insist on destroying any means of defining a default
 ctor even though everybody else demands it.
s/pople/people :) -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 18 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12194


Dmitry Olshansky <dmitry.olsh gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dmitry.olsh gmail.com



12:53:54 PST ---
In this light I long ago gave up on _public_ constructors and use factory
function everywhere for consistency. This way I finally get:
- 0 argument construction
- IFTI in case of templates
- UFCS notation such as 1.inch

Sadly it's solely convention based.

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


Max Samukha <samukha voliacable.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |samukha voliacable.com



PST ---

 I knew this was going to be a problem as soon I saw the pull implementing the
 change. But some pople insist on destroying any means of defining a default
 ctor even though everybody else demands it.
Black out default constructors just to make people fake those with factory functions. I think that's ok, pretty much in line with modern trends in software development. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 18 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12194


Jesse Phillips <Jesse.K.Phillips+D gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Jesse.K.Phillips+D gmail.co
                   |                            |m



14:04:47 PST ---
I'm not really against the change, but I do think it is dangerous since the
compiler can't/doesn't verify the needed changes were made.

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


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla digitalmars.com
         Resolution|                            |WONTFIX



17:51:11 PST ---

 I'm not really against the change, but I do think it is dangerous since the
 compiler can't/doesn't verify the needed changes were made.
In this case, the compiler does give a message. Mixing constructors and static opCall makes a struct hard to reason about and also resulted in some arbitrary behavior by the compiler. I.e. this change came about because of fixing other bugzilla issues. I'm going to mark it as wontfix because it is an intended change. I apologize for the breaking of the existing code, and for not handling this behavior change better. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 18 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12194




This change has been introduced to fix the language design issue discovered by
bug 12070 (the diagnostic message is added by issue 12124).

In D1 age, historically static opCall was a hack to use C++ like syntax for
object construction.
In D2, It has not been recommended because constructor is properly supported
for structs.

Until 2.064, constructor takes precedence over static opCall _in most cases_.
For example, if you mix constructors and static opCall that take arguments,
static opCall is always hidden.

struct S {
    this(int n) {}
    static void opCall(int n, int m) {}
}
void main() {
    auto s = S(1);     // call this(int)
    auto s = S(1, 2);  // error, this(int) is not callable using two int
arguments
}

But if static opCall has no arguments, it had been allowed for S(), like as
OP-code.

----

However, the language behavior will cause a problem if opCall method is not
static. Following is the sample code that summarize bug 12070.

struct S {
    this(int n) {}
    void opCall() {}
}
void main() {
    auto s = S();  // need 'this' for S.opCall()
}

Note the behavior that S.opCall() will match to the instance opCall.
D does not have the feature to resolve function overloading based on the
'static' attribute, as same as C++.

Although it is definitely legitimate to define both regular constructors and
non-static opCall, the code had not work contrary to the expectation until
2.064.

From 2.065, in order to fix the design issue, the syntax `Type()` is always
reserved for default construction if one or more user defined constructors
exist.
And it will conform to the D2 intention that using static opCall for
construction has not been recommended.

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





  this of course means tracking down the places which need
 fixed is not helped by the compiler.
 this of course means tracking down the places which need
fixed is not helped by the compiler. You can make error at the all places that using `static Struct opCall()`, by replacing it to ` disable this();`.
 void main() {
     assert(Struct() == Struct(2));
 }
 
 struct Struct {
     int a;
     this(int a) {
         this.a = a;
     }
disable this(); //static Struct opCall() { // return Struct(2); //}
 }
-------- test.d(2): Error: constructor test.Struct.this is not callable because it is annotated with disable -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 18 2014
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12194




20:02:35 PST ---

 You can make error at the all places that using `static Struct opCall()`, by
 replacing it to ` disable this();`.
Perfect recommendation, thank you. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 18 2014