Skip to content

Argument expression move happens before all arguments are evaluated #10525

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
yuriks opened this issue Nov 16, 2013 · 1 comment
Closed

Argument expression move happens before all arguments are evaluated #10525

yuriks opened this issue Nov 16, 2013 · 1 comment

Comments

@yuriks
Copy link
Contributor

yuriks commented Nov 16, 2013

I briefly discussed this on IRC and was encouraged to submit an issue about it.

When the expressions of two arguments to a function both borrow the same object, but with non-overlapping lifetimes, an error is issued anyway.

For example, in this testcase:

struct Room {
    foo: ~str,
}

fn dummy_insert<K, V>(key: K, value: V) {
}

fn add_room(id: ~str) {
    dummy_insert(id, Room { foo: id.clone() });
}

fn main() {
}

Produces this error:

src/main.rs:9:30: 9:32 error: use of moved value: `id`
src/main.rs:9   dummy_insert(id, Room { foo: id.clone() });
                                             ^~
src/main.rs:9:14: 9:16 note: `id` moved here because it has type `~str`, which is non-copyable (perhaps you meant to use clone()?)
src/main.rs:9   dummy_insert(id, Room { foo: id.clone() });
                             ^~
error: aborting due to previous error
task 'rustc' failed at 'explicit failure', /home/yuriks/rust/src/libsyntax/diagnostic.rs:101
task '<main>' failed at 'explicit failure', /home/yuriks/rust/src/librustc/lib.rs:396

Even though the Room { ... } constructor expression is fully evaluated before the function call happens. It seem that the moving is happening as part of the left-to-right evaluation of arguments, instead of that happening when the function is actually called. Cloning in the 1st argument instead works, but reads more confusingly to me.

Maybe this is intended behaviour, but it doesn't seem ideal to me.

@alexcrichton
Copy link
Member

Closing as working-as-intended. Arguments are evaluated left-to-right, and if you move a left-hand argument, you can't access it with right-hand arguments.

flip1995 pushed a commit to flip1995/rust that referenced this issue Apr 6, 2023
…r=Jarcho

Make redundant_async_block a more complete late pass

This lets us detect more complex situations: `async { x.await }` is simplified into `x` if:

- `x` is an expression without side-effect
- or `x` is an `async` block itself

In both cases, no part of the `async` expression can be part of a macro expansion.

Fixes rust-lang#10509.
Fixes rust-lang#10525.

changelog: [`redundant_async_block`] Do not lint expressions with side effects.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants