<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/56556>56556</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            clang error when partial specialization with a single template parameter
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          TwinKleS-C
      </td>
    </tr>
</table>

<pre>
    I define an adapter class Adapter and two template classes A<...>, B<...>, when I partially specialize Adapter for A and B, for some consideration, I use the requires clause instead of traditional way (like this: template <typename T1> struct Adapter<A<T1>> {...}), for example:
```cpp
// partial specialization for A<...>
template <typename TType> requires true
        && IsA<TType>
struct Adapter<TType> {
        static auto fun (
        ) -> void {
                std::cout << "A" << std::endl;
                return;
        }
};
```
I used msvc, gcc, and clang to test this code. When I only partially specialize for A, all three can be successfully compiled, but if I perform partial specialization for A and B at the same time, both msvc and gcc can be successful. But clang doesn't allow this code, it tells me there are ambiguous partial specializations of 'Adapter<A<int>>' and 'Adapter<B<int>>'
```
y.cpp:65:2: error: ambiguous partial specializations of 'Adapter<A<int>>'
        Adapter<A<int>>::fun(); // print : A
        ^
y.cpp:41:8: note: partial specialization matches [with TType = A<int>]
struct Adapter<TType> {
       ^
y.cpp:52:8: note: partial specialization matches [with TType = A<int>]
struct Adapter<TType> {
       ^
1 error generated.
```

To circumvent this error, I need to add additional constraints to the requires clause to make clang allow my code, like this:
```cpp
// partial specialization for A<...>
template <typename TType> requires true
        && IsA<TType>
        && std::is_base_of_v<A<typename TType::Value>, TType> // additional constraints
struct Adapter<TType> {
        static auto fun (
        ) -> void {
                std::cout << "A" << std::endl;
                return;
        }
};
```
Is this a bug?

clang version:
```
Ubuntu clang version 15.0.0-++20220627042157+655dc02cb023-1~exp1~20220627042241.261
Target: x86_64-pc-linux-gnu
Thread model: posix
```

Here is the complete test code:
```cpp
#include <iostream>

// declare a value
template <typename It>
inline constexpr auto declare (
) -> It;

// check a type is template's instance or not
template <typename It, template <typename> typename Template>
concept IsTemplateInstanceOfT = requires {
        { [] <typename T1> (Template<T1> &) {}(declare<It &>()) };
};

// class A
template <typename TValue>
struct A {
        using Value = TValue;
};

// class B
template <typename TValue>
struct B {
        using Value = TValue;
};

// true if It is A<...>
template <typename It>
concept IsA = IsTemplateInstanceOfT<It, A>;

// true if It is B<...>
template <typename It>
concept IsB = IsTemplateInstanceOfT<It, B>;

// template
template <typename TType>
struct Adapter;

// partial specialization for A<...>
template <typename TType> requires true
        && IsA<TType>
        && std::is_base_of_v<A<typename TType::Value>, TType> // additional constraints
struct Adapter<TType> {
        static auto fun (
        ) -> void {
                std::cout << "A" << std::endl;
                return;
        }
};

// partial specialization for B<...>
template <typename TType> requires true
        && IsB<TType>
        && std::is_base_of_v<B<typename TType::Value>, TType> // additional constraints
struct Adapter<TType> {
        static auto fun (
        ) -> void {
                std::cout << "B" << std::endl;
                return;
        }
};

// test
auto main (
) -> int {
        std::cout << "A<int> is A ? " << IsA<A<int>> << std::endl; // print : A<int> is A ? 1
        std::cout << "B<int> is A ? " << IsA<B<int>> << std::endl; // print : B<int> is A ? 0
        Adapter<A<int>>::fun(); // print : A
        Adapter<B<int>>::fun(); // print : B
        return 0;
}


```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWE1v4zYQ_TXyhbAgS5YdH3ywkg1q9NBD0_YY0NLYZpf6KEnZSX99Z0jJkjZy1rvbAtuigRNLIjnzhvPecJRdmb2utyyDvSiA8YLxjFcGFEsl15ptmjteZMycS2YgryQ34IYBJ3jRve_7XvTBC-9ZMrg7H6FgW1ZxZQSX8pXpClK8En_CxfC-VGxjzSe0hG51maP9stAiA8WNKAsa2bJaAzNHYAr-qIVC34iBnolCG-AZK_fMKJ4JWsElO_NX5oV3UnykZUJ70aaDjzjNawUFR1dPM8TLtFF1alpcOE6R2SEa9ZYJxbV88MJVixNeOFoDtOsFD16w8RaB-6RV1TwJH_HTbkAXvg3Khd5tmF0xDvAJrwjFJXLECo2LAPEs8MO22iJu5rrRN0FdTGFAFwPaIKCU8dqUbF8XtGs94ys2pQWnUmSDVXZhRtFHm7SsDUHGD64OMfCwvb3MgSKTXjRYr8DUqhg8xB1213hxed5urLu1TMhYrk8ppeKQ2i-iEBKiODBDNNXGJh15lIHPfnNMLAsk4SgdXS7IjJS4UAEyEMWwA6brNAWt9zWtSMu8EhIymrnDkMWe-A0Kl-fvptkxnHFjGawpq0bkYO2U5miDsXMwmreefZagMxddVoJGQSwNQS3PXZRkS6B9kFKz3EpFoaLpN9-JQ13W-gpETdJBk0Pui8I48uOIhTaYkXwyYzRTrz5JIdosYvwTkgBBqVLRxbdjci5Y83NtnqUekpo4jdKNEtaKUuEkRlA2Q0te_GGIfo5FYHNHM4vSkNyvZTrnJj2iOr04OQtMqhUbunhgPUzxw83SvAYoDr8TQDOXT3aAgio1ZP4oDdzfp5KlQqV1foKiEadjgy3uBaCkUbk8y-i3LeJ0DGBRR6ja6nqk_OPjnH-ERh5OFPnrRRL9-v_d1ulu9FIuhX7ecQ3P5f751LD6U0c07Vcua2jO2y5hLp7xffwvnwza8YpjcT540WOffo4eJ1CaGoo3XHC3v-zqwtRsMJfNYj_wg6kXYoeShEEYBotwGczDWbzEB4s4ztIgTHdBGE1n3vIDvFT01ZsYzmd-uJg1MuDqAIZE-3K3eF7Mp1U6laKoX6aHom6m4PmD_UyODJZW3aUWL-8o6wcq9EJbddAJJQGJaY9AK4L3eB-JIpV1ZnksSiQF8LzHyp44MsBdocOEnSzlrstgay4WRCGprbTsw31RjkmtqY5NLZVoaTLiHKtY-hFdkw8baeMXjwFt-z9epMBQp1gQ30eGMhkbIuedvFrrbRiIP4XKoHTboW3j86f9k62nF8UPdLBMqPRihR3pNzH4zs99-2xBW0E2qNO8azYKx7fGDpLO7TlmZ_V00L8ebJzr4t8rWpcKMqgLg0BqLVAPdqKNtl1zm_fki70nf4t3Kr62QzNEmZsqeI-6Xc431uto7m1miFMb22t8HkXy1SiSG1Ak11G0VPv86TV-PowZ_f-8_Nedlzem7yaa3pq-5CvSl_w30pf8g-mjA949sHhzjHbkRLUvOYMQrxGtfSGwxRJHHlkPvBPh4NXqWlxjL1hvbc8-iyi5BVHydYjGbF9aqtW3v0sOjCRfaqTLluMFQusfdn0qDBu7SbaOslW04hMjjIS162PdO5r9Z9wVyduXQ87onJXQ9Uc4G-WHQUxqJddHYyr7EmXhHnBJvfOx3cQbKU_t17RS5e-Q4nH0KLSuQeNFjD3yYnJcrwI-n6fxHn9mPOMAPAjusiVfzHm6D3bRRPIdSL2mnikMCzgzawKvsYWaiLVtqZezeLaK5vPY3-3icBXeRek-jFfz1dybB4AqkD7h8Et1mKi1hYQvAxoHpdBGd4PYmogDvnauXYs2QRUdS7V-OoviRwk_T-8n1vvaov8LO6Mq6w">