After my earlier proposal I had the idea that instead of a complete overhaul of semantics, there might be a solution in small, individual changes.
So with the recent discussions and pain points that have been brought up, I have reduced the proposal to two features and an inaction.
I should again point out that all of the ideas are taken from earlier proposals.
Instead of the current path formats, the following will be recognized:
foo::bar(starting with an identifier) is relative to the current module.
::) is an absolute path in the current crate (see Options below for an alternative).
extern::) is absolute in another crate.
self::fooas relative prefixes are as they are today.
extern:: path is regarded as external crate reference, meaning there
is no need to use
extern crate for it to work. However, the external
crate is only available through
extern:: and not as an item in
the current crate root.
This feature is not backwards compatible. It would require a feature flag or an epoch-like facility to activate by default.
crate::foo::bar, but that is bikeshedding territory as they both would have the same semantics.
extern::cratename::could have different syntax, which would also not change the semantics and is more a visual discussion.
mod working just the way it is currently, but allow the module
name to be replaced with
* causing all submodules of the current
module to be loaded, except those loaded explicitly. Renaming is
disallowed (for now) with the glob variant.
As an example, assuming the following files:
then the following statement at the crate root
pub(crate) mod *; pub mod a;
will expand to:
pub(crate) mod b; pub(crate) mod c; pub mod a;
Note that it only pulls in direct submodules of the current module, and does not affect any lower submodules.
The rationale for requiring
* for mod when
extern crate is no
longer necessary is that
extern:: paths don’t introduce items in the
module tree, but
mod does. The
* is semantically symmetric to the one
in a glob import
use foo::*. Both mark sources of items pulled in the
current namespace that aren’t explicitly mentioned.
This feature is backwards compatible and can be enabled by default.
extern crate situation.
structured_paths feature above means there is no need for an
extern crate foo if the path
extern::foo is accessed
However, I would propose to leave the
extern crate as it is right
now and not deprecate it because:
- It can still be used to import a crate root as an item into the current module.
- Having it only be an import of a crate root is backwards compatible.
- Existing documentation and examples continue to work in providing
a local symbol where
extern crateis used.
- It doesn’t have to be deprecated now and a separate discussion can be had if it should get hard-removed in future epochs, or linted, or kept.
extern::cratename:: to Options as visual discussion topic and fixed some prose. Adjusted
extern crate section to mention possible future deprecation. Thanks to @RalfJung!