From c9f2158b59a460350e993a2deccad9dbcafc7a51 Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Mon, 13 Nov 2017 02:42:09 +0100 Subject: [PATCH] fix issue 12064 - std.typecons.wrap doesn't handle NVI --- std/typecons.d | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/std/typecons.d b/std/typecons.d index e2b84f265..c9c10517b 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -4684,6 +4684,13 @@ if (Targets.length >= 1 && allSatisfy!(isMutable, Targets)) alias type = F; } + // issue 12064: Remove NVI members + template OnlyVirtual(members...) + { + enum notFinal(alias T) = !__traits(isFinalFunction, T); + alias OnlyVirtual = Filter!(notFinal, members); + } + // Concat all Targets function members into one tuple template Concat(size_t i = 0) { @@ -4691,9 +4698,10 @@ if (Targets.length >= 1 && allSatisfy!(isMutable, Targets)) alias Concat = AliasSeq!(); else { - alias Concat = AliasSeq!(GetOverloadedMethods!(Targets[i]), Concat!(i + 1)); + alias Concat = AliasSeq!(OnlyVirtual!(GetOverloadedMethods!(Targets[i]), Concat!(i + 1))); } } + // Remove duplicated functions based on the identifier name and function type covariance template Uniq(members...) { @@ -5059,6 +5067,32 @@ if (!isMutable!Target) assert(i.bar(10) == 100); } +@system unittest // issue 12064 +{ + interface I + { + int foo(); + final int nvi1(){return foo();} + } + + interface J + { + int bar(); + final int nvi2(){return bar();} + } + + class Baz + { + int foo() { return 42;} + int bar() { return 12064;} + } + + auto baz = new Baz(); + auto foobar = baz.wrap!(I, J)(); + assert(foobar.nvi1 == 42); + assert(foobar.nvi2 == 12064); +} + // Make a tuple of non-static function symbols package template GetOverloadedMethods(T) {