about summary refs log tree commit diff
path: root/src/doc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-01-21 19:46:20 +0000
committerbors <bors@rust-lang.org>2025-01-21 19:46:20 +0000
commited43cbcb882e7c06870abdd9305dc1f17eb9bab9 (patch)
tree436c680b2714e0300cdbbef3e2ecd321a049794e /src/doc
parentcd805f09ffbfa3896c8f50a619de9b67e1d9f3c3 (diff)
parent56c90dc31e86bbaf486826a21a33d7c56e8f742f (diff)
downloadrust-ed43cbcb882e7c06870abdd9305dc1f17eb9bab9.tar.gz
rust-ed43cbcb882e7c06870abdd9305dc1f17eb9bab9.zip
Auto merge of #134299 - RalfJung:remove-start, r=compiler-errors
remove support for the (unstable) #[start] attribute

As explained by `@Noratrieb:`
`#[start]` should be deleted. It's nothing but an accidentally leaked implementation detail that's a not very useful mix between "portable" entrypoint logic and bad abstraction.

I think the way the stable user-facing entrypoint should work (and works today on stable) is pretty simple:
- `std`-using cross-platform programs should use `fn main()`. the compiler, together with `std`, will then ensure that code ends up at `main` (by having a platform-specific entrypoint that gets directed through `lang_start` in `std` to `main` - but that's just an implementation detail)
- `no_std` platform-specific programs should use `#![no_main]` and define their own platform-specific entrypoint symbol with `#[no_mangle]`, like `main`, `_start`, `WinMain` or `my_embedded_platform_wants_to_start_here`. most of them only support a single platform anyways, and need cfg for the different platform's ways of passing arguments or other things *anyways*

`#[start]` is in a super weird position of being neither of those two. It tries to pretend that it's cross-platform, but its signature is  a total lie. Those arguments are just stubbed out to zero on ~~Windows~~ wasm, for example. It also only handles the platform-specific entrypoints for a few platforms that are supported by `std`, like Windows or Unix-likes. `my_embedded_platform_wants_to_start_here` can't use it, and neither could a libc-less Linux program.
So we have an attribute that only works in some cases anyways, that has a signature that's a total lie (and a signature that, as I might want to add, has changed recently, and that I definitely would not be comfortable giving *any* stability guarantees on), and where there's a pretty easy way to get things working without it in the first place.

Note that this feature has **not** been RFCed in the first place.

*This comment was posted [in May](https://github.com/rust-lang/rust/issues/29633#issuecomment-2088596042) and so far nobody spoke up in that issue with a usecase that would require keeping the attribute.*

Closes https://github.com/rust-lang/rust/issues/29633

try-job: x86_64-gnu-nopt
try-job: x86_64-msvc-1
try-job: x86_64-msvc-2
try-job: test-various
Diffstat (limited to 'src/doc')
-rw-r--r--src/doc/rustc/src/platform-support/nto-qnx.md2
-rw-r--r--src/doc/unstable-book/src/language-features/lang-items.md9
-rw-r--r--src/doc/unstable-book/src/language-features/start.md59
3 files changed, 6 insertions, 64 deletions
diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md
index 1c240d1255a..96e3b58f471 100644
--- a/src/doc/rustc/src/platform-support/nto-qnx.md
+++ b/src/doc/rustc/src/platform-support/nto-qnx.md
@@ -78,7 +78,7 @@ extern "C" {
 }
 
 #[no_mangle]
-pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
+pub extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
     const HELLO: &'static str = "Hello World, the answer is %d\n\0";
     unsafe {
         printf(HELLO.as_ptr() as *const _, 42);
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md
index 32b882e763d..1122bbc5a87 100644
--- a/src/doc/unstable-book/src/language-features/lang-items.md
+++ b/src/doc/unstable-book/src/language-features/lang-items.md
@@ -46,14 +46,15 @@ allocation. A freestanding program that uses the `Box` sugar for dynamic
 allocations via `malloc` and `free`:
 
 ```rust,ignore (libc-is-finicky)
-#![feature(lang_items, start, core_intrinsics, rustc_private, panic_unwind, rustc_attrs)]
+#![feature(lang_items, core_intrinsics, rustc_private, panic_unwind, rustc_attrs)]
 #![allow(internal_features)]
 #![no_std]
+#![no_main]
 
 extern crate libc;
 extern crate unwind;
 
-use core::ffi::c_void;
+use core::ffi::{c_int, c_void};
 use core::intrinsics;
 use core::panic::PanicInfo;
 use core::ptr::NonNull;
@@ -91,8 +92,8 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
     p
 }
 
-#[start]
-fn main(_argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(_argc: c_int, _argv: *const *const u8) -> c_int {
     let _x = Box::new(1);
 
     0
diff --git a/src/doc/unstable-book/src/language-features/start.md b/src/doc/unstable-book/src/language-features/start.md
deleted file mode 100644
index 09e4875a2e4..00000000000
--- a/src/doc/unstable-book/src/language-features/start.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# `start`
-
-The tracking issue for this feature is: [#29633]
-
-[#29633]: https://github.com/rust-lang/rust/issues/29633
-
-------------------------
-
-Allows you to mark a function as the entry point of the executable, which is
-necessary in `#![no_std]` environments.
-
-The function marked `#[start]` is passed the command line parameters in the same
-format as the C main function (aside from the integer types being used).
-It has to be non-generic and have the following signature:
-
-```rust,ignore (only-for-syntax-highlight)
-# let _:
-fn(isize, *const *const u8) -> isize
-# ;
-```
-
-This feature should not be confused with the `start` *lang item* which is
-defined by the `std` crate and is written `#[lang = "start"]`.
-
-## Usage together with the `std` crate
-
-`#[start]` can be used in combination with the `std` crate, in which case the
-normal `main` function (which would get called from the `std` crate) won't be
-used as an entry point.
-The initialization code in `std` will be skipped this way.
-
-Example:
-
-```rust
-#![feature(start)]
-
-#[start]
-fn start(_argc: isize, _argv: *const *const u8) -> isize {
-    0
-}
-```
-
-Unwinding the stack past the `#[start]` function is currently considered
-Undefined Behavior (for any unwinding implementation):
-
-```rust,ignore (UB)
-#![feature(start)]
-
-#[start]
-fn start(_argc: isize, _argv: *const *const u8) -> isize {
-    std::panic::catch_unwind(|| {
-        panic!(); // panic safely gets caught or safely aborts execution
-    });
-
-    panic!(); // UB!
-
-    0
-}
-```