Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Stabilize the #![no_std] attribute #1184

Merged
merged 6 commits into from Jul 30, 2015
Merged

Conversation

@alexcrichton
Copy link
Member

alexcrichton commented Jun 30, 2015

Stabilize the #![no_std] attribute while also improving the ergonomics of
using libcore by default. Additionally add a new #![no_core] attribute to opt
out of linking to libcore.

rendered

Stabilize the `#![no_std]` attribute while also improving the ergonomics of
using libcore by default. Additionally add a new `#![no_core]` attribute to opt
out of linking to libcore. Finally, stabilize a number of language items
required by libcore which the standard library defines.
@alexcrichton alexcrichton self-assigned this Jun 30, 2015
@alexcrichton alexcrichton added the T-libs label Jun 30, 2015
addition to the interface that it will be stabilized with. Each lang item will
no longer be defined with the `#[lang = "..."]` syntax but will instead receive
a dedicated attribute (e.g. `#[panic_fmt]`) to be attached to functions to
identify an implementation.

This comment has been minimized.

Copy link
@eddyb

eddyb Jul 1, 2015

Member

These are already special-cased as "weak lang items" so using a mechanism different from regular lang items is not that much of a compromise IMO, but it would be nice if the existing situation was mentioned in the RFC.

This comment has been minimized.

Copy link
@nagisa

nagisa Jul 1, 2015

Contributor

Why?

I really like how current #[lang] works and that it is easy to grep for it, etc. I also believe it would be not too hard to stabilise #[lang="*"] only for certain *. That being said, I 👎 on this part of the RFC.

This comment has been minimized.

Copy link
@eddyb

eddyb Jul 1, 2015

Member

They aren't really lang items, but rather a minimal set of compiler-sanctioned weak import/exports.
Libraries could be allowed to define custom "pluggable items" and then these 3 would not be known to the language, just libcore and its users.

@Ericson2314
Copy link
Contributor

Ericson2314 commented Jul 1, 2015

Can we avoid stabilizing the lang items but do the rest? That will mean libcore is only stable to use when std is also linked, but I don't think that is a problem (for now). We still get the benefits of making the macros use core, and anybody actually writing kernel code will need unstable core features anyways.

There is a lot of jank in some those lang items as the RFC admits, and eh_personality is somewhat tied to libcompiler/libgcc. Also the fact that the undefined items problem in core and alloc are being defined in two different ways is worrysome---crate level "functors" a la the MLs that any library could use or define or instantiate would be better.

@Tobba
Copy link

Tobba commented Jul 1, 2015

I propose that extern crate core; should be injected regardless of #![no_std]. This would make it easier to write #![no_std] libraries that contain macros which will work regardless of if the consumer crate is no_std or not.

```

This differs with the `panic_fmt` function today in that the file and line
number arguments are omitted. The libcore library will continue to provide

This comment has been minimized.

Copy link
@Tobba

Tobba Jul 1, 2015

What's the rationale behind this change? This was convenient for formatting reasons, and I don't see why it should go.

This comment has been minimized.

Copy link
@alexcrichton

alexcrichton Jul 1, 2015

Author Member

We don't necessarily want to commit to providing a filename/line number in all panic messages as there have been musings in the past that a measurable overhead in terms of binary size and runtime is incurred from having all these strings/numbers in the binary.

instead of taking it by value, and the purpose of this is to ensure that the
function has a clearly defined ABI on all platforms in case that is required.

#### `eh_personality`

This comment has been minimized.

Copy link
@Tobba

Tobba Jul 1, 2015

Both this and stack_exhausted seem like rather bad candidates for stabilization: they're both implementation details of the platform and compiler.

@Tobba
Copy link

Tobba commented Jul 1, 2015

Proposal: don't stabilize any lang items at all, due to the aforementioned arguments.

One of the current major problems of no_std is that writing libraries that work across both settings is very tedious - it currently involves maintaining a tangled mess of #[cfg] attributes which is rarely tested before release. Stabilizing lang items do nothing to improve this situation anyways.

@thepowersgang
Copy link
Contributor

thepowersgang commented Jul 1, 2015

I agree about not stabilizing any language items here, if this is just for allowing no_std library crates.

However - if stabilizing these language items will allow compilation of no_std binaries (using an externally defined entrypoint, instead of #[start]) then maybe.

@Ericson2314
Copy link
Contributor

Ericson2314 commented Jul 1, 2015

Overall, I'm convinced over the long haul we can reduce the complexity of these implementation details (w.g.. with crate functors, stabilized rust without exceptions), so I rather leave them unstable as long as possible. Complexity is worse than instability for the foreseeable future.

@eddyb
Copy link
Member

eddyb commented Jul 1, 2015

@Tobba I thought $crate solved core/std selection issues in macros.

@Tobba
Copy link

Tobba commented Jul 1, 2015

@eddyb As far as I know it only works for referencing the current crate.


```rust
#[panic_fmt]
pub extern fn panic_fmt(msg: &core::fmt::Arguments) -> !;

