Skip to content

[BUG] The meaning of operator= with multiple non-this parameters #451

Closed as not planned
@JohelEGP

Description

@JohelEGP

Title: The meaning of operator= with multiple non-this parameters.

Description:

An operator= with multiple non-this parameters
doesn't work with non definite first assignment.

Looking at #449, it seems like we expect it to work.
I think that is consistent with https://github.com/hsutter/cppfront/wiki/Cpp2:-operator=,-this-&-that#misc-notes's

More generally, writing = always invokes an operator= (in fact for a Cpp2-authored type, and semantically for a Cpp1-authored type). This avoids the Cpp1 inconsistency that "writing = calls operator=, except when it doesn't" (such as in a Cpp1 variable initialization). Conversely, operator= is always invoked by =.

Besides #449, further integration is also the objective of #368, and perhaps also of #409.
#321 is another such issue, but = (...) is intended for an std::initializer_list parameter.

Minimal reproducer (https://cpp2.godbolt.org/z/q1WvTaEnM):

t: type = {
  // operator=: (out this, x, y) = { }
  operator=: (inout this, x, y) = { }
}
main: () = { }
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:

As you can see below, cppfront currently lowers to
a Cpp1 assignment operator with multiple arguments, which is ill-formed.

In order for this to work, it'd have to be lowered to a Cpp1 cpp2_assign overload
(inspired from the C++ standard library containers assign member functions):

  public: auto cpp2_assign(auto const& x, auto const& y) -> t& ;

Here's where it gets contentious with #321.
Cpp2 a = (x, y) would have to choose between
Cpp1 a = {x, y} and
Cpp1 a.cpp2_assign(x, y).

Actual result and error:

  public: auto operator=(auto const& x, auto const& y) -> t& ;
build/_cppfront/main.cpp:9:16: error: overloaded 'operator=' must be a binary operator (has 3 parameters)
  public: auto operator=(auto const& x, auto const& y) -> t& ;
               ^
Cpp2 lowered to Cpp1.
#include "cpp2util.h"

class t;
  
class t {
  // operator=: (out this, x, y) = { }
  public: auto operator=(auto const& x, auto const& y) -> t& ;

  public: t() = default;
  public: t(t const&) = delete; /* No 'that' constructor, suppress copy */
  public: auto operator=(t const&) -> void = delete;
};
auto main() -> int;

  auto t::operator=(auto const& x, auto const& y) -> t& {
                                    return *this;
  }

auto main() -> int{}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions