diff --git a/spec/legacy.dd b/spec/legacy.dd index 89b7670d63..138ee672bc 100644 --- a/spec/legacy.dd +++ b/spec/legacy.dd @@ -24,6 +24,8 @@ $(COMMENT $(TROW Escaping $(DDSUBLINK spec/attribute, scope, `scope`) data, `scope` is $(LINK2 https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md, enforced) in `@safe` code, 2024) + $(TROW $(RELATIVE_LINK2 struct-assign, Assigning to struct rvalue), + Disallow for structs which overload e.g. `opAssign`, 2024) $(COMMENT Not enforced yet) $(TROW `alias` target first syntax, use `alias name = target` instead.) @@ -93,6 +95,41 @@ struct Foo } --- +$(H2 $(LNAME2 struct-assign, Assigning to struct rvalue)) + + $(P It has always been an error for $(DDSUBLINK spec/struct, POD, POD) structs + to assign from an rvalue.) + + $(P From the 2024 edition, it is an error to discard the result of an + assignment from a struct rvalue when it would call `opAssign`, `opOpAssign`, + `opUnary!"++"`, or `opUnary!"--"` and the struct has no pointer + fields:) + +--- +struct S +{ + int i; + + void opAssign(S s); +} + +S foo(); + +void main() +{ + foo() = S(2); // Error, possible no-op +} +--- + $(P Above, unless `opAssign` mutates global data, the assignment in `main` + will have no effect and indicates a bug.) + +$(H3 Corrective Action) + + $(P If a struct rvalue assignment is needed to mutate global state, either + call the operator overload method directly or use an lvalue. + Note: Calling a non-const method on a struct rvalue + $(DDSUBLINK spec/struct, member-functions, is allowed).) + $(SPEC_SUBNAV_PREV_NEXT glossary, Glossary, editions, Editions) )