Skip to content

Decide and implement a solution for internal-facing APIs #4467

@sffc

Description

@sffc

We've hit multiple snags recently where we wanted to change a mostly-internal function that was pub and were blocked because of semver:

  • cmp_iter functions in icu_locid
  • new_owned and Cart types in icu_provider
  • Probably more

Some thoughts/comments/problems:

  1. Even if these had been public-internal functions, we still have some desire to keep them stable-ish because then we can break hard tilde dependencies between components/utils (Revisit policy around component crate interdependent versions #4343)
  2. If the functions are #[doc(hidden)], they are less discoverable including to ICU4X developers. We can't expect ICU4X developers to look into the source code just to see if a function they want happens to be there.
  3. These functions should most likely be excluded from FFI by default
  4. If we are poking holes in a util crate, the holes we poke should probably be part of the public API of that crate, because it is a utility crate. However, within ICU4X component and provider crates, it is okay and expected for us to poke holes.
  5. Previous discussion: Document traits as either sealed or implementable #4338 (comment)

Here's a proposal:

Add a macro_rules that generates the following boilerplate:

#[doc = "<div class=\"stab unstable\">"]
#[doc = "🚧 This code is internal to ICU4X; it may change at any time, in breaking or non-breaking ways,"]
#[doc = "including in SemVer minor releases. It can be enabled with the \"icu4x_internal\" Cargo feature."]
#[doc = "</div>"]
#[cfg(feature = "icu4x_internal")]

The macro_rules can live in icu_locid for now. We can move it later.

To annotate an internal API, you can do this:

/// These are docs for my internal API
icu_locid::_internal::icu4x_internal_api!()
pub struct Foo {}

The icu4x_internal Cargo feature does not bubble up to the metacrate. It can be selectively enabled whenever it is needed. One advantage of making an icu4x_internal feature is that we can disable it when uploading docs to docs.rs (https://docs.rs/about/metadata), although I don't think there's a way to disable just that one feature; we would need to switch from --all-features to an explicit feature list per-crate, which is error-prone. Alternatively, I'm fine if we say we don't introduce a Cargo feature for this and simply let these APIs live in the docs.

In the 1.5 or 2.0 timeframe, I suggest that we scrub our API surface and add this annotation where appropriate. A lot of things that are currently #[doc(hidden)] should probably use the annotation instead, and likewise things that are currently public stable should also probably use the annotation.

If we agree on this, I may suggest we make a similar annotation for the provider module.

Needs approval or input from:

Metadata

Metadata

Assignees

Labels

C-metaComponent: Relating to ICU4X as a wholeS-mediumSize: Less than a week (larger bug fix or enhancement)

Type

No type

Projects

Status

Unclaimed for sprint

Relationships

None yet

Development

No branches or pull requests

Issue actions