Repository: dtolnay/cxx (language: rust)

Issue:
Self-move-assign is inconsistent between Vec and Box
Move assigning a rust::Vec to itself does nothing. But for rust::Box it leaves the Box in moved-from state. Ideally we would pick one or the other behavior and apply it consistently.

<br>

https://github.com/dtolnay/cxx/blob/45a1f88bf9e11ea0682f285a8dd353d866ff3cb8/include/cxx.h#L825-L833

<br>

https://github.com/dtolnay/cxx/blob/45a1f88bf9e11ea0682f285a8dd353d866ff3cb8/include/cxx.h#L737-L745


Discussion / hints:
I consider https://ericniebler.com/2017/03/31/post-conditions-on-self-move/ authoritative on this topic. According to it, either behavior is a legal implementation.

Fix patch:
diff --git a/include/cxx.h b/include/cxx.h
index b9749de45..0744f8cb1 100644
--- a/include/cxx.h
+++ b/include/cxx.h
@@ -824,11 +824,9 @@ Vec<T>::~Vec() noexcept {
 
 template <typename T>
 Vec<T> &Vec<T>::operator=(Vec &&other) noexcept {
-  if (this != &other) {
-    this->drop();
-    this->repr = other.repr;
-    new (&other) Vec();
-  }
+  this->drop();
+  this->repr = other.repr;
+  new (&other) Vec();
   return *this;
 }
 
diff --git a/src/cxx.cc b/src/cxx.cc
index fd34e3440..2e4e0a0bb 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -109,11 +109,9 @@ String &String::operator=(const String &other) noexcept {
 }
 
 String &String::operator=(String &&other) noexcept {
-  if (this != &other) {
-    cxxbridge1$string$drop(this);
-    this->repr = other.repr;
-    cxxbridge1$string$new(&other);
-  }
+  cxxbridge1$string$drop(this);
+  this->repr = other.repr;
+  cxxbridge1$string$new(&other);
   return *this;
 }
 
@@ -392,13 +390,11 @@ Error &Error::operator=(const Error &other) {
 }
 
 Error &Error::operator=(Error &&other) noexcept {
-  if (this != &other) {
-    std::exception::operator=(std::move(other));
-    this->msg = other.msg;
-    this->len = other.len;
-    other.msg = nullptr;
-    other.len = 0;
-  }
+  std::exception::operator=(std::move(other));
+  this->msg = other.msg;
+  this->len = other.len;
+  other.msg = nullptr;
+  other.len = 0;
   return *this;
 }
 


Test patch: