D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3367 - Regression: struct initialization no longer supports ctor overloads
Summary: Regression: struct initialization no longer supports ctor overloads
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Windows
: P2 regression
Assignee: No Owner
URL:
Keywords: patch, rejects-valid
Depends on:
Blocks:
 
Reported: 2009-10-05 20:45 UTC by Rob Jacques
Modified: 2015-06-09 01:29 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Rob Jacques 2009-10-05 20:45:10 UTC
In DMD 2.032, when a struct was assigned to at it's declaration point, opAssign overloads were called if other alternative were not available. In DMD 2.033, neither opAssign or ctor overloads are called, only static opCall works

struct Foo {
    int x;
//    static opCall(int v) { // Un-comment this and the below works
//        Foo f;
//        f.x = v;
//        return f;
//    }
    this(int v){ x = v; }
    void opAssign(int v){
        x = v;
        return this;
    }
}

void main(char[][] args) {

    int y = 5;
    Foo f = y;  // fails
    f = y;      // okay
    f = Foo(y); // okay

}
Comment 1 Don 2009-10-06 01:14:23 UTC
My fault. This is a consquence of the fix to bug 2702. Previously it used to accept any old garbage inside a struct initializer; now it only accepts static opCall. It should definitely allow constructors as well. 

Based on my reading of the spec, the fact that opAssign used to work seems to have been a bug:
"assignment is defined as copying the contents of one object over another, already initialized, type" (struct.html)
Comment 2 Don 2009-10-29 12:58:44 UTC
PATCH: declaration.c, line 1094.
		    {
			/* Look for opCall
			 * See bugzilla 2702 for more discussion
			 */
			Type *ti = ei->exp->type->toBasetype();
------- ADD THIS CODE:			
			// Look for ctor
			if (sd->ctor && 
			    /* Initializing with the same type is done differently
			     */
			    !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc))) {
			   // Rewrite as e1.call(arguments)
			    Expression * eCall = new DotIdExp(loc, e1, Id::ctor);
			    ei->exp = new CallExp(loc, eCall, ei->exp);
			} 
			else
-----------
			// Don't cast away invariant or mutability in initializer
			if (search_function(sd, Id::call) &&
Comment 3 Leandro Lucarella 2009-11-04 06:39:53 UTC
SVN commit: http://www.dsource.org/projects/dmd/changeset/235
Comment 4 Walter Bright 2009-11-06 11:34:23 UTC
Fixed dmd 2.036