Skip to content
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

CWG2975 [temp.constr.normal] Effect of concept _template-head_s on parameter mappings #659

Open
hubert-reinterpretcast opened this issue Dec 24, 2024 · 3 comments

Comments

@hubert-reinterpretcast
Copy link

Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong

Reference (section label): temp.constr.normal

Link to reflector thread (if any): N/A

Issue description

Consider:

template <auto> constexpr bool B = true;

template <unsigned X0> concept C = B<X0>;
template <unsigned short X1> concept C2 = C<X1>;

template <unsigned X> void f() requires C<X>;  // #1
template <unsigned X> int f() requires C2<X> && true;  // #2

void g() {
  return f<65536>();  // should probably call #1
}
void h() {
  f<0>();  // ambiguous?
}

When forming the normalized constraints, it is unclear how the type of X1 in the definition of C2 affects the parameter mapping. https://wg21.link/temp.constr.normal#1.4 does not seem to address this at all.

There is implementation divergence:
GCC and MSVC reject the call to f from g (resolving to #2) and similarly resolves the call to f from h to #2.
Clang and EDG accept the call to f from g (resolving to #1) and rejects the call to f from h as ambiguous.

Online compiler link: https://godbolt.org/z/hEKaosbWe

Adopting the GCC/MSVC behaviour, which seems to ignore the type of X1 in the definition of C2, seems objectively wrong: 65536u is not a value that C2 accepts.

The Clang and EDG behaviour suggests that the parameter mapping for the B<X0> atomic constraints are different between #1 and #2. Presumably when substituting X from #2 into the normalized constraint for C2, some decoration was included.

Suggested resolution

Introducing some sort of "shadow constraint" that X is a valid template argument for a template parameter declared as unsigned short when normalizing the use of C2 from #2 would reject the call from g but accept the call from h as resolving to #2. This seems to be a sensible result, but leaves none of the surveyed implementations unscathed.

@jensmaurer jensmaurer changed the title [temp.constr.normal] Effect of concept _template-head_s on parameter mappings CWG2975 [temp.constr.normal] Effect of concept _template-head_s on parameter mappings Dec 27, 2024
@jensmaurer
Copy link
Member

CWG2975

@hubert-reinterpretcast
Copy link
Author

CWG2975

Thanks Jens.

Suggested minor issue write-up adjustment:

and select #‌2 as more constraint constrained

@jensmaurer
Copy link
Member

Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants