https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686
--- Comment #3 from Steven Sun <StevenSun2021 at hotmail dot com> --- @W E Brown: I got your idea. So are all uses like this ill-formed? This seems unexpected for me. I would expect the complete specialization is full specialization for both primary templates. I also find facts that support your idea: If I modify the full specialization to -------------------- template <> void func<int&&> (int&& arg){} -------------------- It compiles. See https://godbolt.org/z/fh9Mx7Krr If I modify the full specialization to -------------------- template <> void func<int> (int&& arg){} -------------------- It produce the same ICE output as comment 1. See https://godbolt.org/z/eMa5YcrrE It looks like the compiler doesn't knows which primary template to specialize. I look up in the C++20 standard, and did not find anything about 2 primary templates exists. The code in Comment 1 compiles for g++ 6.1 to 9.3, then breaks since 10.1 (all under -std=c++17 -fconcepts). In conclusion, this makes sences but I didn't see that coming. Anyway, I think a possible improvement is make ICE to an error of "ambigous full specialization". Or even better, a change in C++23 standard.