Privacy and its interaction with docs, lints and stability


#1

This text is inspired by the discussion in https://github.com/rust-lang/rust/issues/28450
It describes some things I plan to fix in various privacy-related areas of the compiler.

rustc_privacy not only checks things and reports privacy errors when necessary, it also provides some important data for later stages of compilation, namely

  • stability checking
  • reachability analysis
  • dead code lint
  • other lints
    • missing Copy
    • missing Debug
    • missing docs
    • invalid no_mangle lint
  • rustdoc

Currently privacy produces two sets of HIR nodes - “public” set and “exported” set.

  • “Public” set is a set of all items in a crate that are accessible from other crates directly, without help of reexports, i.e. completely public.
  • “Exported” set is a set of all items that can be accessed with help of pub use aliases or pub type aliases.

Curiously, the both sets are not appropriate for the tasks listed above.

  • Stability uses the public set and don’t require annotations on items reexported from private modules. Theoretically it should lead to many “use of unmarked library feature” errors from libstd, but they all have been probably been caught manually and fixed.

  • Reachability analysis uses the exported set and it can lead to link time errors when non-reexported types from private inner modules are used in public interfaces (let’s call them NRTFPIMUIPIs :slight_smile: ).

  • I haven’t looked closely at the dead code lint, but it uses the exported set, so it should probably give false positives on NRTFPIMUIPIs.

  • rustdoc uses both sets in various ways, it means sometime it can show more docs than needed (for types hidden under pub type) and sometime less (for some things reexported with pub use).

  • Other lints use the exported set and it means that types hidden under pub type “typedefs” require documentation. Copy/Debug/no_mangle lints are probably good as they are

I’m currently rewriting EmbargoVisitor/VisiblePrivateTypesVisitor in rustc_privacy to properly finish implementation of RFC 136 and fix various bad things happening with NRTFPIMUIPIs. I’m going to replace the public and exported sets with two new sets, let’s call them set A and set B.

  • Set A is a set of all items accessible from other crates directly or through pub use (but not pub type) reexports.
  • Set B is a set of all accessible items + set of items used in accessible interfaces (transitively).

The later passes are going to use:

  • stability - Set B (no “use of unmarked library feature” errors are possible and all leaking internals have to be annotated (probably with unstable))
  • reachability - Set B (no link time errors)
  • dead code lint - Set B looks appropriate
  • missing Copy, missing Debug - Set B looks somewhat more appropriate
  • invalid no_mangle lints - Set B (doesn’t matter actually)
  • missing docs - Set A (need to document what you reexport with pub use, don’t need to document what you hide under pub type and other NRTFPIMUIPIs)
  • rustdoc - Set A (the same as missing docs lint)

As for naming, I’m going to keep the old names and call set A “public set” and set B “exported set” despite them changing their meanings.

All of this looks pretty unambiguous, but some additional review never hurts.


#2

Does it make sense to completely ignore pub type?

What about intra-crate reachability?


#3

Could you elaborate? I’m not sure how to answer to it.
As a minimum, pub type has to be recursed into and all types inside of it (and their impls, etc) should be exported to avoid unresolved symbols during linkage.
Intra-crate reachability doesn’t exist, as far as I understand it.


#4

This all sounds great to me, thanks @petrochenkov! I forget the original reason for the public and exported sets being distinct, but regardless these sound like the correct way to define them to me.