Skip to content

Commit 6e537fe

Browse files
committed
Merge branch 'alexcrichton-no_std' into HEAD
2 parents fd0afde + 2c2c429 commit 6e537fe

File tree

2 files changed

+161
-0
lines changed

2 files changed

+161
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ the direction the language is evolving in.
6060
* [1122-language-semver.md](text/1122-language-semver.md)
6161
* [1131-likely-intrinsic.md](text/1131-likely-intrinsic.md)
6262
* [1156-adjust-default-object-bounds.md](text/1156-adjust-default-object-bounds.md)
63+
* [1184-stabilize-no_std.md](text/1184-stabilize-no_std.md)
6364

6465
## Table of Contents
6566
[Table of Contents]: #table-of-contents

text/1184-stabilize-no_std.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
- Feature Name: N/A
2+
- Start Date: 2015-06-26
3+
- RFC PR: https://github.com/rust-lang/rfcs/pull/1184
4+
- Rust Issue: https://github.com/rust-lang/rust/issues/27394
5+
6+
# Summary
7+
8+
Tweak the `#![no_std]` attribute, add a new `#![no_core]` attribute, and
9+
pave the way for stabilizing the libcore library.
10+
11+
# Motivation
12+
13+
Currently all stable Rust programs must link to the standard library (libstd),
14+
and it is impossible to opt out of this. The standard library is not appropriate
15+
for use cases such as kernels, embedded development, or some various niche cases
16+
in userspace. For these applications Rust itself is appropriate, but the
17+
compiler does not provide a stable interface compiling in this mode.
18+
19+
The standard distribution provides a library, libcore, which is "the essence of
20+
Rust" as it provides many language features such as iterators, slice methods,
21+
string methods, etc. The defining feature of libcore is that it has 0
22+
dependencies, unlike the standard library which depends on many I/O APIs, for
23+
example. The purpose of this RFC is to provide a stable method to access
24+
libcore.
25+
26+
Applications which do not want to use libstd still want to use libcore 99% of
27+
the time, but unfortunately the current `#![no_std]` attribute does not do a
28+
great job in facilitating this. When moving into the realm of not using the
29+
standard library, the compiler should make the use case as ergonomic as
30+
possible, so this RFC proposes different behavior than today's `#![no_std]`.
31+
32+
Finally, the standard library defines a number of language items which must be
33+
defined when libstd is not used. These language items are:
34+
35+
* `panic_fmt`
36+
* `eh_personality`
37+
* `stack_exhausted`
38+
39+
To be able to usefully leverage `#![no_std]` in stable Rust these lang items
40+
must be available in a stable fashion.
41+
42+
# Detailed Design
43+
44+
This RFC proposes a nuber of changes:
45+
46+
* Tweak the `#![no_std]` attribute slightly.
47+
* Introduce a `#![no_core]` attribute.
48+
* Pave the way to stabilize the `core` module.
49+
50+
## `no_std`
51+
52+
The `#![no_std]` attribute currently provides two pieces of functionality:
53+
54+
* The compiler no longer injects `extern crate std` at the top of a crate.
55+
* The prelude (`use std::prelude::v1::*`) is no longer injected at the top of
56+
every module.
57+
58+
This RFC proposes adding the following behavior to the `#![no_std]` attribute:
59+
60+
* The compiler will inject `extern crate core` at the top of a crate.
61+
* The libcore prelude will be injected at the top of every module.
62+
63+
Most uses of `#![no_std]` already want behavior along these lines as they want
64+
to use libcore, just not the standard library.
65+
66+
## `no_core`
67+
68+
A new attribute will be added to the compiler, `#![no_core]`, which serves two
69+
purposes:
70+
71+
* This attribute implies the `#![no_std]` attribute (no std prelude/crate
72+
injection).
73+
* This attribute will prevent core prelude/crate injection.
74+
75+
Users of `#![no_std]` today who do *not* use libcore would migrate to moving
76+
this attribute instead of `#![no_std]`.
77+
78+
## Stabilization of libcore
79+
80+
This RFC does not yet propose a stabilization path for the contents of libcore,
81+
but it proposes readying to stabilize the name `core` for libcore, paving the
82+
way for the rest of the library to be stabilized. The exact method of
83+
stabilizing its contents will be determined with a future RFC or pull requests.
84+
85+
## Stabilizing lang items
86+
87+
As mentioned above, there are three separate lang items which are required by
88+
the libcore library to link correctly. These items are:
89+
90+
* `panic_fmt`
91+
* `stack_exhausted`
92+
* `eh_personality`
93+
94+
This RFC does **not** attempt to stabilize these lang items for a number of
95+
reasons:
96+
97+
* The exact set of these lang items is somewhat nebulous and may change over
98+
time.
99+
* The signatures of each of these lang items can either be platform-specific or
100+
it's just "too weird" to stabilize.
101+
* These items are pretty obscure and it's not very widely known what they do or
102+
how they should be implemented.
103+
104+
Stabilization of these lang items (in any form) will be considered in a future
105+
RFC.
106+
107+
# Drawbacks
108+
109+
The current distribution provides precisely one library, the standard library,
110+
for general consumption of Rust programs. Adding a new one (libcore) is adding
111+
more surface area to the distribution (in addition to adding a new `#![no_core]`
112+
attribute). This surface area is greatly desired, however.
113+
114+
When using `#![no_std]` the experience of Rust programs isn't always the best as
115+
there are some pitfalls that can be run into easily. For example, macros and
116+
plugins sometimes hardcode `::std` paths, but most ones in the standard
117+
distribution have been updated to use `::core` in the case that `#![no_std]` is
118+
present. Another example is that common utilities like vectors, pointers, and
119+
owned strings are not available without liballoc, which will remain an unstable
120+
library. This means that users of `#![no_std]` will have to reimplement all of
121+
this functionality themselves.
122+
123+
This RFC does not yet pave a way forward for using `#![no_std]` and producing an
124+
executable because the `#[start]` item is required, but remains feature gated.
125+
This RFC just enables creation of Rust static or dynamic libraries which don't
126+
depend on the standard library in addition to Rust libraries (rlibs) which do
127+
not depend on the standard library.
128+
129+
In stabilizing the `#![no_std]` attribute it's likely that a whole ecosystem of
130+
crates will arise which work with `#![no_std]`, but in theory all of these
131+
crates should also interoperate with the rest of the ecosystem using `std`.
132+
Unfortunately, however, there are known cases where this is not possible. For
133+
example if a macro is exported from a `#![no_std]` crate which references items
134+
from `core` it won't work by default with a `std` library.
135+
136+
# Alternatives
137+
138+
Most of the strategies taken in this RFC have some minor variations on what can
139+
happen:
140+
141+
* The `#![no_std]` attribute could be stabilized as-is without adding a
142+
`#![no_core]` attribute, requiring users to write `extern crate core` and
143+
import the core prelude manually. The burden of adding `#![no_core]` to the
144+
compiler, however, is seen as not-too-bad compared to the increase in
145+
ergonomics of using `#![no_std]`.
146+
* Another stable crate could be provided by the distribution which provides
147+
definitions of these lang items which are all wired to abort. This has the
148+
downside of selecting a name for this crate, however, and also inflating the
149+
crates in our distribution again.
150+
151+
# Unresolved Questions
152+
153+
* How important/common are `#![no_std]` executables? Should this RFC attempt to
154+
stabilize that as well?
155+
* When a staticlib is emitted should the compiler *guarantee* that a
156+
`#![no_std]` one will link by default? This precludes us from ever adding
157+
future require language items for features like unwinding or stack exhaustion
158+
by default. For example if a new security feature is added to LLVM and we'd
159+
like to enable it by default, it may require that a symbol or two is defined
160+
somewhere in the compilation.

0 commit comments

Comments
 (0)