Skip to content
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

[BUG] Cannot return object of type by value #400

Closed
realgdman opened this issue May 1, 2023 · 9 comments
Closed

[BUG] Cannot return object of type by value #400

realgdman opened this issue May 1, 2023 · 9 comments
Labels
bug Something isn't working

Comments

@realgdman
Copy link

realgdman commented May 1, 2023

Cpp1 error when trying to return object (by value?) from local variable

Code example
S : type = {
public x: int = 42;
}

baz: () -> _ = {
return S(); //ok cpp1: return S();
}
foo: () -> _ = {
//foo: () -> move _ = { //same behavior
s: S = ();
return s; //cpp1 error: see below
}

main: () = {
std::cout << baz().x;
std::cout << foo().x;
}

Actual result - cpp1 error

error: call to deleted constructor of 'typename std::remove_reference<S &>::type' (aka 'S')
return std::move(s);
note: 'S' has been explicitly marked deleted here
public: S(S const&) = delete;

Additional info
it is possible to return just constructed object like in baz()
Probably this is desired, but I dont see much difference why local cannot be returned here, and constructed object can.

Another note, it is working if type declared with @struct meta

@realgdman realgdman added the bug Something isn't working label May 1, 2023
@realgdman realgdman changed the title [BUG] Cannot return type by value [BUG] Cannot return object of type by value May 1, 2023
@JohelEGP
Copy link
Contributor

JohelEGP commented May 1, 2023

The error is clear.
See 10241cd:

If the user didn't write a 'that' constructor, suppress Cpp1's compiler-generated copying and assignment

So a @struct works because it is copyable.

@JohelEGP
Copy link
Contributor

JohelEGP commented May 1, 2023

See also https://wg21.link/P2573.
Right now, public: S(S const&) = delete; appears in the error message,
so a short comment can be appended as a stand-in for a proper error message.
Recently, Clang or GCC started trimming source lines too long in error messages,
so the comment should be short yet helpful.
I suggest public: S(S const&) = delete; // No `that` constructor, suppressing.

@realgdman
Copy link
Author

Should baz() still work?

@JohelEGP
Copy link
Contributor

JohelEGP commented May 1, 2023

Yes. That looks OK.

@realgdman
Copy link
Author

realgdman commented May 1, 2023

Well I still not fully understand. Isn't foo() supposed to not copy, but move by cpp2 default? Error rises inside std::remove_reference which for me looks like some inner workings, not what I am expressing in cpp2.

@JohelEGP
Copy link
Contributor

JohelEGP commented May 1, 2023

Copy and move are an overload set.
S doesn't implement a move constructor,
so the deleted copy constructor is used.

@realgdman
Copy link
Author

realgdman commented May 1, 2023

I think baz() works in cpp1 because of guaranteed copy elision in cpp++17? It's still returning S which is not copyable.

On other hand, in foo() cpp2 wraps return in std::move() behind scenes.
Does that mean that I forced to write move constructor? Even if I don't want to change S type definition?
Is there or should be a way to suppress move? I have tried declaring
foo: () -> copy _ = {...} which gives

error: only 'forward' and 'move' return passing style are allowed from functions (at 'copy')

Also I tried return copy s or return (copy s) which is syntax error too.

@JohelEGP
Copy link
Contributor

JohelEGP commented May 1, 2023

I think baz() works in cpp1 because of guaranteed copy elision in cpp++17? It's still returning S which is not copyable.

That's right. Returning a prvalue doesn't require copy/move.

Does that mean that I forced to write move constructor?

Or an in that operator= (copy constructor).

Is there or should be a way to suppress move?

That's subject of #231.
Using x&* rather than x works: https://cpp2.godbolt.org/z/aY13c3GG6.
Also using a function call like as-lvalue.
See also #396.

@hsutter
Copy link
Owner

hsutter commented May 5, 2023

Thanks for the usability report, and I like the error message suggestion. Applied!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants