mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Deprecate typesafe variadic class arguments (#20673)
This commit is contained in:
parent
0131a00173
commit
961862c455
5 changed files with 53 additions and 50 deletions
40
changelog/dmd.deprecation-typesafe-variadic-class.dd
Normal file
40
changelog/dmd.deprecation-typesafe-variadic-class.dd
Normal file
|
@ -0,0 +1,40 @@
|
|||
Typesafe variadic class parameters have been deprecated
|
||||
|
||||
This obscure feature allowed a limited form of implicit construction:
|
||||
|
||||
---
|
||||
void check(bool x, Exception e...)
|
||||
{
|
||||
if (!x)
|
||||
throw e;
|
||||
}
|
||||
|
||||
void main(string[] args)
|
||||
{
|
||||
check(args.length > 1, "missing argument");
|
||||
}
|
||||
---
|
||||
|
||||
However, few uses of this feature have been found, and one project was actually mistakenly using it instead of the more common Typesafe variadic array parameter.
|
||||
Considering D doesn't support implicit construction and already has a confusing amount of different variadic parameter forms, it was decided to remove this feature.
|
||||
|
||||
As a corrective action, either call the constructor in the callee:
|
||||
|
||||
---
|
||||
void check(string msg)
|
||||
{
|
||||
if (!x)
|
||||
throw new Exception(msg);
|
||||
}
|
||||
---
|
||||
|
||||
Or let the caller construct the class instance:
|
||||
|
||||
---
|
||||
void check(bool x, Exception e);
|
||||
|
||||
void main(string[] args)
|
||||
{
|
||||
check(args.length > 1, new Exception("missing argument"));
|
||||
}
|
||||
---
|
|
@ -2493,10 +2493,17 @@ Type typeSemantic(Type type, Loc loc, Scope* sc)
|
|||
errors = true;
|
||||
}
|
||||
|
||||
const bool isTypesafeVariadic = i + 1 == dim &&
|
||||
tf.parameterList.varargs == VarArg.typesafe &&
|
||||
(t.isTypeDArray() || t.isTypeClass());
|
||||
if (isTypesafeVariadic)
|
||||
const bool isTypesafeVariadic = i + 1 == dim && tf.parameterList.varargs == VarArg.typesafe;
|
||||
const bool isStackAllocatedVariadic = isTypesafeVariadic && (t.isTypeDArray() || t.isTypeClass());
|
||||
|
||||
if (isTypesafeVariadic && t.isTypeClass())
|
||||
{
|
||||
// Deprecated in 2.111, kept as a legacy feature for compatibility (currently no plan to turn it into an error)
|
||||
.deprecation(loc, "typesafe variadic parameters with a `class` type (`%s %s...`) are deprecated",
|
||||
t.isTypeClass().sym.ident.toChars(), fparam.toChars());
|
||||
}
|
||||
|
||||
if (isStackAllocatedVariadic)
|
||||
{
|
||||
/* typesafe variadic arguments are constructed on the stack, so must be `scope`
|
||||
*/
|
||||
|
@ -2518,7 +2525,7 @@ Type typeSemantic(Type type, Loc loc, Scope* sc)
|
|||
}
|
||||
}
|
||||
|
||||
if (isTypesafeVariadic)
|
||||
if (isStackAllocatedVariadic)
|
||||
{
|
||||
/* This is because they can be constructed on the stack
|
||||
* https://dlang.org/spec/function.html#typesafe_variadic_functions
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test22023.d(102): Error: typesafe variadic function parameter `a` of type `int[]` cannot be marked `return`
|
||||
fail_compilation/test22023.d(107): Error: typesafe variadic function parameter `c` of type `test22023.C` cannot be marked `return`
|
||||
---
|
||||
*/
|
||||
|
||||
|
@ -14,13 +13,3 @@ ref int f(return int[] a ...)
|
|||
{
|
||||
return a[2];
|
||||
}
|
||||
|
||||
ref int g(return C c ...)
|
||||
{
|
||||
return c.x;
|
||||
}
|
||||
|
||||
class C
|
||||
{
|
||||
int x;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* REQUIRED_ARGS: -preview=dip1000
|
||||
* TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test22818.d(102): Deprecation: typesafe variadic parameters with a `class` type (`C c...`) are deprecated
|
||||
fail_compilation/test22818.d(104): Error: scope parameter `c` may not be returned
|
||||
---
|
||||
*/
|
||||
|
|
|
@ -83,39 +83,6 @@ void test3()
|
|||
printf("%d\n", i);
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
class Foo4
|
||||
{
|
||||
int a;
|
||||
float f;
|
||||
double d;
|
||||
|
||||
this(int a, float f, double d)
|
||||
{
|
||||
this.a = a;
|
||||
this.f = f;
|
||||
this.d = d;
|
||||
}
|
||||
}
|
||||
|
||||
int sum4(Foo4 f ...)
|
||||
{
|
||||
return cast(int)(f.a + f.f + f.d);
|
||||
}
|
||||
|
||||
void test4()
|
||||
{
|
||||
int i;
|
||||
Foo4 foo = new Foo4(1, 2f, 3.0);
|
||||
|
||||
i = sum4(foo);
|
||||
assert(i == 1+2+3);
|
||||
i = sum4(4, 5f, 6.0);
|
||||
assert(i == 4+5+6);
|
||||
|
||||
printf("%d\n", i);
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
|
@ -139,7 +106,6 @@ int main()
|
|||
test1();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
test5();
|
||||
|
||||
printf("Success\n");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue