[Pitch/Discussion] Rename symbols that have been audited as unsafe (or fix LLVM)

As part of the initial set of proposals for Span, RawSpan, MutableSpan and others, we accepted some functions that reinterpret typed memory as untyped bytes. Some of these have since then had to be revised with an @unsafe annotation. As a result, their names do not reflect the unsafety in typical use (when compiled without -strict-memory-safety). This discussion is about how to solve this discrepancy.

The underlying issue is that after LLVM initializes some storage with a value, it chooses to treat any padding bytes within the storage of the value as uninitialized. This in keeping with its identity as a C compiler, but is neither the only possible choice nor necessarily a desirable behaviour from the compiler for languages that use LLVM but are not C, such as Swift.

We can solve the naming discrepancy in one of two ways:

  • Change LLVM's treatment of padding bytes (in Swift mode) so that they do not lead to undefined behaviour, and then remove the @unsafe annotations for these functions or properties.
  • Rename these functions and properties to reflect that they are unsafe.

The second option is the simpler one, but doesn't solve the underlying issue. The unsafety comes from a decision of the C language that Swift might not make; is it feasible to make a different decision?

In the meantime, I have prepared a proposal document for renaming (PR), since the standard library is the part of the system I understand best. In short, the @unsafe symbols to be renamed are as follows:

  • bytesunsafeBytes (Span, MutableSpan)
  • mutableBytesunsafeMutableBytes (MutableSpan)
  • append(_:as:)append(unsafeBytes:as:) (OutputRawSpan)
  • append(repeating:count:as:)append(repeatingUnsafeBytes:count:as:) (OutputRawSpan)

I'd be glad for this proposal to be put aside in favor of changing LLVM. While the amount of effort is not the same, both have a similar time horizon for completion because of the lengthy deprecation window we must allow for.

1 Like

Nit regarding the latter two operations: is it the append which is unsafe or the bytes being read from? If the former, the name really should be unsafeAppend.

Safety is always better than unsafety of course. If we rename now to reflect the currently unsafe reality but then make LLVM better, the newly-made-safe-previously-deprecated APIs can be straightforwardly undeprecated, presumably. So it doesn't seem either-or.

It's actually both. The source bytes might include some locations marked by the compiler as undefined, and it can kindly copy that state over.

Indeed.

1 Like

What are the downsides to changing LLVM's behavior (if any)?

Because honestly, to me as a "user" or the language, this reads:
Option A:
Deal with deprecations, migration work for everyone, a messy transition phase, and more unsafe littered all over codebases (for the shiny new "safe" language addition mind you), - or -

Option B:
just make the problem go away without any changes

so, why would anyone NOT want the LLVM adjustments?