When compiling for -gnu, winapi statically links to the mingw equivalents of user32.dll and other system libraries that are bundled with winapi itself instead of dynamically linking to the official version in C:\Windows\System32.
To be clear here, user32.dll is part of the OS and is loaded at runtime. Both GNU and MSVC must load the same .dll. If they didn't they would only work on one specific version of Windows
The difference between MSVC and GNU is user32.lib. This is an "import library". It's essentially no more than a list of functions with the name of the DLL that has to be loaded at runtime. The linker uses this information to add to the binary's import table.
This is wrong; the real difference is just that debug symbols are stored in a different format, so you need to use a different debugger than GDB. I usually just use Visual Studio's, as it's actually quite nice in general, but there are plenty to choose from, both first and third-party!
What this comes down to in general is that the whole MinGW toolchain simply does not try to be compatible with the Windows platform's usual formats, ABIs, etc. As its name ("Minimalist GNU for Windows") implies, it is more of a set of shims to get GNU-targeting software running on Windows without too much adjustment.
This means that, for simple things like MessageBoxW in user32.dll, things work out okay thanks to MinGW's import libs, but in the general case you simply can't expect it to be compatible with first or third-party libraries or platform APIs which actually follow the standard platform conventions.
Truly supporting Windows means supporting Windows' formats and ABIs, so Rust's default Windows toolchain is the one that does that.