Deprecate traits(isVirtualFunction) and traits(getVirtualFunctions) (#14802)

This commit is contained in:
Razvan Nitu 2023-01-20 16:11:37 +08:00 committed by GitHub
parent 35abfc4a9f
commit 636e61ea4d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 72 deletions

View file

@ -0,0 +1,11 @@
Deprecate `traits(isVirtualFunction)` and `traits(getVirtualFunctions)`
Up until this release, D had both `traits(isVirtualFunction)` and `traits(isVirtualMethod)`
(and their coressponding `traits(get...)` counterpart). The differenrcte between the two is
that `isVirtualFunction` returns true for `final` methods that do not override anything. This
is in contradiction with the D spec which states that `final` functions that do not override
other functions cannot be virtual. `isVirtualMethod` correctly returns `false` in that case.
Starting with this release, both `traits(isVirtualFunction)` and `traits(getVirtualFunctions)`
are deprecated. If the behavior of `traits(isVirtualFunction)` is desired, it can be achieved by
`traits(isVirtualMethod, f) || (traits(isFinalFunction, f) && !traits(isOverrideFunction, f))`.

View file

@ -634,6 +634,10 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
}
if (e.ident == Id.isVirtualFunction)
{
// @@@DEPRECATED2.121@@@
// Deprecated in 2.101 - Can be removed from 2.121
e.deprecation("`traits(isVirtualFunction)` is deprecated. Use `traits(isVirtualMethod)` instead");
if (dim != 1)
return dimError(1);
@ -995,6 +999,13 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
if (errors < global.errors)
e.error("`%s` cannot be resolved", eorig.toChars());
if (e.ident == Id.getVirtualFunctions)
{
// @@@DEPRECATED2.121@@@
// Deprecated in 2.101 - Can be removed from 2.121
e.deprecation("`traits(getVirtualFunctions)` is deprecated. Use `traits(getVirtualMethods)` instead");
}
/* Create tuple of functions of ex
*/
auto exps = new Expressions();

View file

@ -14,11 +14,6 @@ class Foo
{
auto dg = &f;
}
foreach (f; __traits(getVirtualFunctions, typeof(this), "bar"))
{
auto dg = &f;
}
}
uint bar() { return 0; }

View file

@ -0,0 +1,20 @@
// REQUIRED_ARGS: -de
/*
TEST_OUTPUT:
---
fail_compilation/deprecate_getVirtualFunctions.d(18): Deprecation: `traits(isVirtualFunction)` is deprecated. Use `traits(isVirtualMethod)` instead
fail_compilation/deprecate_getVirtualFunctions.d(19): Deprecation: `traits(getVirtualFunctions)` is deprecated. Use `traits(getVirtualMethods)` instead
---
*/
class A
{
void fun() {}
}
void main()
{
auto a = __traits(isVirtualFunction, A.fun);
foreach(f; __traits(getVirtualFunctions, A, "fun")) {}
}

View file

@ -8,4 +8,4 @@ fail_compilation/fail19076.d(11): Error: `(I).V` cannot be resolved
interface P { }
interface I : P { }
auto F = __traits(getVirtualFunctions, I, "V");
auto F = __traits(getVirtualMethods, I, "V");

View file

