Skip to content

Unexpected behavior in deduction of nested templates with template template parameters (inconsistent with GCC, MSVC) #81577

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

Open
13steinj opened this issue Feb 13, 2024 · 4 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@13steinj
Copy link

I don't have enough practice with standard-ese to express myself any better than that, unfortunately. Define EVEN_WORSE or ALTERNATIVE_EVEN_WORSE for a different, but seemingly related, inconsistency. Define FIXED to fix the original issue, and "fix" the "even worse" inconsistencies (successful compile, unexpectedly).

I'm happy to provide the motivating example, it's just larger. A whole load of transitional layers from one set of types to another.

Reduced Example
template<typename>
struct Wrapper;

template<template<typename> typename, typename T>
using ComposedWrapper = Wrapper<T>;

template<typename...>
struct mp_list;

template<typename>
struct converter_impl;

template<typename T>
using converter = converter_impl<T>::type;

template<
#if !defined(EVEN_WORSE)
    template<typename> typename Wrapper,
#endif
    typename T
>
struct converter_impl<mp_list<Wrapper<T>>> {
    using type = void;
};

template<typename T>
struct converter_impl<ComposedWrapper<Wrapper, T>> {
    using type = converter<T>;
};

#if defined(__clang__) && defined(FIXED)

template<typename T>
struct converter_impl<ComposedWrapper<Wrapper, mp_list<T>>> {
    using type = int;
};

#endif

template<typename>
concept valid = true;

static_assert(valid<converter<ComposedWrapper<Wrapper,
#if !defined(ALTERNATIVE_EVEN_WORSE)
    mp_list<
#endif
        mp_list<int>
#if !defined(ALTERNATIVE_EVEN_WORSE)
    >
#endif
>>>);
@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels Feb 13, 2024
@llvmbot
Copy link
Member

llvmbot commented Feb 13, 2024

@llvm/issue-subscribers-clang-frontend

Author: None (13steinj)

I don't have enough practice with standard-ese to express myself any better than that, unfortunately. Define `EVEN_WORSE` or `ALTERNATIVE_EVEN_WORSE` for a different, but seemingly related, inconsistency. Define `FIXED` to fix the original issue, and "fix" the "even worse" inconsistencies (successful compile, unexpectedly).

I'm happy to provide the motivating example, it's just larger. A whole load of transitional layers from one set of types to another.

<details>
<summary><a href="https://gcc.godbolt.org/z/Whqfnjv49"&gt;Reduced Example</href></summary>

template&lt;typename&gt;
struct Wrapper;

template&lt;template&lt;typename&gt; typename, typename T&gt;
using ComposedWrapper = Wrapper&lt;T&gt;;

template&lt;typename...&gt;
struct mp_list;

template&lt;typename&gt;
struct converter_impl;

template&lt;typename T&gt;
using converter = converter_impl&lt;T&gt;::type;

template&lt;
#if !defined(EVEN_WORSE)
    template&lt;typename&gt; typename Wrapper,
#endif
    typename T
&gt;
struct converter_impl&lt;mp_list&lt;Wrapper&lt;T&gt;&gt;&gt; {
    using type = void;
};

template&lt;typename T&gt;
struct converter_impl&lt;ComposedWrapper&lt;Wrapper, T&gt;&gt; {
    using type = converter&lt;T&gt;;
};

#if defined(__clang__) &amp;&amp; defined(FIXED)

template&lt;typename T&gt;
struct converter_impl&lt;ComposedWrapper&lt;Wrapper, mp_list&lt;T&gt;&gt;&gt; {
    using type = int;
};

#endif

template&lt;typename&gt;
concept valid = true;

static_assert(valid&lt;converter&lt;ComposedWrapper&lt;Wrapper,
#if !defined(ALTERNATIVE_EVEN_WORSE)
    mp_list&lt;
#endif
        mp_list&lt;int&gt;
#if !defined(ALTERNATIVE_EVEN_WORSE)
    &gt;
#endif
&gt;&gt;&gt;);

</details>

@13steinj
Copy link
Author

This might be a variation of #65843

@shafik
Copy link
Collaborator

shafik commented Feb 15, 2024

I believe this is IFNDR, it depends on how aggressively the compiler instantiates and I believe is allowed to be more aggressive here.

Also see: #59966 (comment)

CC @erichkeane @cor3ntin

@13steinj
Copy link
Author

13steinj commented Feb 15, 2024

I'm a bit confused in that the issue appears to be related to incomplete types. Yes, I'm using some incomplete types here, but this is just the reduced example. The larger example the types used in converter were all boost::mpll or boost::mp11 types that were not incomplete. Completing the incomplete types in the example does not resolve the issue.

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"
Projects
None yet
Development

No branches or pull requests

4 participants