microsoft / microsoft/vscode-cpptools

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

Offen
#10,568 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug Language Service verified Visual Studio
Vorherrschende Sprache
TypeScript
Sterne
6.2k
Forks
1.7k
Ø Merge
14 Std. 46 Min.
Gemergte PRs (30 T.)
61

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Reproduziere die Diagnose mit dem minimal.cpp-Beispiel in VS Code unter Verwendung der bereitgestellten c_cpp_properties.json und der C++20-Konfiguration. Verfolge die Suche nach dem Coroutine-Promise im IntelliSense-Pfad der C/C++-Erweiterung; als abgeschlossen gilt die Arbeit, wenn das Beispiel keinen Fehler mehr meldet und coroutine_traits mit Outer& auflöst.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
cpp
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.