-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[clang][regression][rejects-valid] clang trunk rejecting valid pack expansion #91787
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
Comments
@llvm/issue-subscribers-clang-frontend Author: Eric Niebler (ericniebler)
I believe the following C++20 code should compile:
template <class...>
concept True = true;
template <bool>
struct I {
template <template <class...> class F, class... As>
using f = F<As...>;
};
template <template <class...> class F, class... As>
using meval = I<True<As...>>::template f<F, As...>;
template <class F, class... As>
concept P = true;
template <class F, class... As>
requires P<F, As...>
using V = void;
template <class...Ts>
auto f() -> meval<V, int, Ts...> {
}
int main() {
f();
} Clang 18 and earlier accepts it, as does gcc. With clang-trunk, I get:
See repro here: https://godbolt.org/z/c1dG74EPd |
That's CWG1430 We can ask guidance from core if it should apply in the template argument deduction that happens within TTP matching (as specified to happen in P0522R0, in terms of function template rewrite). I see no such exclusion in the proposed solution. |
I'll note that this is breaking at least two popular open source libraries: stdexec and libunifex. Possibly others. |
template <template <class...> class F, class... As>
using Alias = F<As...>;
template <template <class...> class F, class... As>
using meval = Alias<F, As...>;
template <class F, class... As>
concept P = true;
template <class F, class... As>
requires P<F, As...>
using V = void;
template <class...Ts>
auto f() -> meval<V, int, Ts...> {
}
int main() {
f();
} After #89807, It's unclear what the conforming behavior here should be. Maybe we should ignore CWG1430 during partial ordering? I'll try to raise the issue in CWG but I think this issue give us ground to temporarily revert the default of This is disrupting everyone using stdexec, which is at least 3 vendors. @mizvekov are you able to work on a revert (switch back the flag to be off by default + remove the depreciation warning) ? |
When this sort of significant breakage happens, it's also usual that we would 'take the matter in to our own hands' and amend the rules ourselves, as we did to improve the situation with P0522. |
Note everyone is consistent on the examples from CWG1430: https://godbolt.org/z/xavdor73e and currently clang is the only one that rejects this example: https://godbolt.org/z/qe1ercoqj @cor3ntin raising some questions that looks like they need resolving, so it seems like we should revert so we can get some clarity here. |
Commenting out the template <class F, class... As>
//requires P<F, As...>
using V = void; |
It makes sense: There is a fast path that doesn't involve any template argument deduction, and it applies when the template parameter lists are close enough, but doesn't apply when constraints are involved. If CWG1430 required us to diagnose this, then this fast path would be wrong to accept that code, but that doesn't help your problem. |
After deliberation about this issue, I think we should accept the code. The template template parameter matching rules are a duck-typed, anything goes matter, where we will figure out if the use was valid later when we instantiate the template. |
We operated a partial revert of the problematic commit here #91811 |
Duplicate of #62529 |
I believe the following C++20 code should compile:
Clang 18 and earlier accepts it, as does gcc. With clang-trunk, I get:
See repro here: https://godbolt.org/z/c1dG74EPd
The text was updated successfully, but these errors were encountered: