microsoft / microsoft/vscode-cpptools
Wrong lookup of promise type with std::coroutine_traits and non-static member functions
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.2k
- Forks
- 1.7k
- Avg merge
- 14h 46m
- Merged PRs (30d)
- 61
Description
Environment
- OS and Version: Windows 10, 10.0.19044
- VS Code Version: 1.75.1 (user setup)
- C/C++ Extension Version: 1.14.3
- If using SSH remote, specify OS of remote machine: Debian 11/bullseye
Bug Summary and Steps to Reproduce
Bug Summary:
The C/C++ extension shows an error for coroutines implemented as non-static member functions when using the std::coroutine_traits to define the promise type. Consider the following minimal example:
#include <coroutine>
struct Resumable {
std::coroutine_handle<> m_handle;
};
struct my_promise_type {
bool m_ready = false;
~my_promise_type() { }
Resumable get_return_object() { return {.m_handle = std::coroutine_handle<my_promise_type>::from_promise(*this)}; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() { }
void return_value(bool value) { m_ready = value; }
};
class Outer;
namespace std {
template<typename... ARGS>
struct coroutine_traits<Resumable, Outer &, ARGS...>{
using promise_type = my_promise_type;
};
}
class Outer {
public:
Resumable coroutine() { co_return true; }
};
Outer c;
int main(){
auto coro = c.coroutine();
coro.m_handle.resume();
}
The example can be compiled with the command line
g++ -g -o minimal -fcoroutines -std=gnu++20 -O3 minimal.cpp
In this case, we define the promise_type of the Resumable struct using std::coroutine_traits. The documentation states that for coroutines defined as non-static member functions. ARGS must include the implicit object parameter, hence, struct coroutine_traits includes Outer & in the template parameter list.
The extension, however, shows the following error for the coroutine Outer::coroutine(), expecting the second parameter to be of type Outer * instead of the correct Outer &:
class "std::__n4861::coroutine_traits<Resumable, Outer *>" has no member "promise_type "C/C++(135)
Steps to reproduce:
- Open a file with the above contents in VS Code and the C/C++ extension installed as
minimal.cpp. - See error for Outer::coroutine()
Expected behavior:
The lookup for promise_type is done via std::__n4861::coroutine_traits<Resumable, Outer &>::promise_type instead of std::__n4861::coroutine_traits<Resumable, Outer *>.
Configuration and Logs
Contents of c_cpp_properties.json:
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/g++",
"cStandard": "c17",
"intelliSenseMode": "linux-gcc-x64",
"cppStandard": "c++20"
}
],
"version": 4
}
Log Diagnostics:
-------- Diagnostics - 2/22/2023, 12:35:57 PM
Version: 1.14.3
Current Configuration:
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/g++",
"cStandard": "c17",
"intelliSenseMode": "linux-gcc-x64",
"cppStandard": "c++20",
"compilerPathIsExplicit": true,
"cStandardIsExplicit": true,
"cppStandardIsExplicit": true,
"intelliSenseModeIsExplicit": true
}
Translation Unit Mappings:
[ [...]/minimal.cpp ]:
[...]/minimal.cpp
Translation Unit Configurations:
[ [...]/minimal.cpp ]:
Process ID: 212752
Memory Usage: 278 MB
Compiler Path: /usr/bin/g++
Includes:
/usr/include/c++/10
/usr/include/x86_64-linux-gnu/c++/10
/usr/include/c++/10/backward
/usr/lib/gcc/x86_64-linux-gnu/10/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
Standard Version: c++20
IntelliSense Mode: linux-gcc-x64
Other Flags:
--g++
--gnu_version=100201
Total Memory Usage: 278 MB
------- Workspace parsing diagnostics -------
Number of files discovered (not excluded): 7245
Language server log:
willSaveWaitUntil: 0ms
LSP: cpptools/fileChanged: file:///[...]/minimal.cpp
LSP: textDocument/didSave: file:///[...]/minimal.cpp
tag parsing file: /[...]/minimal.cpp
idle loop: reparsing the active document
Checking for syntax errors: /[...]/minimal.cpp
Queueing IntelliSense update for files in translation unit of: /[...]/minimal.cpp
Error squiggle count: 1
Update IntelliSense time (sec): 0.255
LSP: cpptools/getSemanticTokens: file:///[...]/minimal.cpp (id: 8551)
LSP: cpptools/getFoldingRanges: file:///[...]/minimal.cpp (id: 8552)
LSP: cpptools/getCodeActions: file:///[...]/minimal.cpp (id: 8553)
Other Extensions
- Remote - SSH
- Remote Explorer
- CMake
- CMake Tools
Additional context
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the diagnostic with the minimal.cpp example in VS Code using the supplied c_cpp_properties.json and C++20 configuration. Trace the coroutine promise lookup in the C/C++ extension's IntelliSense path; done means the example no longer reports an error and resolves coroutine_traits with Outer&.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100