Open
Description
Title: Postfix operators of member assignment ignored.
Minimal reproducer (https://cpp2.godbolt.org/z/b8EEa6jnf):
spanning_vector: <T> type = {
view: * std::vector<T>;
operator=: (out this, inout v: std::vector<T>) = view = v&;
operator=: (inout this, inout v: std::vector<T>) = view* = v;
}
main: () = {
vec1: std::vector<i32> = (0, 1, 2);
vec2: std::vector<i32> = (3, 4, 5, 6, 7);
view: spanning_vector = vec1;
view = vec2;
assert(vec1 == vec2);
}
Commands:
cppfront main.cpp2
clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -I . main.cpp
Expected result:
- An error telling me to first discard the member-wise assignment with
view = _;
, or *view = v;
(for the assignment to Just Work [BUG] move-assignment operators defaulting to memberwise semantics makes it impossible to cleanup old value #475 (comment)).
Actual result and error: view = v;
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
template<typename T> class spanning_vector;
//=== Cpp2 type definitions and function declarations ===========================
template<typename T> class spanning_vector {
private: std::vector<T>* view;
public: explicit spanning_vector(std::vector<T>& v);
public: auto operator=(std::vector<T>& v) -> spanning_vector& ;
public: spanning_vector(spanning_vector const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(spanning_vector const&) -> void = delete;
};
auto main() -> int;
//=== Cpp2 function definitions =================================================
template <typename T> spanning_vector<T>::spanning_vector(std::vector<T>& v)
: view{ &v }
{ }
template <typename T> auto spanning_vector<T>::operator=(std::vector<T>& v) -> spanning_vector& {
view = v;
return *this;
}
auto main() -> int{
std::vector<cpp2::i32> vec1 {0, 1, 2};
std::vector<cpp2::i32> vec2 {3, 4, 5, 6, 7};
spanning_vector view {vec1};
view = vec2;
cpp2::Default.expects(std::move(vec1) == std::move(vec2), "");
}
Output:
main.cpp2:5:61: error: assigning to 'std::vector<int> *' from incompatible type 'std::vector<int>'; take the address with &
5 | view = v;
| ^
| &
main.cpp2:10:26: note: in instantiation of member function 'spanning_vector<int>::operator=' requested here
10 | view = vec2;
| ^
1 error generated.
See also:
-
*view = v;
(for the assignment to Just Work [BUG] move-assignment operators defaulting to memberwise semantics makes it impossible to cleanup old value #475 (comment)).
- Origin of the example: [BUG] Permit
operator=
within this
(via function metafunction@proxy
) #452 (comment).