diff --git a/regression-tests/pure2-bugfix-for-out-this-nonconstructor-error.cpp2 b/regression-tests/pure2-bugfix-for-out-this-nonconstructor-error.cpp2 new file mode 100644 index 000000000..6831e3675 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-out-this-nonconstructor-error.cpp2 @@ -0,0 +1,4 @@ + +Machine: @polymorphic_base type = { + operator%: (out this, _: std::string) = {} +} diff --git a/regression-tests/test-results/pure2-bugfix-for-out-this-nonconstructor-error.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-out-this-nonconstructor-error.cpp2.output new file mode 100644 index 000000000..0d5527d6d --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-out-this-nonconstructor-error.cpp2.output @@ -0,0 +1,3 @@ +pure2-bugfix-for-out-this-nonconstructor-error.cpp2... +pure2-bugfix-for-out-this-nonconstructor-error.cpp2(3,16): error: a function with an 'out this' parameter must be a constructor + diff --git a/source/parse.h b/source/parse.h index 9c80447bf..922811b98 100644 --- a/source/parse.h +++ b/source/parse.h @@ -4502,9 +4502,10 @@ auto function_type_node::is_constructor() const (*parameters).ssize() > 0 && (*parameters)[0]->has_name("this") && (*parameters)[0]->direction() == passing_style::out + && my_decl + && my_decl->has_name("operator=") ) { - assert(my_decl && my_decl->has_name("operator=")); return true; } return false; diff --git a/source/sema.h b/source/sema.h index 424261a69..9891913c1 100644 --- a/source/sema.h +++ b/source/sema.h @@ -2086,6 +2086,21 @@ class sema } } + // If the first parameter is 'out this', it must be a constructor. + if ( + !n.is_constructor() + && (*n.parameters).ssize() > 0 + && (*n.parameters)[0]->has_name("this") + && (*n.parameters)[0]->direction() == passing_style::out + ) + { + errors.emplace_back( + n.position(), + "a function with an 'out this' parameter must be a constructor" + ); + return false; + } + return true; }