Skip to content

Ref/& Destructuring Inconsistency in Structs #2819

@quantatic

Description

@quantatic

Rust pattern matching and destructuring allows the use of & and ref.

In the example below, the use of these is intuitive.

fn main() {
    let a: (u32) = (1234);
    let (ref ref_a) = a;

    let b: (&u32) = (&1234);
    let (&deref_b) = b;
}

In this case, we end up with ref_a of type &u32, and deref_b of type u32. Simple enough -- we can go both ways with both ref and & in pattern matching.

In the instance with structs, this consistency breaks down when matching struct field names. In the example that follows, this is shown:

struct Borrowed {
    val: u32
}

fn main() {
    let a = Borrowed {
        val: 1234
    };

    let Borrowed {ref val} = a;
}

In this case, val is borrowed as &u32, mirroring tuple functionality. The following example on the other hand, does not work.

struct Derefed<'a> {
    val: &'a u32
}

fn main() {
    let a = Derefed {
        val: &1234
    };

    let Derefed {&val} = a; // error: expected identifier, found `&`
    let Derefed {val: &val} = a; // works as expected
}

While not functionality-breaking, it is extremely non-intuitive that this matching only works via ref and not via & for structs, when binding directly to the same variable name.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-patternsPattern matching related proposals & ideasT-langRelevant to the language team, which will review and decide on the RFC.

    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