Skip to content

fix(cpp1): emit converting assignment from converting constructor #474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
quantity: type = {
value: int = ();
operator=: (out this, val: int) = { value = val; }
}

main: () = {
x := quantity(0);
static_assert(!std::is_assignable_v<decltype((x)), int>);
_ = x;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ widget: final type =
{
v: int;

operator=: (out this, value: int) = { v = value; }
operator=: (implicit out this, value: int) = { v = value; }

operator==: (this, that) -> bool;

Expand Down
2 changes: 1 addition & 1 deletion regression-tests/pure2-types-basics.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ myclass : type = {
print();
}

operator=: (out this, s: std::string) = {
operator=: (implicit out this, s: std::string) = {
this.data = 99;
this.more = s;
std::cout << "myclass: explicit from string\n";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ myclass : type = {
std::cout << "assign - move ";
}

operator=: (out this, x: std::string) = {
operator=: (implicit out this, x: std::string) = {
name = x;
std::cout << "ctor - from string ";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ myclass : type = {
// std::cout << "assign - move ";
// }

operator=: (out this, x: std::string) = {
operator=: (implicit out this, x: std::string) = {
name = x;
std::cout << "ctor - from string ";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ myclass : type = {
std::cout << "assign - move ";
}

operator=: (out this, x: std::string) = {
operator=: (implicit out this, x: std::string) = {
name = x;
std::cout << "ctor - from string ";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ myclass : type = {
std::cout << "assign - move ";
}

operator=: (out this, x: std::string) = {
operator=: (implicit out this, x: std::string) = {
name = x;
std::cout << "ctor - from string ";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ myclass : type = {
// std::cout << "assign - move ";
// }

operator=: (out this, x: std::string) = {
operator=: (implicit out this, x: std::string) = {
name = x;
std::cout << "ctor - from string ";
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

#define CPP2_USE_MODULES Yes

//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"

#line 1 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
class quantity;


//=== Cpp2 type definitions and function declarations ===========================

#line 1 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
class quantity {
private: int value {};
public: explicit quantity(cpp2::in<int> val);

public: quantity(quantity const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(quantity const&) -> void = delete;
#line 4 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
};

auto main() -> int;


//=== Cpp2 function definitions =================================================


#line 3 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
quantity::quantity(cpp2::in<int> val)
: value{ val }
#line 3 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
{}

#line 6 "pure2-bugfix-for-explicit-converting-assignment.cpp2"
auto main() -> int{
auto x {quantity(0)};
static_assert(!(std::is_assignable_v<decltype((x)),int>));
(void) std::move(x);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pure2-bugfix-for-explicit-converting-assignment.cpp2... ok (all Cpp2, passes safety checks)

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class widget final
{
private: int v;

public: explicit widget(cpp2::in<int> value);
public: widget(cpp2::in<int> value);
#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
public: auto operator=(cpp2::in<int> value) -> widget& ;

Expand All @@ -40,13 +40,13 @@ auto main() -> int;

#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
widget::widget(cpp2::in<int> value)
: v{ value }
: v{ value }
#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
{}
#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
auto widget::operator=(cpp2::in<int> value) -> widget& {
v = value;
return *this;
v = value;
return *this;
#line 6 "pure2-defaulted-comparisons-and-final-types.cpp2"
}

Expand Down
2 changes: 1 addition & 1 deletion regression-tests/test-results/pure2-types-basics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class myclass {


#line 13 "pure2-types-basics.cpp2"
public: explicit myclass(cpp2::in<std::string> s);
public: myclass(cpp2::in<std::string> s);

#line 13 "pure2-types-basics.cpp2"
public: auto operator=(cpp2::in<std::string> s) -> myclass& ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ class X {
// Note: A constructor with an 'out' parameter
public: explicit X(cpp2::out<Y> y);

#line 10 "pure2-types-order-independence-and-nesting.cpp2"
public: auto operator=(cpp2::out<Y> y) -> X& ;


#line 34 "pure2-types-order-independence-and-nesting.cpp2"
// X::exx member function description here
Expand All @@ -66,8 +63,6 @@ class Y {
private: X* px;

public: explicit Y(X* x);
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
public: auto operator=(X* x) -> Y& ;

public: auto why(cpp2::in<int> count) const -> void;

Expand Down Expand Up @@ -139,16 +134,6 @@ namespace N {
// then do anything else the constructor wants to do
std::cout << "made a safely initialized cycle\n";
}
#line 10 "pure2-types-order-independence-and-nesting.cpp2"
auto X::operator=(cpp2::out<Y> y) -> X& {
y.construct(&(*this));
py = &y.value();

#line 31 "pure2-types-order-independence-and-nesting.cpp2"
std::cout << "made a safely initialized cycle\n";
return *this;
#line 32 "pure2-types-order-independence-and-nesting.cpp2"
}

#line 35 "pure2-types-order-independence-and-nesting.cpp2"
auto X::exx(cpp2::in<int> count) const -> void{
Expand All @@ -164,12 +149,6 @@ namespace N {
: px{ x }
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
{ }
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
auto Y::operator=(X* x) -> Y& {
px = x;
return *this;
#line 49 "pure2-types-order-independence-and-nesting.cpp2"
}

auto Y::why(cpp2::in<int> count) const -> void {
CPP2_UFCS(exx, (*cpp2::assert_not_null(px)), count + 1); }// use X object from Y
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ class mystruct;
class my_integer {
private: int v;
public: explicit my_integer(cpp2::in<int> val);
#line 4 "pure2-types-ordering-via-meta-functions.cpp2"
public: auto operator=(cpp2::in<int> val) -> my_integer& ;

public: [[nodiscard]] auto operator<=>(my_integer const& that) const -> std::strong_ordering = default;

Expand All @@ -43,8 +41,6 @@ public: [[nodiscard]] auto operator<=>(my_integer const& that) const -> std::str
class case_insensitive_string {
private: std::string v; // case insensitive
public: explicit case_insensitive_string(cpp2::in<std::string> val);
#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
public: auto operator=(cpp2::in<std::string> val) -> case_insensitive_string& ;

public: [[nodiscard]] auto operator<=>(case_insensitive_string const& that) const -> std::weak_ordering = default;

Expand All @@ -56,8 +52,6 @@ public: [[nodiscard]] auto operator<=>(case_insensitive_string const& that) cons
class person_in_family_tree {
private: int dummy_data;
public: explicit person_in_family_tree(cpp2::in<int> parents);
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
public: auto operator=(cpp2::in<int> parents) -> person_in_family_tree& ;

public: [[nodiscard]] auto operator<=>(person_in_family_tree const& that) const -> std::partial_ordering = default;

Expand All @@ -81,38 +75,20 @@ auto main() -> int;
: v{ val }
#line 4 "pure2-types-ordering-via-meta-functions.cpp2"
{}
#line 4 "pure2-types-ordering-via-meta-functions.cpp2"
auto my_integer::operator=(cpp2::in<int> val) -> my_integer& {
v = val;
return *this;
#line 4 "pure2-types-ordering-via-meta-functions.cpp2"
}


#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
case_insensitive_string::case_insensitive_string(cpp2::in<std::string> val)
: v{ val }
#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
{}
#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
auto case_insensitive_string::operator=(cpp2::in<std::string> val) -> case_insensitive_string& {
v = val;
return *this;
#line 9 "pure2-types-ordering-via-meta-functions.cpp2"
}


#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
person_in_family_tree::person_in_family_tree(cpp2::in<int> parents)
: dummy_data{ parents }
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
{}
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
auto person_in_family_tree::operator=(cpp2::in<int> parents) -> person_in_family_tree& {
dummy_data = parents;
return *this;
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
}


#line 21 "pure2-types-ordering-via-meta-functions.cpp2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class myclass {


#line 22 "pure2-types-smf-and-that-1-provide-everything.cpp2"
public: explicit myclass(cpp2::in<std::string> x);
public: myclass(cpp2::in<std::string> x);

#line 22 "pure2-types-smf-and-that-1-provide-everything.cpp2"
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class myclass {
// std::cout << "assign - move ";
// }

public: explicit myclass(cpp2::in<std::string> x);
public: myclass(cpp2::in<std::string> x);

#line 22 "pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp2"
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class myclass {


#line 22 "pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp2"
public: explicit myclass(cpp2::in<std::string> x);
public: myclass(cpp2::in<std::string> x);

#line 22 "pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp2"
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class myclass {


#line 22 "pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp2"
public: explicit myclass(cpp2::in<std::string> x);
public: myclass(cpp2::in<std::string> x);

#line 22 "pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp2"
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class myclass {
// std::cout << "assign - move ";
// }

public: explicit myclass(cpp2::in<std::string> x);
public: myclass(cpp2::in<std::string> x);

#line 22 "pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp2"
public: auto operator=(cpp2::in<std::string> x) -> myclass& ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ class p_widget;
class widget {
private: int val {0};
public: explicit widget(cpp2::in<int> i);
#line 4 "pure2-types-value-types-via-meta-functions.cpp2"
public: auto operator=(cpp2::in<int> i) -> widget& ;

public: [[nodiscard]] auto operator<=>(widget const& that) const -> std::strong_ordering = default;
public: widget(widget const& that);
Expand All @@ -42,8 +40,6 @@ public: explicit widget();
class w_widget {
private: int val {0};
public: explicit w_widget(cpp2::in<int> i);
#line 9 "pure2-types-value-types-via-meta-functions.cpp2"
public: auto operator=(cpp2::in<int> i) -> w_widget& ;

public: [[nodiscard]] auto operator<=>(w_widget const& that) const -> std::weak_ordering = default;
public: w_widget(w_widget const& that);
Expand All @@ -58,8 +54,6 @@ public: explicit w_widget();
class p_widget {
private: int val {0};
public: explicit p_widget(cpp2::in<int> i);
#line 14 "pure2-types-value-types-via-meta-functions.cpp2"
public: auto operator=(cpp2::in<int> i) -> p_widget& ;

public: [[nodiscard]] auto operator<=>(p_widget const& that) const -> std::partial_ordering = default;
public: p_widget(p_widget const& that);
Expand All @@ -86,12 +80,6 @@ template<typename T> auto test() -> void;
: val{ i }
#line 4 "pure2-types-value-types-via-meta-functions.cpp2"
{}
#line 4 "pure2-types-value-types-via-meta-functions.cpp2"
auto widget::operator=(cpp2::in<int> i) -> widget& {
val = i;
return *this;
#line 4 "pure2-types-value-types-via-meta-functions.cpp2"
}


widget::widget(widget const& that)
Expand All @@ -111,12 +99,6 @@ widget::widget(){}
: val{ i }
#line 9 "pure2-types-value-types-via-meta-functions.cpp2"
{}
#line 9 "pure2-types-value-types-via-meta-functions.cpp2"
auto w_widget::operator=(cpp2::in<int> i) -> w_widget& {
val = i;
return *this;
#line 9 "pure2-types-value-types-via-meta-functions.cpp2"
}


w_widget::w_widget(w_widget const& that)
Expand All @@ -136,12 +118,6 @@ w_widget::w_widget(){}
: val{ i }
#line 14 "pure2-types-value-types-via-meta-functions.cpp2"
{}
#line 14 "pure2-types-value-types-via-meta-functions.cpp2"
auto p_widget::operator=(cpp2::in<int> i) -> p_widget& {
val = i;
return *this;
#line 14 "pure2-types-value-types-via-meta-functions.cpp2"
}


p_widget::p_widget(p_widget const& that)
Expand Down
3 changes: 2 additions & 1 deletion source/cppfront.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5464,9 +5464,10 @@ class cppfront
&& !current_functions.back().declared_that_functions.inout_this_in_that
)
||
// A3) This is '(out this, something-other-than-that)'
// A3) This is '(implicit out this, something-other-than-that)'
(
n.is_constructor()
&& n.is_function_with_implicit_this()
&& !n.is_constructor_with_that()
)
)
Expand Down
Loading