Why isn’t isUniquelyReferenced(_:) working here?

  case .s(var s): 
   // -1 for return from pattern match (total: +2)
       s.foo() 
       e = .empty // -1 (total: +1)
      s.foo() // should be uniquely referenced

If s would be a struct which is owned by the enum, i.e. it is stored in the enum value, the above code would be quite problematic if the struct s would be referenced out of the enum and then the enum value is changed, making further access invalid.

To cicumvent the problem, the enum value fixed as switch param is duplicated behind the scenes s.t. replacing the enum value e inside the switch block would only mutate the enum value outside the switch block and not the duplicated enum value inside.

But, I don't know if these are the current semantics of Swift's switch.

why would you expect the assignment to not mutate the enum value inside the case block?

1 Like

why would you expect the assignment to not mutate the enum value inside the case block?

I would expect it because the old subvalue s of the enum is accessed after mutation inducing undefined behavior (UB). To circumvent UB, a safe copy has to made before.

Nonetheless, it would be much clearer to deny any writeable operation to a enum value during referencing a subvalue of it.

no, the var expression binds the associated value to a new value s, making it independent from the old value in the enum, which can be destroyed at any time without affecting the newly bound value.

no, the var expression binds the associated value to a new value s , making it independent from the old value in the enum , which can be destroyed at any time without affecting the newly bound value.

Okay, looking amateurish at the SIL of your program, it seems that C.init() is separated from the enum such that a new hidden (stack?) var is created storing C.init() and var c just refers to this hidden value which is however not possible in more general cases.

Question:
Is it guaranteed that releasing values of aggregate type (release_value) also decrements references inside the aggregate value immediately?
If yes, then your case seems to be a bug.

Terms of Service

Privacy Policy

Cookie Policy