@ -1,28 +1,29 @@
/* TEST_OUTPUT:
---
fail_compilation/test17096.d(28): Error: expected 1 arguments for `isPOD` but had 2
fail_compilation/test17096.d(29): Error: expected 1 arguments for `isNested` but had 2
fail_compilation/test17096.d(30): Error: expected 1 arguments for `isVirtualFunction` but had 2
fail_compilation/test17096.d(31): Error: expected 1 arguments for `isVirtualMethod` but had 2
fail_compilation/test17096.d(32): Error: expected 1 arguments for `isAbstractFunction` but had 2
fail_compilation/test17096.d(33): Error: expected 1 arguments for `isFinalFunction` but had 2
fail_compilation/test17096.d(34): Error: expected 1 arguments for `isOverrideFunction` but had 2
fail_compilation/test17096.d(35): Error: expected 1 arguments for `isStaticFunction` but had 2
fail_compilation/test17096.d(36): Error: expected 1 arguments for `isRef` but had 2
fail_compilation/test17096.d(37): Error: expected 1 arguments for `isOut` but had 2
fail_compilation/test17096.d(38): Error: expected 1 arguments for `isLazy` but had 2
fail_compilation/test17096.d(39): Error: expected 1 arguments for `identifier` but had 2
fail_compilation/test17096.d(40): Error: expected 1 arguments for `getProtection` but had 2
fail_compilation/test17096.d(41): Error: expected 1 arguments for `parent` but had 2
fail_compilation/test17096.d(42): Error: expected 1 arguments for `classInstanceSize` but had 2
fail_compilation/test17096.d(43): Error: expected 1 arguments for `allMembers` but had 2
fail_compilation/test17096.d(44): Error: expected 1 arguments for `derivedMembers` but had 2
fail_compilation/test17096.d(45): Error: expected 1 arguments for `getAliasThis` but had 2
fail_compilation/test17096.d(46): Error: expected 1 arguments for `getAttributes` but had 2
fail_compilation/test17096.d(47): Error: expected 1 arguments for `getFunctionAttributes` but had 2
fail_compilation/test17096.d(48): Error: expected 1 arguments for `getUnitTests` but had 2
fail_compilation/test17096.d(49): Error: expected 1 arguments for `getVirtualIndex` but had 2
fail_compilation/test17096.d(50): Error: a single type expected for trait pointerBitmap
fail_compilation/test17096.d(29): Error: expected 1 arguments for `isPOD` but had 2
fail_compilation/test17096.d(30): Error: expected 1 arguments for `isNested` but had 2
fail_compilation/test17096.d(31): Deprecation: `traits(isVirtualFunction)` is deprecated. Use `traits(isVirtualMethod)` instead
fail_compilation/test17096.d(31): Error: expected 1 arguments for `isVirtualFunction` but had 2
fail_compilation/test17096.d(32): Error: expected 1 arguments for `isVirtualMethod` but had 2
fail_compilation/test17096.d(33): Error: expected 1 arguments for `isAbstractFunction` but had 2
fail_compilation/test17096.d(34): Error: expected 1 arguments for `isFinalFunction` but had 2
fail_compilation/test17096.d(35): Error: expected 1 arguments for `isOverrideFunction` but had 2
fail_compilation/test17096.d(36): Error: expected 1 arguments for `isStaticFunction` but had 2
fail_compilation/test17096.d(37): Error: expected 1 arguments for `isRef` but had 2
fail_compilation/test17096.d(38): Error: expected 1 arguments for `isOut` but had 2
fail_compilation/test17096.d(39): Error: expected 1 arguments for `isLazy` but had 2
fail_compilation/test17096.d(40): Error: expected 1 arguments for `identifier` but had 2
fail_compilation/test17096.d(41): Error: expected 1 arguments for `getProtection` but had 2
fail_compilation/test17096.d(42): Error: expected 1 arguments for `parent` but had 2
fail_compilation/test17096.d(43): Error: expected 1 arguments for `classInstanceSize` but had 2
fail_compilation/test17096.d(44): Error: expected 1 arguments for `allMembers` but had 2
fail_compilation/test17096.d(45): Error: expected 1 arguments for `derivedMembers` but had 2
fail_compilation/test17096.d(46): Error: expected 1 arguments for `getAliasThis` but had 2
fail_compilation/test17096.d(47): Error: expected 1 arguments for `getAttributes` but had 2
fail_compilation/test17096.d(48): Error: expected 1 arguments for `getFunctionAttributes` but had 2
fail_compilation/test17096.d(49): Error: expected 1 arguments for `getUnitTests` but had 2
fail_compilation/test17096.d(50): Error: expected 1 arguments for `getVirtualIndex` but had 2
fail_compilation/test17096.d(51): Error: a single type expected for trait pointerBitmap
---
*/
enum b03 = __traits(isPOD, 1, 2);

