https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114110
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Keywords| |diagnostic Last reconfirmed| |2024-02-26 --- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Frank Heckenbach from comment #0) > The actual problem here is that the move-constructor was deleted because a No, the move constructor is simply *not declared*. If it had been deleted then it would have been selected by overload resolution as a better match and you'd get an error telling you the move constructor was deleted. The distinction is important (and frequently misunderstood). > destructor was declared, but gcc does not mention this at all (instead of, > or at least in addition to, why the copy-constructor was deleted). That would be better. If move construction fails, it's unlikely that the type is copyable-but-not-movable, because such types are stupid and should not exist. So then the question is whether it's supposed to be completely non-copyable and non-movable, or whether the class has a bug that we can help to diagnose. The right heuristic is probably: If initializing T from a T rvalue is ill-formed, check whether an implicit move constructor was suppressed. If it was, print a fix-it suggesting: S(S&&) = default; Reduced: struct MO { MO(MO&&) { } }; struct S { ~S() = default; MO m; }; S&& f(); S s = f(); This prints: mo.cc:7:9: error: use of deleted function ‘S::S(const S&)’ 7 | S s = f(); | ^ mo.cc:2:8: note: ‘S::S(const S&)’ is implicitly deleted because the default definition would be ill-formed: 2 | struct S { | ^ mo.cc:2:8: error: use of deleted function ‘constexpr MO::MO(const MO&)’ mo.cc:1:8: note: ‘constexpr MO::MO(const MO&)’ is implicitly declared as deleted because ‘MO’ declares a move constructor or move assignment operator 1 | struct MO { | ^~ I think it would be better to print: mo.cc:7:9: error: use of deleted function ‘S::S(const S&)’ 7 | S s = f(); | ^ mo.cc:5:4: note: ‘S::S(S&&)’ is not implicitly declared 'S' declares a destructor: 2 | ~S() = default; | ^~ mo.cc:5:4: note: add a user-declared move constructor to fix this: ~S() = default; ^ S(S&&) = default; mo.cc:2:8: note: ‘S::S(const S&)’ is implicitly deleted because the default definition would be ill-formed: 2 | struct S { | ^ mo.cc:2:8: error: use of deleted function ‘constexpr MO::MO(const MO&)’ mo.cc:1:8: note: ‘constexpr MO::MO(const MO&)’ is implicitly declared as deleted because ‘MO’ declares a move constructor or move assignment operator 1 | struct MO { | ^~ N.B. I don't think showing the locations "struct S {" and "struct MO {" for the implicitly deleted copy constructors is useful, but I think I've said that in another bug report somewhere.