-
Notifications
You must be signed in to change notification settings - Fork 226
Constexpr Improvements #1789
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
RobertLeahy
wants to merge
4
commits into
NVIDIA:main
Choose a base branch
from
RobertLeahy:constexpr_20260125
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Constexpr Improvements #1789
+9
−6
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The type returned by stdexec::__apply was previously specified via
decltype(auto). This is convenient to write, but means that in order to
determine the return type the compiler must substitute into the actual
body of the function. Doing this to constexpr functions causes Clang (at
least up to 21.1.0) to fail to build the get_env function of many
receiver types which are member types of an operation state (and which
contain a reference back to that operation state). Consider this example
which doesn't build on Clang 21.1.0 and which is intended to be similar
to the aforementioned situation:
template<typename T>
constexpr auto get(T& t) noexcept {
return t.get();
}
template<typename T>
struct state {
using return_type = typename T::type;
struct inner {
constexpr return_type get() const noexcept;
state& self;
};
static_assert(
std::is_same_v<
decltype(get(std::declval<inner&>())),
int>);
T t;
};
template<typename T>
constexpr auto state<T>::inner::get() const noexcept -> return_type {
return self.t.get();
}
struct t {
using type = int;
constexpr int get() const noexcept {
return i;
}
int i;
};
constexpr auto impl() noexcept {
state<t> s{t{5}};
state<t>::inner i{s};
return get(i);
}
The error given by clang is that state<t> is incomplete when it's used
within state<t>::inner::get. The backtrace associated with the
compilation error identifies the static_assert as the problematic source
of the use, if it is removed then Clang 21.1.0 accepts the above. This
is eyebrow-raising for at least two reasons:
- The point of use of state<t> is within the out of line definition of
state::inner::get which occurs lexically after state is complete
- state::inner::get does not have a deduced return type, therefore the
compiler has all the information necessary to determine the return
type of get (the free function) without considering the definition of
state::inner::get
Codifying the second bullet by explicitly specifying the return type of
get (the free function):
constexpr auto get(T& t) noexcept -> decltype(t.get()) {
return t.get();
}
Causes Clang 21.1.0 to accept the above example (because it doesn't
attempt to build the body of state::inner::get from a context whereat
state is incomplete).
Note that removing constexpr from state::inner::get causes Clang 21.1.0
to accept the original example.
This discussion may seem to have nothing to do with stdexec::__apply
until one examines the backtrace generated when Clang fails to build the
get_env member function of affected receiver types: The backtrace
radiates from building the body of stdexec::__apply.
Explicitly specified the return type of stdexec::__apply to ameliorate
the above.
ericniebler
reviewed
Jan 26, 2026
… and noexcept clause
Collaborator
|
/ok to test 52deced |
ericniebler
approved these changes
Jan 26, 2026
Collaborator
|
/ok to test 2beb079 |
romintomasetti
added a commit
to romintomasetti/stdexec
that referenced
this pull request
Jan 26, 2026
Signed-off-by: romintomasetti <romin.tomasetti@gmail.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Please do not squash.