Skip to content

Assignee expressions can contain rest-patterns. #2208

@theemathas

Description

@theemathas

See also #2209 for more on assignee expressions.

The following two code snippets compile:

struct Thing { _field: i32 }

fn main() {
    Thing { .. } = Thing { _field: 1 };
}
macro_rules! foo {
    ($x:expr) => {}
}

foo!(Thing { .. });

This implies that Thing { .. } is an expression. In particular, since it's valid on the lhs of an assignment expression, Thing { .. } must be an assignee expression.

An assignee expression can be a struct expression. However, struct expressions cannot contain rest-patterns. Therefore, according to the reference, Thing { .. } cannot be an assignee expression.

Thus, either the compiler or the reference is wrong. I think the reference should be somehow amended to match the compiler.

Similar issues affect rest-patterns in tuples ((x, y, ..)), in slices ([x, y, ..]), and in call expressions (tuple structs; Thing(x, y, ..)).


To make things worse, as pointed out by @kpreid, the Thing { .. } syntax is also currently legal in nightly as syntax for default field values. For example, the following code compiles:

#![feature(default_field_values)]
struct Foo {
    x: i32 = 0,
}
fn main() {
    // creates a struct with default field values, then assigns it to a rest-pattern
    Foo { .. } = Foo { .. };
    // creates two structs with default field values, then assigns one to another
    *&mut Foo { .. } = Foo { .. };
}

I don't know how to specify a disambiguation rule between default field values vs rest-patterns in assignee expressions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions