RFC 0240: unsafe-api-location

libs (unsafe | convention)

Summary

This is a conventions RFC for settling the location of unsafe APIs relative to the types they work with, as well as the use of raw submodules.

The brief summary is:

Motivation

Many data structures provide unsafe APIs either for avoiding checks or working directly with their (otherwise private) representation. For example, string provides:

The problem is that currently, there is no clear/consistent guideline about which of these APIs should live as methods/static functions associated with a type, and which should live in a raw submodule. Both forms appear throughout the standard library.

Detailed design

The proposed convention is:

The benefits are:

The perspective here is that marking APIs unsafe is enough to deter their use in ordinary situations; they don't need to be further distinguished by placement into a separate module.

There are also some naming conventions to go along with unsafe static functions and methods:

The unsafe methods and static functions for a given type should be placed in their own impl block, at the end of the module defining the type; this will ensure that they are grouped together in rustdoc. (Thanks @lilyball for the suggestion.)

Drawbacks

One potential drawback of these conventions is that the documentation for a module will be cluttered with rarely-used unsafe APIs, whereas the raw submodule approach neatly groups these APIs. But rustdoc could easily be changed to either hide or separate out unsafe APIs by default, and in the meantime the impl block grouping should help.

More specifically, the convention of placing unsafe constructors in raw makes them very easy to find. But the usual from_ convention, together with the naming conventions suggested above, should make it fairly easy to discover such constructors even when they're supplied directly as static functions.

More generally, these conventions give unsafe APIs more equal status with safe APIs. Whether this is a drawback depends on your philosophy about the status of unsafe programming. But on a technical level, the key point is that the APIs are marked unsafe, so users still have to opt-in to using them. Ed note: from my perspective, low-level/unsafe programming is important to support, and there is no reason to penalize its ergonomics given that it's opt-in anyway.

Alternatives

There are a few alternatives:

Unresolved questions

The core::raw module provides structs with public representations equivalent to several built-in and library types (boxes, closures, slices, etc.). It's not clear whether the name of this module, or the location of its contents, should change as a result of this RFC. The module is a special case, because not all of the types it deals with even have corresponding modules/type declarations -- so it probably suffices to leave decisions about it to the API stabilization process.