Export macros from submodules RFC

Summary

We propose we re-export the macros exposed in the stdlib's root from their logical sub-modules too. Additionally we define an initial mapping of the macros to submodules.

Motivation

Right now the Rust stdlib exports over 70 macros, most of which exist only in the crate root - despite providing a wide range of functionality. Ideally this functionality should be exposed from subcrates, but that was not possible up until recently.

This however, recently changed, and it now is possible to expose macros from submodules. This RFC proposed we do exactly that: export macros from submodules.

Guide-level explanation

Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means:

  • Introducing new named concepts.
  • Explaining the feature largely in terms of examples.
  • Explaining how Rust programmers should think about the feature, and how it should impact the way they use Rust. It should explain the impact as concretely as possible.
  • If applicable, provide sample error messages, deprecation warnings, or migration guidance.
  • If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers.

For implementation-oriented RFCs (e.g. for compiler internals), this section should focus on how compiler contributors should think about the change, and give examples of its concrete impact. For policy RFCs, this section should provide an example-driven introduction to the policy, and explain its impact in concrete terms.

Reference-level explanation

This is the technical portion of the RFC. Explain the design in sufficient detail that:

  • Its interaction with other features is clear.
  • It is reasonably clear how the feature would be implemented.
  • Corner cases are dissected by example.

The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work.

Drawbacks

Why should we not do this?

Rationale and alternatives

  • Why is this design the best in the space of possible designs?
  • What other designs have been considered and what is the rationale for not choosing them?
  • What is the impact of not doing this?

Prior art

Discuss prior art, both the good and the bad, in relation to this proposal.
A few examples of what this can include are:

  • For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had?
  • For community proposals: Is this done by some other community and what were their experiences with it?
  • For other teams: What lessons can we learn from what other communities have done here?
  • Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background.

This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture.
If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages.

Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC.
Please also take into consideration that rust sometimes intentionally diverges from common language features.

Unresolved questions

Future possibilities

Hey all, this is a first stab at mapping the macros on std root to their respective submodules. I figured if we get to an RFC this might be one of the bigger topics to be discussed, so I figured I'd front load it before writing more of the RFC text.

Roughly my ideas was to try and move as many macros to submodules as possible. The only ones where it doesn't make sense is for items which I'd squarely classify as "lang". But even then there might be some wiggle room (see the "notes" column).

Anyway, feel free to comment on this HackMD!

Macro mappings

Macro name Proposed mod Notes
assert std::assert New submodule: assert
assert_eq std::assert New submodule: assert
assert_matches::assert_matches std::assert Unstable, New submodule: assert
assert_matches::debug_assert_matches std::assert Unstable, New submodule: assert
assert_ne std::assert New submodule: assert
cfg std Lang construct
clone::Clone std::clone Derive attribute
cmp::Eq std::cmp Derive attribute
cmp::Ord std::cmp Derive attribute
cmp::PartialEq std::cmp Derive attribute
cmp::PartialOrd std::cmp Derive attribute
column std Should this be std::env?
compile_error std Lang construct
concat std Operates on str
concat_bytes std Unstable
concat_idents std Unstable
const_format_args std Unstable
dbg std::io Operates on std::io::stdout
debug_assert std::assert New submodule: assert
debug_assert_eq std::assert New submodule: assert
debug_assert_ne std::assert New submodule: assert
default::Default std::default Derive attribute
env std::env Operates on env during compilation
eprint std::io Operates on std::io::stderr
eprintln std::io Operates on std::io::stderr
file std::fs Should this be in std::env?
fmt::Debug std Proc attribute
format std::fmt Formats arguments
format_args std::fmt Formats arguments
format_args_nl std::fmt Unstable
future::join std Unstable, already there!
hash::Hash std Derive attribute
include std::fs Performs file reads during compilation
include_bytes std::fs Performs file reads during compilation
include_str std::fs Performs file reads during compilation
is_aarch64_feature_detected std::arch Unstable
is_arm_feature_detected std::arch Unstable
is_mips64_feature_detected std::arch Unstable
is_mips_feature_detected std::arch Unstable
is_powerpc64_feature_detected std::arch Unstable
is_powerpc_feature_detected std::arch Unstable
is_riscv_feature_detected std::arch Unstable
is_x86_feature_detected std::arch Unstable
line std Should this be in std::env?
llvm_asm std Unstable, soon to be removed
log_syntax std Unstable
marker::Copy std::marker Proc attribute
matches std This feels like it's a core thing
module_path std Should this be in std::env?
option_env std::env Inspects the env during compilation
panic std::panic Panics
prelude::v1::bench std::prelude::v1 Prelude
prelude::v1::cfg_accessible std::prelude::v1 Prelude
prelude::v1::cfg_eval std::prelude::v1 Prelude
prelude::v1::derive std::prelude::v1 Prelude
prelude::v1::global_allocator std::prelude::v1 Prelude
prelude::v1::test std::prelude::v1 Prelude
prelude::v1::test_case std::prelude::v1 Prelude
print std::io Operates on std::io::stdout
println std::io Operates on std::io::stdout
ptr::addr_of std::ptr Already there!
ptr::addr_of_mut std::ptr Already there!
simd::simd_swizzle std::simd Unstable, Already there!
stringify std Should this be in proc_macro::?
task::ready std::task Unstable, likely to be removed
thread_local std::thread Operates on threads
todo std::panic Panics
trace_macros std Unstable
try std Lang item, Deprecated
unimplemented std::panic Panics
unreachable std::panic Panics
vec std::vec Creates a vec
write std::io, std::fmt Used in both std::fmt and std::io
writeln std::io, std::fmt Used in both std::fmt and std::io
  • Most unsure about write / writeln. Both are the same, both used in std::fmt and std::io.

Notes

  • Write down the rules for how to decide where traits should go
    • Derive macros sit next to the trait they're derived from
    • We're allowed to have new submodules
    • assert and todo could potentially be subject to changes, so maybe let's not lock them in?
Select a repo