From 7a6da0ff7907c08035d42653bb4cc0dabd46269f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sat, 4 Apr 2020 11:19:40 +0200 Subject: [PATCH] Avoid instantiating generic visitor with types it cannot handle. In cases where statically typed visitors need to be defined to avoid compile errors in a generic visitor, the generic one was still instantiated with the types already handled by the statically typed one(s), possibly resulting in a compile error. --- source/taggedalgebraic/visit.d | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/taggedalgebraic/visit.d b/source/taggedalgebraic/visit.d index 8aeac99..46e9086 100644 --- a/source/taggedalgebraic/visit.d +++ b/source/taggedalgebraic/visit.d @@ -217,7 +217,7 @@ private template matchesType(alias fun) { else static if (Params.length == 1 && is(T == Params[0])) enum matchesType = true; else enum matchesType = false; } else static if (!isUnitType!T) { - static if (isSomeFunction!(fun!T)) { + static if (__traits(compiles, fun!T) && isSomeFunction!(fun!T)) { alias Params = ParameterTypeTuple!(fun!T); static if (Params.length == 1 && is(T == Params[0])) enum matchesType = true; else enum matchesType = false; @@ -226,6 +226,16 @@ private template matchesType(alias fun) { } } +unittest { + class C {} + alias mt1 = matchesType!((C c) => true); + alias mt2 = matchesType!((c) { static assert(!is(typeof(c) == C)); }); + static assert(mt1!C); + static assert(!mt1!int); + static assert(mt2!int); + static assert(!mt2!C); +} + private template selectHandler(T, VISITORS...) { import std.traits : ParameterTypeTuple, isSomeFunction;