From dfa92a9cb68366a8655ac26b51af0c740bcf9b72 Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Fri, 23 Dec 2022 17:56:56 +0000 Subject: [PATCH] tint: Fix ProgramBuilder::WrapInFunction overload not being picked up Before this change, the variadic function template version of WrapInFunction would be selected when passing a utils::VectorRef, even though an overload exists for that type. The reason is that during type deduction, the compiler will select templates over non-templates in its overload set. The only way around this was to avoid type-deduction by explicitly casting the argument to utils::VectorRef. This CL adds a CanWrapInStatement metafunction that evaluates to true if the arg type is one that could be passed to ProgramBuilder::WrapInStatement. This is used to SFINAE in the variadic args version of WrapInFunction. Change-Id: I8aa3d69e2ce7324fd60b1b2a5906a51d51b549a3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/115502 Reviewed-by: David Neto Commit-Queue: Antonio Maiorano Kokoro: Kokoro --- src/tint/program_builder.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h index 5396cdd0c5..4dac010736 100644 --- a/src/tint/program_builder.h +++ b/src/tint/program_builder.h @@ -149,6 +149,10 @@ struct IsVectorLike> { }; } // namespace detail +// Forward declare metafunction that evaluates to true iff T can be wrapped in a statement. +template +struct CanWrapInStatement; + /// ProgramBuilder is a mutable builder for a Program. /// To construct a Program, populate the builder and then `std::move` it to a /// Program. @@ -3326,12 +3330,13 @@ class ProgramBuilder { /// by the Resolver. /// @param args a mix of ast::Expression, ast::Statement, ast::Variables. /// @returns the function - template + template ::value && ...)>> const ast::Function* WrapInFunction(ARGS&&... args) { utils::Vector stmts{ WrapInStatement(std::forward(args))..., }; - return WrapInFunction(utils::VectorRef{std::move(stmts)}); + return WrapInFunction(std::move(stmts)); } /// @param stmts a list of ast::Statement that will be wrapped by a function, /// so that each statement is reachable by the Resolver. @@ -3411,6 +3416,17 @@ inline ProgramID ProgramIDOf(const ProgramBuilder* builder) { return builder->ID(); } +// Primary template for metafunction that evaluates to true iff T can be wrapped in a statement. +template +struct CanWrapInStatement : std::false_type {}; + +// Specialization of CanWrapInStatement +template +struct CanWrapInStatement< + T, + std::void_t().WrapInStatement(std::declval()))>> + : std::true_type {}; + } // namespace tint #endif // SRC_TINT_PROGRAM_BUILDER_H_