Namespaced crates update

The following draft RFC by @Manishearth proposes :: as a separator in crate names (it was proposing a slash before). The left portion of the crate name when using :: is another package to which the right portion name belongs.

This topic is to summarize the changes in the RFC.

More Than One ::

The RFC says further :: portions can be supported in the future. I suppose in this case x::y::z would mean:

  • x is a package
  • x::y is another package
    • Owned by package x
  • x::y::z is another package
    • Owned by package x::y

Package Consumption

In the crate API, :: is kept as is and is not mapped to _, as if the crate were a submodule.

Previously, with the / separator instead, it'd map to _.

File system

Probably, in the cache directory, :: translates to /.

1 Like

Since it was an immediate question I had, inlining this answer here: (per the RFC as currently written)

There are no provided safeguards against both publishing a crate foo::bar and defining an item foo::bar in the crate foo. It becomes a name resolution error at use time if both names are present and don't refer to the same item (i.e. it's not an error iff the item foo::bar is a re-export of the crate foo::bar). If only one dependency is present in the extern prelude, there's no name clash.

1 Like

Perhaps such name clashes could cause a compile error? (as opposed to a potential confusing resolution)

It could end up being useful if you re-export another crate from the same crate (so that you don't need it as a dependency), including if you use a crate behind an optional feature.

Or, yeah, maybe you're correct. Usually framework crates will have a core crate, like:

  • x::core
    • pub use x::y as y;
    • contains dependency x::y
  • x::y

Quite confusing... Because Cargo may see x::y as an unused dependency in case it's not re-exported.

This causes problems if crate foo has a file bar in it and foo::bar needs cached.

Though the cache directory uses {}-{package.version} so I don’t think conflicts are possible as a package name cannot include a .. It’s all internal implementation details of cargo so exactly what happens there doesn’t matter much. (This makes me wonder what happens if you include a : or / as part of a prerelease identifier or build metadata).

The more important question is how the .crate package is named since that is somewhat a public API of cargo.

1 Like

Something more cryptic can be used too, like foo::bar resolving to or foo%3A%3Abar, or (because foo::0::bar isn't possible even with r#0).