Skip to content

Wrong lookup of promise type with std::coroutine_traits and non-static member functions #10568

Open

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:

  1. Open a file with the above contents in VS Code and the C/C++ extension installed as minimal.cpp.
  2. 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions