What happens
A project built with GCC on Linux that imports any member reaching mcpp.plugins (for example rules-qt) shows an error in an editor on every import mcpp.rules.…; line of its build.mcpp:
Module file '…/module-hints/mcpp.rules.qt.pcm' not found
The build itself succeeds.
Why
mcpp::plugins::json::value holds std::vector<std::pair<std::string, value>> members and walks it in an inline get(). clangd reads a GCC project with clang over libstdc++'s std module, and there pair<string, value> is instantiated while value is still incomplete:
type_traits:1539:30: error: incomplete type 'std::pair<std::string, mcpp::plugins::json::value>' used in type trait expression
so mcpp.plugins never compiles and every member that imports it is missing. GCC accepts the code, and so does clang with libc++, which is why CI never saw it: the Linux fixtures build with GCC, the llvm-pinned fixtures and macOS use libc++. Clang with libstdc++ is the one combination no build compiles, and it is the one every editor uses for a GCC project.
Reproduced with mcppls diagnostics build.mcpp (mcpp-language-server 0.0.15) on tests/all-rules-compile: 1 error; 34 of the 37 fixtures with a build.mcpp report it.
Fix
json::value's members become a plain struct member { std::string first; value second; }, with get() defined once both types are complete. Source-compatible: members is used only inside plugins.cppm, and the fields keep their names.
- CI gains the two missing combinations: an [email protected] (libc++) lane, and an editor lane that reads every fixture's
build.mcpp with mcppls and fails on any error.
- docs/plugin-development.md states the rule: plugin code is the C++23 all three accept, with the known differences.