hsutter / cppfront

A personal experimental C++ Syntax 2 -> Syntax 1 compiler
Other
5.52k stars 246 forks source link

[BUG] Can't declare idiomatic `swap` #507

Open JohelEGP opened 1 year ago

JohelEGP commented 1 year ago

Title: Can't declare idiomatic swap.

Description:

See https://github.com/hsutter/cppfront/issues/345#issuecomment-1585417506. There's code to make swap noexcept by default, but that can only be in or move, and not inout as required by swap.

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

t: type = {
  swap: (inout this, inout that) = { }
}
main: () = { }

Commands: ```bash cppfront main.cpp2 clang++17 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -I . main.cpp ```

Expected result:

An idiomatic swap.

Actual result and error:

Output:

main.cpp2(2,32): error: a 'that' parameter must be in or move
ntrel commented 1 year ago

I started working on this, but I haven't figured out yet why calling swap generates the CPP2_UFCS macro instead of calling the member function. https://github.com/hsutter/cppfront/compare/main...ntrel:cppfront:inout-that

JohelEGP commented 1 year ago

That's because all calls of the form expression.function(expression-list arguments) are candidates for UFCS.

ntrel commented 1 year ago

But swap is declared as a member function, so it shouldn't try UFCS. Probably somewhere else needs updating in the compiler.

JohelEGP commented 1 year ago

No. cppfront doesn't implement lookup, so it has to defer to the lowered Cpp1 code to decide it wants to use the member function. It does that through the UFCS macro.