Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/stable' into merge_stable
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinNowak committed Jan 17, 2016
2 parents 0fd13df + 8399e29 commit d22b6ae
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 37 deletions.
51 changes: 21 additions & 30 deletions src/func.d
Expand Up @@ -4451,38 +4451,13 @@ public:
*/
if (ad && (!parent.isTemplateInstance() || parent.isTemplateMixin()))
{
size_t dim = Parameter.dim(tf.parameters);
StructDeclaration sd = ad.isStructDeclaration();
if (sd)
{
bool allDefaultedParams = (dim == 0) && tf.varargs == 1; // c-style: foo(...)
bool isDefCtor = dim == 0;

for (size_t i = 0; i < dim; i++)
{
auto arg = Parameter.getNth(tf.parameters, i);

// note: D-style variadic arguments allowed as a special-case (tf.varargs == 2)
if (i + 1 == dim && arg.defaultArg)
{
isDefCtor = true;
allDefaultedParams = true;
}
else
{
break;
}
}
immutable dim = Parameter.dim(tf.parameters);

if (isDefCtor)
if (auto sd = ad.isStructDeclaration())
{
if (dim == 0 && tf.varargs == 0) // empty default ctor w/o any varargs
{
if (allDefaultedParams) // only warn for now
{
warning(loc, "%s %s default constructor for structs "
"only allowed with @disable, no body, and no "
"parameters", kind(), toPrettyChars());
}
else if (fbody || !(storage_class & STCdisable) || dim)
if (fbody || !(storage_class & STCdisable))
{
error("default constructor for structs only allowed "
"with @disable, no body, and no parameters");
Expand All @@ -4491,6 +4466,22 @@ public:
}
sd.noDefaultCtor = true;
}
else if (dim == 0 && tf.varargs) // allow varargs only ctor
{
}
else if (dim && Parameter.getNth(tf.parameters, 0).defaultArg)
{
// if the first parameter has a default argument, then the rest does as well
if (storage_class & STCdisable)
{
deprecation("@disable'd constructor cannot have default "~
"arguments for all parameters.");
deprecationSupplemental(loc, "Use @disable this(); if you want to disable default initialization.");
}
else
deprecation("all parameters have default arguments, "~
"but structs cannot have default constructors.");
}
}
else if (dim == 0 && tf.varargs == 0)
{
Expand Down
2 changes: 2 additions & 0 deletions test/compilable/compile1.d
Expand Up @@ -937,3 +937,5 @@ import core.vararg;
struct S3438_1 { this(int x, int y = 1) { } }
struct S3438_2 { this(int x, ...) { } }
struct S3438_3 { this(int x, int[] arr...) { } }
struct S3438_4 { this(...) { } }
struct S3438_5 { this(int[] arr...) { } }
15 changes: 8 additions & 7 deletions test/fail_compilation/diag3438.d
@@ -1,20 +1,21 @@
// REQUIRED_ARGS: -w
// REQUIRED_ARGS: -de
/*
TEST_OUTPUT:
---
fail_compilation/diag3438.d(15): Warning: constructor diag3438.F1.this default constructor for structs only allowed with @disable, no body, and no parameters
fail_compilation/diag3438.d(16): Warning: constructor diag3438.F2.this default constructor for structs only allowed with @disable, no body, and no parameters
fail_compilation/diag3438.d(17): Warning: constructor diag3438.F3.this default constructor for structs only allowed with @disable, no body, and no parameters
fail_compilation/diag3438.d(19): Warning: constructor diag3438.F5.this default constructor for structs only allowed with @disable, no body, and no parameters
fail_compilation/diag3438.d(20): Warning: constructor diag3438.F6.this default constructor for structs only allowed with @disable, no body, and no parameters
fail_compilation/diag3438.d(16): Deprecation: constructor diag3438.F1.this all parameters have default arguments, but structs cannot have default constructors.
fail_compilation/diag3438.d(17): Deprecation: constructor diag3438.F2.this all parameters have default arguments, but structs cannot have default constructors.
fail_compilation/diag3438.d(20): Deprecation: constructor diag3438.F5.this @disable'd constructor cannot have default arguments for all parameters.
fail_compilation/diag3438.d(20): Deprecation: Use @disable this(); if you want to disable default initialization.
fail_compilation/diag3438.d(21): Deprecation: constructor diag3438.F6.this @disable'd constructor cannot have default arguments for all parameters.
fail_compilation/diag3438.d(21): Deprecation: Use @disable this(); if you want to disable default initialization.
---
*/

import core.vararg;

struct F1 { this(int x = 1) { } }
struct F2 { this(int x = 1, ...) { } }
struct F3 { this(...) { } }
struct F3 { this(...) { } } // ok
struct F4 { this(int[] x...) { } } // ok
struct F5 { @disable this(int x = 1); }
struct F6 { @disable this(int x = 1) { } }
9 changes: 9 additions & 0 deletions test/fail_compilation/diag3438b.d
@@ -0,0 +1,9 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag3438b.d(9): Error: default argument expected for y
---
*/

// Make sure the deprecation doesn't interfere w/ the check for default arguments
struct S { this(int x = 1, int y) { } }

0 comments on commit d22b6ae

Please sign in to comment.