Skip to content

Ref/& Destructuring Inconsistency in Structs #2819

Open
@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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions