Skip to content

Commit

Permalink
Merge pull request #7569 from BBasile/issue-18149
Browse files Browse the repository at this point in the history
fix issue 18149 - Add a compiler trait to detect if a function is @disable
merged-on-behalf-of: unknown
  • Loading branch information
dlang-bot authored Jan 18, 2018
2 parents f7313b5 + 43ef5ce commit c68ae00
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 0 deletions.
43 changes: 43 additions & 0 deletions changelog/disabled-trait.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
A compiler trait used to detect if a function is marked with `@disable` has been added.

Prior to this release is was impossible to filter out `@disable` functions without
using `__trait(compiles)`, which was less than ideal since `false` could be
returned for other reasons.

Now, in metaprogramming code, `@disable` functions can be detected accurately,
using `__traits(isDisabled)` and even in overload sets:

---
module runnable;

struct Foo
{
import std.stdio;
@disable static void foo() {__PRETTY_FUNCTION__.writeln;}
static void foo(int v) {__PRETTY_FUNCTION__.writeln;}
static void bar() {__PRETTY_FUNCTION__.writeln;}
@disable static void bar(int v) {__PRETTY_FUNCTION__.writeln;}
}

void test(T)()
{
foreach (member; __traits(allMembers, T))
foreach (overload; __traits(getOverloads, T, member))
static if (!__traits(isDisabled, overload))
{
static if (is(typeof(&overload) == void function()))
overload();
else static if (is(typeof(&overload) == void function(int)))
overload(42);
}
}

void main(){test!Foo;}
---

prints:

$(CONSOLE
void runnable.Foo.foo(int v)
void runnable.Foo.bar()
)
5 changes: 5 additions & 0 deletions src/dmd/declaration.d
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,11 @@ extern (C++) abstract class Declaration : Dsymbol
return (storage_class & STC.deprecated_) != 0;
}

final bool isDisabled() const pure nothrow @nogc @safe
{
return (storage_class & STC.disable) != 0;
}

final bool isOverride() const pure nothrow @nogc @safe
{
return (storage_class & STC.override_) != 0;
Expand Down
1 change: 1 addition & 0 deletions src/dmd/id.d
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ immutable Msgtable[] msgtable =
{ "isTemplate" },
{ "isPOD" },
{ "isDeprecated" },
{ "isDisabled" },
{ "isFuture" },
{ "isNested" },
{ "isFloating" },
Expand Down
8 changes: 8 additions & 0 deletions src/dmd/traits.d
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ shared static this()
"isAbstractClass",
"isArithmetic",
"isAssociativeArray",
"isDisabled",
"isDeprecated",
"isFuture",
"isFinalClass",
Expand Down Expand Up @@ -583,6 +584,13 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
e.error("aggregate or function expected instead of `%s`", o.toChars());
return new ErrorExp();
}
if (e.ident == Id.isDisabled)
{
if (dim != 1)
return dimError(1);

return isFuncX(f => f.isDisabled());
}
if (e.ident == Id.isAbstractFunction)
{
if (dim != 1)
Expand Down
10 changes: 10 additions & 0 deletions test/runnable/traits.d
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class AC2 { abstract void foo(); }
class AC3 : AC2 { }
final class FC { void foo() { } }
enum E { EMEM }
struct D1 { @disable void true_(); void false_(){} }

/********************************************************/

Expand Down Expand Up @@ -1540,6 +1541,15 @@ void test15094()

/********************************************************/

void testIsDisabled()
{
static assert(__traits(isDisabled, D1.true_));
static assert(!__traits(isDisabled, D1.false_));
static assert(!__traits(isDisabled, D1));
}

/********************************************************/

int main()
{
test1();
Expand Down

0 comments on commit c68ae00

Please sign in to comment.