Some thoughts on more ergonomic Struct Update Syntax

struct Foo<T> {
    a: T,
    b: usize,
    c: usize,
    d: usize,
    e: usize,
    f: usize,
}


fn main() {
    let f = Foo {
        a: "aaa".to_string(),
        b:0,
        c:0,
        d:0,
        e:0,
        f:0,
    };
    
    let _: Foo<usize> = Foo {
        a: 1,
        ..f
    };
}

This example (Playground link) compiles failed:

error[E0308]: mismatched types
  --> src/main.rs:23:11
   |
23 |         ..f
   |           ^ expected `usize`, found struct `String`
   |
   = note: expected struct `Foo<usize>`
              found struct `Foo<String>`

Yes, this totally meets the expectation since Foo<usize> and Foo<String> are different types. However, I think we are kind of too rigid. We'll often encounter such a situation similar to the example above. This could be annoying if we can't utilize the update syntax. For example, the tracing project exists so much inelegant code due to this limitation. See here1, here2.

IMO, we deserve an improvement on the update syntax for better ergonomic programming. However, I'm not a Rust compile expert, maybe we have some obstacles to achieve this? Or maybe we shouldn't do this? Well, what do you think?

5 Likes

Related, if not exactly the same

The FRU that we currently have moves from each field individually, right? So it makes sense that it would be type checked as such, rather than caring about the type that you're pulling from.

(Though should we be able to Vec4 { w: 0, ..vec3 }? I honestly don't know and this kinda breaks what I think of as type safety in this, as fields are matched by name and field type if this is allowed. Plus refactoring one of the two types would break this "at a distance." So I think reasonable is "has the same base type, modulo generic instantiation" (i.e. fields are matched by identity not name) and type check that the fields match, not the whole generic instantiation.)

Allowing this would give more reason for why FRU works the way it does... so long as I got the direction right and I'm not describing the other way that isn't his it works.