Skip to content

Commit 4f65307

Browse files
committed
author "reexport-stdlib-macros" RFC
1 parent 873890e commit 4f65307

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed

text/0000-reexport-stdlib-macros.md

+198
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
- Feature Name: (fill me in with a unique ident, `reexport-stdlib-macros`)
2+
- Start Date: (fill me in with today's date, 2022-01-04)
3+
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
4+
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
This RFC proposed we start re-exporting macros currently exposed in `core::*`
10+
from submodules. We define a mapping of which macros to re-export from which
11+
submodules, though in some cases it makes most sense to keep the macros exported
12+
from `core`.
13+
14+
This RFC does not yet propose we deprecate or migrate any code,
15+
that is left up to future RFCs.
16+
17+
# Motivation
18+
[motivation]: #motivation
19+
20+
Right now the Rust stdlib exports over 70 macros, most of which exist only in
21+
the crate root - despite providing a wide range of functionality. This has
22+
negative consequences for the stdlib's root: not only are there countless
23+
submodules, there are also an overwhelming number of macros doing an assortment
24+
of things. But it also has negative consequences for the individual submodules:
25+
they will often only tell part of a story, and often leave out crucial
26+
information on how they should actually be used.
27+
28+
Take for example the [`std::panic`
29+
submodule](https://doc.rust-lang.org/std/panic/index.html). It includes various
30+
methods to inspect, catch, and even modify panic behavior. But it includes no
31+
facilities to actually trigger panics. Experienced rustaceans will know that
32+
this can be done using `panic!`, `todo!`, `unimplemented!` and the like. But for
33+
someone new to Rust, this information is not made readily available.
34+
35+
When macros are available from submodules we can begin to paint a more complete
36+
picture of how those submodules are intended to be used. Up until recently it
37+
wasn't possible to expose macros from submodules, but now that it is we should
38+
take the opportunity to start making use of it.
39+
40+
# Mapping re-exports
41+
42+
The following table covers which macro we're talking about, which sub-module it
43+
should be made available from, whether that's a new sub-module, and whether the
44+
macro is unstable. Macros which are unstable can be _moved_ rather than just
45+
re-exported.
46+
47+
| __Macro name__ | __Proposed mod__ | __New exports?__ | __Unstable?__ |
48+
|----------------------------------------|--------------------|------------------|---------------|
49+
| `assert` | `core::panic` |||
50+
| `assert_eq` | `core::panic` |||
51+
| `assert_matches::assert_matches` | `core::panic` |||
52+
| `assert_matches::debug_assert_matches` | `core::panic` |||
53+
| `assert_ne` | `core::panic` |||
54+
| `cfg` | `core` |||
55+
| `clone::Clone` | `core::clone` |||
56+
| `cmp::Eq` | `core::cmp` |||
57+
| `cmp::Ord` | `core::cmp` |||
58+
| `cmp::PartialEq` | `core::cmp` |||
59+
| `cmp::PartialOrd` | `core::cmp` |||
60+
| `column` | `core` |||
61+
| `compile_error` | `core` |||
62+
| `concat` | `core` |||
63+
| `concat_bytes` | `core` |||
64+
| `concat_idents` | `core` |||
65+
| `const_format_args` | `core::fmt` |||
66+
| `dbg` | `core::io` |||
67+
| `debug_assert` | `core::panic` |||
68+
| `debug_assert_eq` | `core::panic` |||
69+
| `debug_assert_ne` | `core::panic` |||
70+
| `default::Default` | `core::default` |||
71+
| `env` | `core` |||
72+
| `eprint` | `core::io` |||
73+
| `eprintln` | `core::io` |||
74+
| `file` | `core` |||
75+
| `fmt::Debug` | `core::fmt` |||
76+
| `format` | `core::fmt` |||
77+
| `format_args` | `core::fmt` |||
78+
| `format_args_nl` | `core::fmt` |||
79+
| `future::join` | `core` |||
80+
| `hash::Hash` | `core::hash::Hash` |||
81+
| `include` | `core` |||
82+
| `include_bytes` | `core` |||
83+
| `include_str` | `core` |||
84+
| `is_aarch64_feature_detected` | `core::arch` |||
85+
| `is_arm_feature_detected` | `core::arch` |||
86+
| `is_mips64_feature_detected` | `core::arch` |||
87+
| `is_mips_feature_detected` | `core::arch` |||
88+
| `is_powerpc64_feature_detected` | `core::arch` |||
89+
| `is_powerpc_feature_detected` | `core::arch` |||
90+
| `is_riscv_feature_detected` | `core::arch` |||
91+
| `is_x86_feature_detected` | `core::arch` |||
92+
| `line` | `core` |||
93+
| `llvm_asm` | `core` |||
94+
| `log_syntax` | `core` |||
95+
| `marker::Copy` | `core::marker` |||
96+
| `matches` | `core` |||
97+
| `module_path` | `core` |||
98+
| `option_env` | `core` |||
99+
| `panic` | `core::panic` |||
100+
| `prelude::v1::bench` | `core::prelude::v1` |||
101+
| `prelude::v1::cfg_accessible` | `core::prelude::v1` |||
102+
| `prelude::v1::cfg_eval` | `core::prelude::v1` |||
103+
| `prelude::v1::derive` | `core::prelude::v1` |||
104+
| `prelude::v1::global_allocator` | `core::prelude::v1` |||
105+
| `prelude::v1::test` | `core::prelude::v1` |||
106+
| `prelude::v1::test_case` | `core::prelude::v1` |||
107+
| `print` | `core::io` |||
108+
| `println` | `core::io` |||
109+
| `ptr::addr_of` | `core::ptr` |||
110+
| `ptr::addr_of_mut` | `core::ptr` |||
111+
| `simd::simd_swizzle` | `core::simd` |||
112+
| `stringify` | `core` |||
113+
| `task::ready` | `core::task` |||
114+
| `thread_local` | `core::thread` |||
115+
| `todo` | `core::panic` |||
116+
| `trace_macros` | `core` |||
117+
| `try` | `core` |||
118+
| `unimplemented` | `core::panic` |||
119+
| `unreachable` | `core::panic` |||
120+
| `vec` | `core::vec` |||
121+
| `write` | `core` |||
122+
| `writeln` | `core` |||
123+
124+
# Reference-level explanation
125+
[reference-level-explanation]: #reference-level-explanation
126+
127+
The implementation of this RFC should be no more than adding a re-export from
128+
the submodule to the existing macro found in the crate root. Say we're re-exporting
129+
`core::assert` from `core::panic::assert`, we could imagine it being done along
130+
these lines:
131+
132+
```rust
133+
pub mod core {
134+
/// Panics the current thread.
135+
#[macro_export]
136+
macro_rules! panic { ... }
137+
138+
pub mod panic {
139+
pub use crate::panic;
140+
}
141+
}
142+
```
143+
144+
Some of these macros such as `panic!` will be built-ins, meaning that changing
145+
their implementations might have implications for the compiler. Because this RFC
146+
only proposes we re-export macros and not _migrate_ macros (see "future
147+
possibilities"), simply creating an alias for the macro from the submodule is enough.
148+
149+
# Prior art
150+
[prior-art]: #prior-art
151+
152+
It was only up to recently that it wasn't possible to export macros from
153+
submodules. New macros being added to the stdlib are already available from
154+
submodules (e.g. `std::ptr::addr_of`, `std::task::ready`). And derive-macros
155+
have always been available from submodules (e.g. `std::clone::Clone`,
156+
`std::hash::Hash`).
157+
158+
Now that the technical restriction has been lifted, we can finally look
159+
at the existing macros and start to re-export them from their logical
160+
submodules.
161+
162+
# Unresolved questions
163+
[unresolved-questions]: #unresolved-questions
164+
165+
## `write/writeln`
166+
167+
Both the `write` and `writeln` macros call a method named `write` on a type, as
168+
exists in the stdlib as
169+
[`std::fmt::Write`](https://doc.rust-lang.org/std/fmt/trait.Write.html) and
170+
[`std::io::Write`](https://doc.rust-lang.org/std/io/trait.Write.html).
171+
172+
Because `write/writeln` both need to be available from `core`, they would need
173+
to _at least_ be available from `core::fmt` - there is no `core::io`. But when
174+
considering the `std` docs it might make sense to expose them from both. One
175+
point in favor of doing it from both locations is that it would enable both the
176+
`fmt` and `io` docs to be more self-contained. But it's unclear what the best
177+
option would be. What should we do here?
178+
179+
# Future possibilities
180+
[future-possibilities]: #future-possibilities
181+
182+
## Deprecate macros in stdlib root
183+
184+
Once we have the macros re-exported from their respective submodules, we can
185+
start looking at what to do with the macros currently still in the stdlib's
186+
root. Should we deprecate them over an edition? Should we change the way they're
187+
shown in the docs? Because having 50 or so deprecated items in the crate root
188+
seems like a lot.
189+
190+
It's likely we'll want to do _something_ here, but it's unclear what exactly.
191+
Therefor we're leaving this as an open question which should be explored in the
192+
future, but for now is out of the scope of this RFC.
193+
194+
## API Guidlines
195+
196+
It might be helpful for the stdlib's API guidelines to include a section
197+
explaining when to export macros from existing submodules, when to export them
198+
from newly created submodules, and when to export them from the crate root.

0 commit comments

Comments
 (0)