View file

@ -63,8 +63,6 @@ TmpPrm!(__traits(getMember, Foo, "MyInt")) tpt = TmpPrm!(__traits(getMember, Foo
int virtual(int p){return p;}
void test(this T)()
{
alias vf = __traits(getVirtualFunctions, Class, "virtual");
assert(vf.length == 2);
alias vm = __traits(getVirtualMethods, Class, "virtual");
assert(vm.length == 1);
assert(vm[0](42) == 42);

View file

@ -312,14 +312,6 @@ void test9()
/********************************************************/
void test10()
{
assert(__traits(isVirtualFunction, C.bar) == true);
assert(__traits(isVirtualFunction, S.bar) == false);
}
/********************************************************/
void test11()
{
assert(__traits(isAbstractFunction, C.bar) == false);
@ -403,24 +395,6 @@ class D15
int foo(int) { return 2; }
}
void test15()
{
D15 d = new D15();
assert(__traits(getVirtualFunctions, D15, "foo").length == 2);
assert(typeid(typeof(__traits(getVirtualFunctions, D15, "foo")[0])).toString()
== "void function()");
assert(typeid(typeof(__traits(getVirtualFunctions, D15, "foo")[1])).toString()
== "int function(int)");
alias typeof(__traits(getVirtualFunctions, D15, "foo")) b;
assert(typeid(b[0]).toString() == "void function()");
assert(typeid(b[1]).toString() == "int function(int)");
auto i = __traits(getVirtualFunctions, d, "foo")[1](1);
assert(i == 2);
}
/********************************************************/
struct S16 { }
@ -714,14 +688,6 @@ interface AA
int YYY();
}
class CC : AA
{
final int YYY() { return 4; }
}
static assert(__traits(isVirtualMethod, CC.YYY));
static assert(__traits(getVirtualMethods, CC, "YYY").length == 1);
class DD
{
final int YYY() { return 4; }
@ -790,8 +756,6 @@ void test7858()
static assert(__traits(isFinalFunction, C.ffunc) ==
__traits(isFinalFunction, __traits(getOverloads, C, "ffunc")[0])); // NG
static assert(__traits(isVirtualFunction, C.vfunc) ==
__traits(isVirtualFunction, __traits(getOverloads, C, "vfunc")[0])); // NG
static assert(__traits(isVirtualMethod, C.vfunc) ==
__traits(isVirtualMethod, __traits(getOverloads, C, "vfunc")[0])); // NG
static assert(__traits(isAbstractFunction, C.afunc) ==
@ -1456,13 +1420,11 @@ int main()
test7();
test8();
test9();
test10();
test11();
test12();
test13();
test7123();
test14();
test15();
test16();
test17();
test18();

View file

@ -654,7 +654,7 @@ if (func.length == 1 /*&& isCallable!func*/)
int test(int);
int test() @property;
}
alias ov = __traits(getVirtualFunctions, Overloads, "test");
alias ov = __traits(getVirtualMethods, Overloads, "test");
alias F_ov0 = FunctionTypeOf!(ov[0]);
alias F_ov1 = FunctionTypeOf!(ov[1]);
alias F_ov2 = FunctionTypeOf!(ov[2]);

View file

@ -1417,7 +1417,7 @@ class TypeInfo_Function : TypeInfo
int func(int a, int b);
}
alias functionTypes = typeof(__traits(getVirtualFunctions, C, "func"));
alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
assert(typeid(functionTypes[0]).toString() == "void function()");
assert(typeid(functionTypes[1]).toString() == "void function(int)");
assert(typeid(functionTypes[2]).toString() == "int function(int, int)");
@ -1431,7 +1431,7 @@ class TypeInfo_Function : TypeInfo
void func(int a);
}
alias functionTypes = typeof(__traits(getVirtualFunctions, C, "func"));
alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
Object obj = typeid(functionTypes[0]);
assert(obj.opEquals(typeid(functionTypes[0])));