microsoft / microsoft/vscode-cpptools

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

Ouverte
#10,568 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

bug Language Service verified Visual Studio
Langage dominant
TypeScript
Étoiles
6.2k
Forks
1.7k
Merge moyen
14 h 46 min
PR mergées (30 j)
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:

  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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Reproduisez le diagnostic avec l’exemple minimal.cpp dans VS Code en utilisant le c_cpp_properties.json fourni et la configuration C++20. Suivez la recherche du promise de la coroutine dans le chemin IntelliSense de l’extension C/C++ ; le travail est terminé lorsque l’exemple ne signale plus d’erreur et résout coroutine_traits avec Outer&.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
cpp
Domaine
devtools
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.