microsoft / microsoft/vscode-cpptools

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

Abierto
#10,568 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug Language Service verified Visual Studio
Lenguaje dominante
TypeScript
Estrellas
6.2k
Forks
1.7k
Merge medio
14 h 46 min
PR fusionados (30 d)
61

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Reproduce el diagnóstico con el ejemplo minimal.cpp en VS Code usando el c_cpp_properties.json proporcionado y la configuración de C++20. Traza la búsqueda del promise de la coroutine en la ruta de IntelliSense de la extensión C/C++; el trabajo estará terminado cuando el ejemplo ya no informe de ningún error y resuelva coroutine_traits con Outer&.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
cpp
Área
devtools
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.