Description
Title: Converting assignment generated from non-converting constructor.
Description:
Relevant extracts from https://github.com/hsutter/cppfront/wiki/Cpp2:-operator=,-this-&-that
always talk about generating converting assignment from a converting constructor,
but cppfront
currently generate converting assignment from an explicit constructor.
implicit
: On a two-parameteroperator=
function, writingoperator=: (implicit out this, /*...*/)
defines a conversion function that can be used to perform implicit conversions to this type.
operator=
is the generalized name for all value-setting functions, including the six combinations of { copy, move, converting } x { constructors, assignment operators }.Note: The concept of a converting assignment operator is first-class in Cpp2, and makes this 3x2 matrix of options symmetric. In Cpp1, it's common to write a converting constructor from some other type, but not an assignment operator from that other type, which leads to asymmetries like
mytype var = other;
working butvar = other;
not working.
- (A)ssignment, A1, A2, A3: If you write a copy or move or converting constructor, but not a corresponding copy or move or converting assignment operator, the latter is generated.
Note: Generating
inout this
(assignment) fromout this
also generates converting assignment from converting construction, which is a new thing. Today in Cpp1, if you write a converting constructor from another typeX
, you may or may not write the corresponding assignment fromX
; in Cpp2 you will get that by default, and it sets the object to the same state as the converting constructor fromX
does.
Minimal reproducer (https://cpp2.godbolt.org/z/zzK9qc4Gx):
quantity: type = {
value: int = ();
operator=: (out this, val: int) = { value = val; }
}
main: () = {
x := quantity(0);
x = 1;
}
Commands:
cppfront -clean-cpp1 main.cpp2
clang++17 -std=c++2b -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -I . main.cpp
Expected result:
An error at:
x = 1;
Actual result and error:
Cpp2 lowered to Cpp1.
#include "cpp2util.h"
class quantity;
class quantity {
private: int value {};
public: explicit quantity(cpp2::in<int> val);
public: auto operator=(cpp2::in<int> val) -> quantity& ;
public: quantity(quantity const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(quantity const&) -> void = delete;
};
auto main() -> int;
quantity::quantity(cpp2::in<int> val)
: value{ val }
{}
auto quantity::operator=(cpp2::in<int> val) -> quantity& {
value = val;
return *this;
}
auto main() -> int{
auto x {quantity(0)};
x = 1;
}
Output:
Program returned: 0