This comment has been minimized.

Copy link
@petrochenkov

petrochenkov Jul 1, 2015

Contributor

It doesn't feel right for me that functions deeply internal to Rust are stabilized as extern "C". Is anybody going to import them from C code? Do they need more ABI stability than any other functions?

This comment has been minimized.

Copy link
@alexcrichton

alexcrichton Jul 1, 2015

Author Member

A possible extension one day could be to allow to define these kinds of lang items in other languages (e.g. C), so I figured it would be nice to have a defined ABI to leave the door open to that possibility.


```rust
#[stack_exhausted]
pub extern fn stack_exhausted() -> !;

This comment has been minimized.

Copy link
@nagisa

nagisa Jul 1, 2015

Contributor

This being a diverging function restricts

the implementation of what happens on stack overflow

to terminating the program. I don’t see how you could reallocate a bigger stack and return to normal execution. for example.

This comment has been minimized.

Copy link
@eddyb

eddyb Jul 1, 2015

Member

That's not supported, our abuse of segmented stacks will be removed as soon as LLVM gets proper support for stack probes across all platforms.
IIRC there are some patches waiting to be reviewed and merged (cc @Zoxc).

This comment has been minimized.

Copy link
@nagisa

nagisa Jul 1, 2015

Contributor

our abuse of segmented stacks will be removed as soon as LLVM gets proper support for stack probes across all platforms.

Aware. What I’m just pointing out the function doesn’t exactly work as advertised just above it.

On Windows, where this abuse is not done, this “language item” is not used at all, so I’m doubtful this needs to be stabilised.

This comment has been minimized.

Copy link
@alexcrichton

alexcrichton Jul 1, 2015

Author Member

I agree with @eddyb that there's really no way this function could ever return, adding segmented stacks back is likely to be a much more invasive change than just affecting this function.

This comment has been minimized.

Copy link
@huonw

huonw Jul 1, 2015

Member

We can presumably generalise the signature in future if we find use-cases for other ones.

library. This means that users of `#![no_std]` will have to reimplement all of
this functionality themselves.

This RFC does not yet pave a way forward for using `#![no_std]` and producing an

This comment has been minimized.

Copy link
@steveklabnik

steveklabnik Jul 1, 2015

Member

I would argue that it is paving a way forward, but it's just not there yet. These are the first steps.

@alexcrichton
Copy link
Member Author

alexcrichton commented Jul 1, 2015

@Ericson2314, @Tobba, @thepowersgang

Can we avoid stabilizing the lang items but do the rest?

This is certainly an alternative! (which I have now added) The consequence of this decision is there will be no stable method of producing a staticlib or dylib which uses #![no_std] everywhere. I would personally like to enable this use case as having #![no_std] doesn't seem too useful without it. We can avoid stabilizing the exact signatures with the #![lang_items_abort] alternative mentioned, but there may be other ways to enable the use case of producing a final artifact without defining the precise signatures.


@Tobba

I propose that extern crate core; should be injected regardless of #![no_std].

Unfortunately I think this is not backwards compatible.

This would make it easier to write #![no_std] libraries that contain macros which will work regardless of if the consumer crate is no_std or not.

That's a good point, I've added a drawback to this RFC.

@eefriedman
Copy link
Contributor

eefriedman commented Jul 2, 2015

What's the point of stabilizing #![no_core]? It's not like it would actually be usable in stable Rust.

It makes zero sense to require users to provide an implementation of eh_personality. Assuming users don't do something weird, if you're not linking to libstd, there's no way to unwind, and therefore the eh_personality implementation will never be called. (Weird things here include manually calling _Unwind_RaiseException and unwinding through rust code by accident.)

A variant of the #[lang_items_abort] proposal: define an #[abort] attribute, as an alternative to all three lang-items. Say it has the signature fn abort(msg: &core::fmt::Arguments)->!, we call it whenever we hit any unrecoverable condition. It isn't allowed to unwind.

@eddyb
Copy link
Member

eddyb commented Jul 2, 2015

@eefriedman libcore can panic (and thus unwind), that's why this weak lang item contraption exists in the first place.

@eefriedman
Copy link
Contributor

eefriedman commented Jul 2, 2015

@eddyb libcore can panic, sure, but without libstd's implementation of panic_fmt, it isn't possible to actually unwind.

@Ericson2314
Copy link
Contributor

Ericson2314 commented Jul 2, 2015

@eefriedman As a practical matter, I think rustc demands eh_personality to generate pads assuming panic_fmt is defined to unwind. But certainly I agree this is not an ideal situation, and a great reason why even the existence of eh_personality, not just its signature, shouldn't be stabilized.

@alexcrichton

I would personally like to enable this use case as having #![no_std] doesn't seem too useful without it

Again, I don't think instability around Rust in the kernel is a problem, now or in the foreseeable future. Stabilizing #![no_std] and the existence of core to solve a particular problem like the macros is different, but now it is less clear whether doing so would help with that.

