Bug 360567

Summary: Wrong parameter info displayed for variadic function templates
Product: [Applications] kdevelop Reporter: Alexander Potashev <aspotashev>
Component: Language Support: CPP (Clang-based)Assignee: kdevelop-bugs-null
Status: RESOLVED FIXED    
Severity: normal CC: kde
Priority: HI    
Version First Reported In: git master   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed/Implemented In: 5.0.0
Sentry Crash Report:

Description Alexander Potashev 2016-03-15 15:55:46 UTC
In the sample code below, pressing Ctrl+Space shows "void print()". "void print()" is just wrong here, these two options should be displayed instead:
 * void print(int a, char b)
 * void print(std::string a, double b)

=====
#include <string>
#include <iostream>

void print_impl(int a, char b)
{
    std::cout << a << b;
}

void print_impl(std::string a, double b)
{
    std::cout << a << b;
}

template <typename ...Args>
void print(Args&& ...args)
{
    print_impl(args...);
    std::cout << std::endl;
}

int main()
{
    print(1, '2');
    print("abc", 1e15);
    return 0;
}

Reproducible: Always
Comment 1 Kevin Funk 2016-03-15 17:23:14 UTC
Related issue, which I just saw:

template<class T>
T *acquire(const QString &name) { return new T; }

Hovering over 'acquire' yields: T* acquire(const QString& T) -> wrong!
Comment 2 Matt Whitlock 2016-06-15 20:32:14 UTC
(In reply to Alexander Potashev from comment #0)
> In the sample code below, pressing Ctrl+Space shows "void print()". "void
> print()" is just wrong here, these two options should be displayed instead:
>  * void print(int a, char b)
>  * void print(std::string a, double b)

Your suggestion is wrong. The compiler is in fact free to instantiate the variadic function template using *any* template parameters whatsoever. It is true that there will be a compilation error for any but two distinct tuples of argument types, but this has no bearing on the parameters with which the template may be instantiated.

What you're asking for is effectively that the contextual assistant should compute the set containing all tuples of argument types that would not result in a compilation error, but this may in fact be an infinite set, and in general there is no way to guess what type tuples might be in the set.

Consider the following addition to your example:

template <typename E>
std::enable_if_t<std::is_enum_v<E>, void> print_impl(E value) {
    std::cout << static_cast<std::underlying_type_t<E>>(value);
}

Now what is the contextual assistant supposed to show when you press Ctrl+Space? Do you expect it to search through every defined type, trying to instantiate the print_impl(E) function template? Do you expect every defined enumerated type to appear in the list of suggestions? That would be pretty impractical.
Comment 3 Kevin Funk 2016-06-17 19:25:36 UTC
No longer considering this as a release blocker.
Comment 4 Milian Wolff 2016-09-08 16:23:43 UTC
In code completion, I see `void print(Args&&...)` being displayed, which seems to be correct. Where do you request code completion to see `void print()` instead? As explained by Matt, showing only the two available options sounds wrong to me.

Kevin, I'll report a new bug for your issue and look into that now.
Comment 5 Alexander Potashev 2016-09-10 10:42:57 UTC
Now I see "void print(Args &&...)".