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

[16 regression] Partial specialization with constrained parameters declared in wrong order is suddenly "not more specialized" #58896

Closed
HolyBlackCat opened this issue Nov 9, 2022 · 17 comments
Assignees
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts regression

Comments

@HolyBlackCat
Copy link

HolyBlackCat commented Nov 9, 2022

template <typename A, typename B>
concept C = sizeof(A) > sizeof(B);

template <typename A, typename B>
struct X {};

template <typename B, C<B> A>
struct X<A, B> {};

Clang 15 accepts this, but trunk says:

<source>:8:8: error: class template partial specialization is not more specialized than the primary template [-Winvalid-partial-specialization]
struct X<A, B> {};
       ^
<source>:5:8: note: template is declared here
struct X {};
       ^

Desugaring this to template <typename B, typename A> requires C<A, B> has no effect, the error is still there.

But further fixing the parameter order to template <typename A, typename B> requires C<A, B> fixes the error.

Tested at trunk commit 129177eaf0ecb202a6f44ab8d23ad51fe00d15f6 with -std=c++20.

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels Nov 9, 2022
@llvmbot
Copy link
Member

llvmbot commented Nov 9, 2022

@llvm/issue-subscribers-clang-frontend

@erichkeane
Copy link
Collaborator

Started looking into this one again. It is strange that if the parameters passed as the partial specialization are reversed, it 'works fine'. That is: struct X<A, B> vs struct X<B, A>. It isn't clear to me what is going on, but it seems to be failing the TemplateArgumentListsAreEqualcheck inSemaTemplateDeduction.cpp's getMoreSpecialized` (~5647). I'm not sure why that is, but I'll keep looking.

@erichkeane
Copy link
Collaborator

I see the code in this area was extensively refactored/rewritten by @yuanfang-chen

@erichkeane
Copy link
Collaborator

I note that the problem really is that we identify the args as 'equal' by doing profiling (SemaTemplateDeduction.cpp:5544), BUT because of the reversing, 1 canonical is "depth = 0, index = 1" and the other is "depth = 0, Index = 0". Which is why reversing them works. @yuanfang-chen : Is this something you can take a look at?

@yuanfang-chen
Copy link
Collaborator

Sure. I'll take a look.

@yuanfang-chen yuanfang-chen self-assigned this Feb 17, 2023
@erichkeane
Copy link
Collaborator

Note @yuanfang-chen : I'm on the fence as to whether this is related to: #60749. I am beginning to lean again to this having a similar cause.

@yuanfang-chen
Copy link
Collaborator

Actually, the partial specialization without constraint C works as Clang 15(https://godbolt.org/z/esYcKf971):

template <typename A, typename B>
struct X<B, A> {};

The only difference in Clang 16 is how constraint C is used in partial ordering. For the original test case, partial ordering bail out at https://eel.is/c++draft/temp.func.order#6.2.2 (specifically if the function parameters that positionally correspond between the two templates are not of the same type, X<B,A> vs X<A,B>), but constraint C only kicks in at https://eel.is/c++draft/temp.func.order#6.4

@erichkeane
Copy link
Collaborator

Actually, the partial specialization without constraint C works as Clang 15(https://godbolt.org/z/esYcKf971):

template <typename A, typename B>
struct X<B, A> {};

The only difference in Clang 16 is how constraint C is used in partial ordering. For the original test case, partial ordering bail out at https://eel.is/c++draft/temp.func.order#6.2.2 (specifically if the function parameters that positionally correspond between the two templates are not of the same type, X<B,A> vs X<A,B>), but constraint C only kicks in at https://eel.is/c++draft/temp.func.order#6.4

Perhaps I'm being a little dense here... but are you saying Clang16 is 'correct' here and that this example should be rejected?

@yuanfang-chen
Copy link
Collaborator

Perhaps I'm being a little dense here... but are you saying Clang16 is 'correct' here and that this example should be rejected?

Sorry, I wasn't clear. Yes, I meant Clang16 is correct.

@erichkeane
Copy link
Collaborator

@hubert-reinterpretcast : I think I agree with Yuanfang's reading here after spending a bit of this morning on it. Can you confirm, and we can close this as 'not a defect'?

@erichkeane
Copy link
Collaborator

@yuanfang-chen : If you wouldn't mind, a commit explaining this and adding a test (if one doesn't already exist!) to make sure we're enforcing this would be greatly appreciated.

@yuanfang-chen
Copy link
Collaborator

@yuanfang-chen : If you wouldn't mind, a commit explaining this and adding a test (if one doesn't already exist!) to make sure we're enforcing this would be greatly appreciated.

Sure. Then I found

template<C T, C V> struct Y4; // expected-note {{template is declared here}}
template<D T, C V> struct Y4<V, T>; // expected-error {{class template partial specialization is not more specialized than the primary template}}
which seems cover the above test case.

@erichkeane
Copy link
Collaborator

That test works, but would still like a comment on that one with the ref to temp.func.order next to it.

@yuanfang-chen
Copy link
Collaborator

That test works, but would still like a comment on that one with the ref to temp.func.order next to it.

How about

// Per [temp.func.order]p6.2.2, specifically "if the function parameters that
// positionally correspond between the two templates are not of the same type",
// this partial specialization does not work.
// See https://github.com/llvm/llvm-project/issues/58896

@erichkeane
Copy link
Collaborator

SGTM! Would appreciate that!

@yuanfang-chen
Copy link
Collaborator

erichkeane

No problem. Sent 3e00f24

@erichkeane
Copy link
Collaborator

I think I'm convinced, so unless Hubert says otherwise (and reopens this), I'm just going to close it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts regression
Projects
Status: Done
Development

No branches or pull requests

8 participants