@daboross
Copy link

daboross commented Jul 4, 2015

#[no_std] makes sense as an attribute, it's fairly easy to tell what it's doing - #[no_core] however seems counterintuitive - it isn't exactly clear that it's also assuming #[no_std].

Would it make sense to just have one attribute, something like #[prelude()]? It would be used like #![prelude(core)] or #![prelude(none)], and #![prelude(std)] would be assumed if it isn't declared. believe it would make more sense to have using std, core, or no injected prelude all be under one attribute, rather than multiple.

@eddyb
Copy link
Member

eddyb commented Jul 4, 2015

@daboross #![no_std] #[prelude] extern crate core; is actually what I expected the future direction to be.
Maybe we can still generalize prelude injection to custom and/or multiple crates.
That said, we also need to replace #[prelude_import]'s order-based glob priority with something proper, e.g. prelude glob imports can be overridden by glob imports which, in turn, can be overridden by explicit imports.

@Virtlink
Copy link

Virtlink commented Jul 7, 2015

All crates (including libstd) should be treated equally. There should be nothing that libstd can do that any other crate can't.

Firstly, I'd agree with @eddyb: introduce #[prelude] to manually use the prelude of the marked crate. This removes the special treatment of libstd's prelude. And we don't want to treat libcore's prelude special either, so let's not do #![no_core] and instead require #[prelude] extern crate core for users that want to use libcore and its prelude.

Then for at least eh_personality and stack_exhausted I'd add stub implementations that can be overridden by the user. Most users using #![no_std] don't need any special behavior here. However, overriding these stubs would be unstable, such that their signatures may change in the future. Libstd is just another crate overriding these stubs, and not special in that regard.

Finally, by default any Rust crate would implicitly include #[prelude] extern crate std; unless #![no_std] is specified. Then #![no_std] would mean no defaults instead of no libstd and prelude, which I think is more logical.

@alexcrichton
Copy link
Member Author

alexcrichton commented Jul 8, 2015

@Virtlink

Firstly, I'd agree with @eddyb: introduce #[prelude] to manually use the prelude of the marked crate

The question about what to do with preludes is somewhat orthogonal to the #![no_std] story, there's a separate RFC for dealing with custom preludes.

let's not do #![no_core] and instead require #[prelude] extern crate core for users that want to use libcore and its prelude.

The problem with this is that Rust isn't very useful without extern crate core because of the lang items that it defines, and we ideally want the #![no_std] case to be just as ergonomic as the normal use case, and we wouldn't necessarily expect all users to write extern crate std;

@Ericson2314
Copy link
Contributor

Ericson2314 commented Jul 8, 2015

My first priority is not stabilizing those lang items, but I'd prefer @eddyb's end goal too. Treating all crates as equally as possible an admirable goal, and one #[prelude] extern cate core; is but a tiny decrease in ergonomics.

In fact if we had proper glob-import priority like @eddyb requests, we could just do something like:

extern crate core;
use core::prelude_v1::*;

Even simpler!

Edit: proper glob-import priority, and crate-wide imports for exactly that.

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Jul 30, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Jul 30, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Jul 30, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184
bors added a commit to rust-lang/rust that referenced this pull request Jul 31, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184

Closes #27394
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Jul 31, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184
bors added a commit to rust-lang/rust that referenced this pull request Jul 31, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184

Closes #27394
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Jul 31, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184
bors added a commit to rust-lang/rust that referenced this pull request Jul 31, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184

Closes #27394
bors added a commit to rust-lang/rust that referenced this pull request Aug 1, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184

Closes #27394
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Aug 3, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Aug 3, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184
bors added a commit to rust-lang/rust that referenced this pull request Aug 3, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184

Closes #27394
bors added a commit to rust-lang/rust that referenced this pull request Aug 4, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184

Closes #27394
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Aug 4, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184
bors added a commit to rust-lang/rust that referenced this pull request Aug 4, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184

Closes #27394
bors added a commit to rust-lang/rust that referenced this pull request Aug 5, 2015
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.

[rfc]: rust-lang/rfcs#1184

Closes #27394
joelarmstrong added a commit to joelarmstrong/syscall.rs that referenced this pull request Aug 12, 2015
Broken on latest rust nightly because using no_std automatically injects
an "extern crate core". (rust-lang/rfcs#1184)
mokus0 added a commit to mokus0/rlibc that referenced this pull request Aug 16, 2015
mokus0 added a commit to mokus0/zinc that referenced this pull request Aug 16, 2015
Marwes added a commit to Marwes/mopa that referenced this pull request Jan 3, 2016
archaelus pushed a commit to archaelus/volatile_cell that referenced this pull request Oct 8, 2016
archaelus pushed a commit to archaelus/ioreg that referenced this pull request Oct 8, 2016
@Centril Centril added the A-no_std label Nov 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

You can’t perform that action at this time.