Skip to content

Argument expression move happens before all arguments are evaluated #10525

Closed
@yuriks

Description

@yuriks

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions