Suggestion: references in struct literal


#1

This may have been asked before, but here goes

Struct { field } desugars to Struct { field: field }, could Struct { &field } desugar to Struct { field: &field }?

Or is this too much magic?


#2

I see two possible meanings for that, the one you propose or Struct { field: { let &x = field; x } }. So maybe this extension wouldn’t be that obvious.


#3

Yeah good point. I think my expansion is more expected though.


#4

I personally would not expect your expansion, looking at how pattern matching works. I’d prefer something like

Type { ref x }
// equivalent to
Type { ref x: x }
// equivalent to
Type { x: &x }

#5

Struct literals aren’t patterns, though. This feature is similar struct patterns but going the other way.


#6

perhaps my expectation is wrong, then.


#7

This is probably the first question I had after reading the “struct field shortcut in expressions” RFC.
Struct field shortcut in patterns supports making simple transformations inline - S { ref field }, and S { mut field }, and S { ref mut field } (and also S { box field }, but we don’t talk about it), what is equivalent for struct expression?
I didn’t suggest to extend the RFC back then just to let the basic feature get into the language and marinate for some time.

Now it seems reasonable to look at these extensions again, e.g. S { &field } can be a shortcut for inline referencing, S { *field } - for inline dereferencing, if these operations are commonly used in practice.
S { &field } can be supported in patterns as well.


#8

Interesting idea, but that feels like too much magic to me as well.

Is there a common situation in which you’re constructing a large number of reference fields at once, and don’t just want to reference another structure grouping those fields?


#9

I’m just bikeshedding really.


#10

I’m a bit fuzzy on the motivation here. Obviously Struct { &field } is better than Struct { field: &field }, but this shortcut only works for local bindings (const and static items theoretically could too, but since those are upper case and fields are lower case, idiomatic code won’t be able to apply the shorthand syntax in those cases). Thus in many cases one can side step the need to create a reference when creating the struct by instead making the local a reference. That is, instead of

let field = foo();
// ...
let s = Struct { &field };

one could just do this:

let field = &foo(); // or a ref pattern if needed, e.g., for function arguments
// ...
let s = Struct { field };

This doesn’t work when the field value needs to mutated between creation of the local and creation of the struct, but that seems a narrow special case of something that already doesn’t happen all too often.