But auto ref/deref may work for Foo { bar }
but it does not work for Foo { mut bar }
.
It would be cool to see Foo { &bar, &mut baz }
but I wonder what would happened to Foo { bar? }
or Foo { baz.await }
or Foo { bar.field }
?
But auto ref/deref may work for Foo { bar }
but it does not work for Foo { mut bar }
.
It would be cool to see Foo { &bar, &mut baz }
but I wonder what would happened to Foo { bar? }
or Foo { baz.await }
or Foo { bar.field }
?
Thatās why I like @petrochenkovās proposal from above, namely that we do a transformation like this:
Given a struct Foo
defined like this:
Foo {
field0: T0,
field1: T1,
...
fieldN: TN,
}
and the following struct literal:
Foo { expr0, expr1, ..., exprN }
where the only identifier in expr0
is field0
, in expr1
is field1
, ā¦, in exprN
is fieldN
, then we desugar to the following struct literal:
Foo {
field0: expr0,
field1: expr1,
...
fieldN: exprN,
}
I can very easily see that leading to errors. Consider math on a vector or matrix that wants to intentionally shuffle around components, for instance.
Also, just to confirm, would āone identifierā rule out dotted expressions like this?
struct V3 { x: f64, y: f64, z: f64 }
fn shuffle(v: V3) -> V3 {
V3 { v.y, v.z, v.x }
}
I can easily see a C programmer writing that, because C allows initializing structs positionally.This needs to continue producing an error, rather than incorrectly producing an identity function.
I can easily imagine the same kind of error with expressions that have only one identifier.
(Even for the existing field punning, I can imagine code that will erroneously compile; Iād favor having, for instance, a lint for cases that involve structs containing entirely fields of the same type and same-length short names where the field puns appear out of order.)
I actually made this error with the existing shortcut once.
I needed to swap two fields and wrote something like this:
let s = if lo <= hi {
S { lo, hi }
} else {
S { hi, lo }
}
I can see at least two ways we could catch that with a lint.
The least likely to cause false positives: if you write two struct initializers with field puns in the same function with fields in different orders, lint.
Also, the one I mentioned in the previous post involving an out-of-order struct initializer with field puns that consist entirely of fields with the same name-length and same type. That could lead to false positives, but you can trivially fix those by reordering the fields or by labeling the fields.
Itās apparent that this can cause bugs regardless of what is proposed here, so itās perhaps not very relevant to this discussion. At least, I donāt see how this proposal makes that situation any worse.
It seems to me that allowing arbitrary expressions (with only the āone identifierā limit) makes bugs more likely.
My thinking is to disallow the use of dot expressions or keywords. We could also disallow non-unary operators. I think with all of these restrictions we can still improve ergonomics for the most common cases.
I do like the idea of a lint, though.
While I donāt personally have a use for it, I donāt have any strong objection to allowing this for most unary operators, if that would help.
I would find it quite confusing to permit &
, though, precisely because of potential confusion with what ref
means.
It seems like it would be a bit bizzare to disallow only &
, wouldnāt it? Also, I expect &
and *
to be the most common use cases for thisā¦
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.