__decay built-in rejected by gcc head
Opened this issue · 3 comments
My guess is that in
commit 9d0dba02c5452d5906f87e59455a4c38944eb217
Author: Ken Matsui <kmatsui@gcc.gnu.org>
Date: Thu Feb 15 04:44:54 2024 -0800
libstdc++: Optimize std::decay compilation performance
This patch optimizes the compilation performance of std::decay
by dispatching to the new __decay built-in trait.
gcc caught up with include/stdexec/__detail/__type_traits.hpp
//////////////////////////////////////////////////////////////////////////////////////////////////
// __decay_t: An efficient implementation for std::decay
#if STDEXEC_HAS_BUILTIN(__decay)
template <class _Ty>
using __decay_t = __decay(_Ty);
End result is my old code fails with
In file included from bounce.cc:32:
/usr/src/local/stdexec/include/exec/async_scope.hpp: In instantiation of 'exec::__scope::__when_empty_sender_t<_Constrained> exec::__scope::async_scope::when_empty(_Constrained&&) const [with _Constrained = stdexec::__sexpr<<lambda closure object>stdexec::{anonymous}::<lambda()>(), stdexec::{anonymous}::__anon>]':
bounce.cc:473:1: required from here
473 | }
| ^
/usr/src/local/stdexec/include/exec/async_scope.hpp:758:12: error: use of built-in trait '__decay(_Ty)' in function signature; use library traits instead
758 | auto when_empty(_Constrained&& __c) const -> __when_empty_sender_t<_Constrained> {
| ^~~~~~~~~~
/usr/src/local/stdexec/include/exec/async_scope.hpp: In instantiation of 'exec::__scope::__when_empty_sender_t<_Constrained> exec::__scope::async_scope::when_empty(_Constrained&&) const [with _Constrained = stdexec::__sexpr<<lambda closure object>stdexec::{anonymous}::<lambda()>(), stdexec::{anonymous}::__anon>]':
bounce.cc:473:1: required from here
473 | }
| ^
/usr/src/local/stdexec/include/exec/async_scope.hpp:758:12: error: use of built-in trait '__decay(_Ty)' in function signature; use library traits instead
758 | auto when_empty(_Constrained&& __c) const -> __when_empty_sender_t<_Constrained> {
| ^~~~~~~~~~
Egregious hack
diff --git a/include/stdexec/__detail/__type_traits.hpp b/include/stdexec/__detail/__type_traits.hpp
index 01b96467..cd78cf1e 100644
--- a/include/stdexec/__detail/__type_traits.hpp
+++ b/include/stdexec/__detail/__type_traits.hpp
@@ -31,7 +31,7 @@ namespace stdexec {
#if STDEXEC_HAS_BUILTIN(__decay)
template <class _Ty>
- using __decay_t = __decay(_Ty);
+ using __decay_t = std::decay_t<_Ty>;
#elif STDEXEC_NVHPC()
allows me to compile once again.
Presumably ignore until 15 is released, then test on version?
FWIW, there's a GCC bug report related to it (the bug here fixed was an ICE in the compiler), apparently using __decay
is not the way to go.
Cf. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116052
apparently using __decay is not the way to go.
What is the issue with using __decay
builtin?
It seems like the stdlib is fine using it in the definition of the std::decay
struct definition.
template<typename T>
struct decay {
using type = __decay(T);
};
Is there a restriction on the places that such a built-in can be used?
i.e. it's ok to use in member-alias-templates of a class definition, but not at namespace-scope-alias-templates.
Having said that, if the compilers/stdlib are now optimizing std::decay_t
then we may as well just use that directly rather than trying to optimize in stdexec code.
Is there a restriction on the places that such a built-in can be used?
Yes, the restriction is that built-ins are not allowed to appear in function signatures. That's what the compilation error is all about. Using the trait that resolves to the built-in in function signatures is fine. Use the trait, don't use the built-in.