https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119844
Nathaniel Shead <nshead at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic CC| |nshead at gcc dot gnu.org --- Comment #2 from Nathaniel Shead <nshead at gcc dot gnu.org> --- I haven't attempted to fully reproduce, but it appears to me you have something like the following: // user.cpp export module User; export struct User { int value; }; // main.cpp struct User; struct MainWindow { User* u; }; import User; int foo(MainWindow m) { return m.u->value; } $ g++-15 -fmodules -S user.cpp main.cpp main.cpp: In function ‘int foo(MainWindow)’: main.cpp:7:13: error: invalid use of incomplete type ‘struct User’ 7 | return m.u->value; | ^~ main.cpp:1:8: note: forward declaration of ‘struct User’ 1 | struct User; | ^~~~ This error is expected (though the diagnostic could definitely be improved!): 'User' (in main.cpp) and 'User@User' (in user.cpp) are unrelated, distinct types; the former belonging to the global module, and the latter attached to the module 'User'. You can see this by comparing e.g.: // main.cpp struct User; import User; User u; $ g++-15 -fmodules -S user.cpp main.cpp main.cpp:3:1: error: reference to ‘User’ is ambiguous 3 | User u; | ^~~~ In module User, imported at main.cpp:2: user.cpp:2:15: note: candidates are: ‘struct User@User’ 2 | export struct User { | ^~~~ main.cpp:1:8: note: ‘struct User’ 1 | struct User; | ^~~~ To fix the issue, you could defined user.cpp as something like this: // user.cpp export module User; export extern "C++" struct User { int value; }; The 'extern "C++"' ensures that 'User' is declared attached to the global module. I'll leave this PR open for now for the diagnostic issue, however, as I imagine this to be a common mistake, and we should be able to detect this and emit some kind of note pointing to the conflicting type.