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
This commit is contained in:
bors
2025-01-21 19:46:20 +00:00
22 changed files with 37 additions and 185 deletions

View File

@@ -1,10 +1,9 @@
#![warn(clippy::borrow_as_ptr)] #![warn(clippy::borrow_as_ptr)]
#![feature(lang_items, start, libc)]
#![no_std] #![no_std]
#![crate_type = "lib"]
#[clippy::msrv = "1.75"] #[clippy::msrv = "1.75"]
#[start] pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
fn main(_argc: isize, _argv: *const *const u8) -> isize {
let val = 1; let val = 1;
let _p = core::ptr::addr_of!(val); let _p = core::ptr::addr_of!(val);
@@ -12,11 +11,3 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
let _p_mut = core::ptr::addr_of_mut!(val_mut); let _p_mut = core::ptr::addr_of_mut!(val_mut);
0 0
} }
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -1,10 +1,9 @@
#![warn(clippy::borrow_as_ptr)] #![warn(clippy::borrow_as_ptr)]
#![feature(lang_items, start, libc)]
#![no_std] #![no_std]
#![crate_type = "lib"]
#[clippy::msrv = "1.75"] #[clippy::msrv = "1.75"]
#[start] pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
fn main(_argc: isize, _argv: *const *const u8) -> isize {
let val = 1; let val = 1;
let _p = &val as *const i32; let _p = &val as *const i32;
@@ -12,11 +11,3 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
let _p_mut = &mut val_mut as *mut i32; let _p_mut = &mut val_mut as *mut i32;
0 0
} }
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -1,5 +1,5 @@
error: borrow as raw pointer error: borrow as raw pointer
--> tests/ui/borrow_as_ptr_no_std.rs:9:14 --> tests/ui/borrow_as_ptr_no_std.rs:8:14
| |
LL | let _p = &val as *const i32; LL | let _p = &val as *const i32;
| ^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of!(val)` | ^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of!(val)`
@@ -8,7 +8,7 @@ LL | let _p = &val as *const i32;
= help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]` = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`
error: borrow as raw pointer error: borrow as raw pointer
--> tests/ui/borrow_as_ptr_no_std.rs:12:18 --> tests/ui/borrow_as_ptr_no_std.rs:11:18
| |
LL | let _p_mut = &mut val_mut as *mut i32; LL | let _p_mut = &mut val_mut as *mut i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of_mut!(val_mut)` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of_mut!(val_mut)`

View File

@@ -1,6 +1,6 @@
#![feature(lang_items, start, libc)]
#![warn(clippy::box_default)] #![warn(clippy::box_default)]
#![no_std] #![no_std]
#![crate_type = "lib"]
pub struct NotBox<T> { pub struct NotBox<T> {
_value: T, _value: T,
@@ -18,16 +18,7 @@ impl<T: Default> Default for NotBox<T> {
} }
} }
#[start] pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
fn main(_argc: isize, _argv: *const *const u8) -> isize {
let _p = NotBox::new(isize::default()); let _p = NotBox::new(isize::default());
0 0
} }
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -1,7 +1,7 @@
//@compile-flags: -Clink-arg=-nostartfiles //@compile-flags: -Clink-arg=-nostartfiles
//@ignore-target: apple windows //@ignore-target: apple windows
#![feature(lang_items, start, libc)] #![crate_type = "lib"]
#![no_std] #![no_std]
#![allow(clippy::if_same_then_else)] #![allow(clippy::if_same_then_else)]
#![allow(clippy::redundant_pattern_matching)] #![allow(clippy::redundant_pattern_matching)]
@@ -15,18 +15,9 @@ impl Drop for S {
fn drop(&mut self) {} fn drop(&mut self) {}
} }
#[start] pub fn main(argc: isize, argv: *const *const u8) -> isize {
fn main(argc: isize, argv: *const *const u8) -> isize {
if let Some(_) = Some(S) { if let Some(_) = Some(S) {
} else { } else {
} }
0 0
} }
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -1,32 +0,0 @@
//@compile-flags: -Clink-arg=-nostartfiles
//@ignore-target: apple
#![feature(lang_items, start, libc)]
#![no_std]
use core::panic::PanicInfo;
use core::sync::atomic::{AtomicUsize, Ordering};
static N: AtomicUsize = AtomicUsize::new(0);
#[warn(clippy::main_recursion)]
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
let x = N.load(Ordering::Relaxed);
N.store(x + 1, Ordering::Relaxed);
if x < 3 {
main(_argc, _argv);
}
0
}
#[allow(clippy::empty_loop)]
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -1,11 +1,10 @@
#![no_std] #![no_std]
#![feature(lang_items, start, libc)]
#![crate_type = "lib"] #![crate_type = "lib"]
use core::panic::PanicInfo; use core::panic::PanicInfo;
#[warn(clippy::all)] #[warn(clippy::all)]
fn main() { pub fn main() {
let mut a = 42; let mut a = 42;
let mut b = 1337; let mut b = 1337;

View File

@@ -1,11 +1,10 @@
#![no_std] #![no_std]
#![feature(lang_items, start, libc)]
#![crate_type = "lib"] #![crate_type = "lib"]
use core::panic::PanicInfo; use core::panic::PanicInfo;
#[warn(clippy::all)] #[warn(clippy::all)]
fn main() { pub fn main() {
let mut a = 42; let mut a = 42;
let mut b = 1337; let mut b = 1337;

View File

@@ -1,5 +1,5 @@
error: this looks like you are trying to swap `a` and `b` error: this looks like you are trying to swap `a` and `b`
--> tests/ui/crate_level_checks/no_std_swap.rs:12:5 --> tests/ui/crate_level_checks/no_std_swap.rs:11:5
| |
LL | / a = b; LL | / a = b;
... | ... |

View File

@@ -1,6 +1,6 @@
//@ignore-target: apple //@ignore-target: apple
#![feature(no_core, lang_items, start)] #![feature(no_core, lang_items)]
#![no_core] #![no_core]
#![allow(clippy::missing_safety_doc)] #![allow(clippy::missing_safety_doc)]

View File

@@ -2,27 +2,11 @@
//@ignore-target: apple //@ignore-target: apple
#![warn(clippy::empty_loop)] #![warn(clippy::empty_loop)]
#![feature(lang_items, start, libc)] #![crate_type = "lib"]
#![no_std] #![no_std]
use core::panic::PanicInfo; pub fn main(argc: isize, argv: *const *const u8) -> isize {
#[start]
fn main(argc: isize, argv: *const *const u8) -> isize {
// This should trigger the lint // This should trigger the lint
loop {} loop {}
//~^ ERROR: empty `loop {}` wastes CPU cycles //~^ ERROR: empty `loop {}` wastes CPU cycles
} }
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
// This should NOT trigger the lint
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {
// This should also trigger the lint
loop {}
//~^ ERROR: empty `loop {}` wastes CPU cycles
}

View File

@@ -1,5 +1,5 @@
error: empty `loop {}` wastes CPU cycles error: empty `loop {}` wastes CPU cycles
--> tests/ui/empty_loop_no_std.rs:13:5 --> tests/ui/empty_loop_no_std.rs:10:5
| |
LL | loop {} LL | loop {}
| ^^^^^^^ | ^^^^^^^
@@ -8,13 +8,5 @@ LL | loop {}
= note: `-D clippy::empty-loop` implied by `-D warnings` = note: `-D clippy::empty-loop` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::empty_loop)]` = help: to override `-D warnings` add `#[allow(clippy::empty_loop)]`
error: empty `loop {}` wastes CPU cycles error: aborting due to 1 previous error
--> tests/ui/empty_loop_no_std.rs:26:5
|
LL | loop {}
| ^^^^^^^
|
= help: you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body
error: aborting due to 2 previous errors

View File

@@ -1,4 +1,4 @@
#![feature(lang_items, start)] #![crate_type = "lib"]
#![warn(clippy::imprecise_flops)] #![warn(clippy::imprecise_flops)]
#![warn(clippy::suboptimal_flops)] #![warn(clippy::suboptimal_flops)]
#![no_std] #![no_std]
@@ -17,15 +17,6 @@ fn fake_abs1(num: f64) -> f64 {
if num >= 0.0 { num } else { -num } if num >= 0.0 { num } else { -num }
} }
#[start] pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
fn main(_argc: isize, _argv: *const *const u8) -> isize {
0 0
} }
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -6,7 +6,6 @@
//@aux-build:../auxiliary/proc_macros.rs //@aux-build:../auxiliary/proc_macros.rs
#![warn(clippy::missing_const_for_fn)] #![warn(clippy::missing_const_for_fn)]
#![feature(start)]
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
extern crate helper; extern crate helper;
@@ -71,15 +70,6 @@ mod with_test_fn {
} }
} }
// Allowing on this function, because it would lint, which we don't want in this case.
// if we have `#[start]` and `#[test]` check `is_entrypoint_fn(cx, def_id.to_def_id())` is stopped
// working
#[allow(clippy::missing_const_for_fn)]
#[start]
fn init(num: isize, something: *const *const u8) -> isize {
1
}
trait Foo { trait Foo {
// This should not be suggested to be made const // This should not be suggested to be made const
// (rustc doesn't allow const trait methods) // (rustc doesn't allow const trait methods)

View File

@@ -1,22 +1,13 @@
#![warn(clippy::missing_spin_loop)] #![warn(clippy::missing_spin_loop)]
#![feature(lang_items, start, libc)] #![crate_type = "lib"]
#![no_std] #![no_std]
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicBool, Ordering};
#[start] pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
fn main(_argc: isize, _argv: *const *const u8) -> isize {
// This should trigger the lint // This should trigger the lint
let b = AtomicBool::new(true); let b = AtomicBool::new(true);
// This should lint with `core::hint::spin_loop()` // This should lint with `core::hint::spin_loop()`
while b.load(Ordering::Acquire) { core::hint::spin_loop() } while b.load(Ordering::Acquire) { core::hint::spin_loop() }
0 0
} }
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -1,22 +1,13 @@
#![warn(clippy::missing_spin_loop)] #![warn(clippy::missing_spin_loop)]
#![feature(lang_items, start, libc)] #![crate_type = "lib"]
#![no_std] #![no_std]
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicBool, Ordering};
#[start] pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
fn main(_argc: isize, _argv: *const *const u8) -> isize {
// This should trigger the lint // This should trigger the lint
let b = AtomicBool::new(true); let b = AtomicBool::new(true);
// This should lint with `core::hint::spin_loop()` // This should lint with `core::hint::spin_loop()`
while b.load(Ordering::Acquire) {} while b.load(Ordering::Acquire) {}
0 0
} }
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -1,5 +1,5 @@
error: busy-waiting loop should at least have a spin loop hint error: busy-waiting loop should at least have a spin loop hint
--> tests/ui/missing_spin_loop_no_std.rs:12:37 --> tests/ui/missing_spin_loop_no_std.rs:11:37
| |
LL | while b.load(Ordering::Acquire) {} LL | while b.load(Ordering::Acquire) {}
| ^^ help: try: `{ core::hint::spin_loop() }` | ^^ help: try: `{ core::hint::spin_loop() }`

View File

@@ -1,5 +1,6 @@
#![feature(lang_items, start, libc)] #![feature(lang_items, libc)]
#![no_std] #![no_std]
#![no_main]
#![warn(clippy::result_unit_err)] #![warn(clippy::result_unit_err)]
#[clippy::msrv = "1.80"] #[clippy::msrv = "1.80"]
@@ -12,8 +13,8 @@ pub fn returns_unit_error_lint() -> Result<u32, ()> {
Err(()) Err(())
} }
#[start] #[no_mangle]
fn main(_argc: isize, _argv: *const *const u8) -> isize { extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
0 0
} }

View File

@@ -1,5 +1,5 @@
error: this returns a `Result<_, ()>` error: this returns a `Result<_, ()>`
--> tests/ui/result_unit_error_no_std.rs:11:1 --> tests/ui/result_unit_error_no_std.rs:12:1
| |
LL | pub fn returns_unit_error_lint() -> Result<u32, ()> { LL | pub fn returns_unit_error_lint() -> Result<u32, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -1,19 +1,10 @@
#![feature(lang_items, start, libc)] #![crate_type = "lib"]
#![no_std] #![no_std]
#![deny(clippy::zero_ptr)] #![deny(clippy::zero_ptr)]
#[start] pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
fn main(_argc: isize, _argv: *const *const u8) -> isize {
let _ = core::ptr::null::<usize>(); let _ = core::ptr::null::<usize>();
let _ = core::ptr::null_mut::<f64>(); let _ = core::ptr::null_mut::<f64>();
let _: *const u8 = core::ptr::null(); let _: *const u8 = core::ptr::null();
0 0
} }
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -1,19 +1,10 @@
#![feature(lang_items, start, libc)] #![crate_type = "lib"]
#![no_std] #![no_std]
#![deny(clippy::zero_ptr)] #![deny(clippy::zero_ptr)]
#[start] pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
fn main(_argc: isize, _argv: *const *const u8) -> isize {
let _ = 0 as *const usize; let _ = 0 as *const usize;
let _ = 0 as *mut f64; let _ = 0 as *mut f64;
let _: *const u8 = 0 as *const _; let _: *const u8 = 0 as *const _;
0 0
} }
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

View File

@@ -1,5 +1,5 @@
error: `0 as *const _` detected error: `0 as *const _` detected
--> tests/ui/zero_ptr_no_std.rs:7:13 --> tests/ui/zero_ptr_no_std.rs:6:13
| |
LL | let _ = 0 as *const usize; LL | let _ = 0 as *const usize;
| ^^^^^^^^^^^^^^^^^ help: try: `core::ptr::null::<usize>()` | ^^^^^^^^^^^^^^^^^ help: try: `core::ptr::null::<usize>()`
@@ -11,13 +11,13 @@ LL | #![deny(clippy::zero_ptr)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: `0 as *mut _` detected error: `0 as *mut _` detected
--> tests/ui/zero_ptr_no_std.rs:8:13 --> tests/ui/zero_ptr_no_std.rs:7:13
| |
LL | let _ = 0 as *mut f64; LL | let _ = 0 as *mut f64;
| ^^^^^^^^^^^^^ help: try: `core::ptr::null_mut::<f64>()` | ^^^^^^^^^^^^^ help: try: `core::ptr::null_mut::<f64>()`
error: `0 as *const _` detected error: `0 as *const _` detected
--> tests/ui/zero_ptr_no_std.rs:9:24 --> tests/ui/zero_ptr_no_std.rs:8:24
| |
LL | let _: *const u8 = 0 as *const _; LL | let _: *const u8 = 0 as *const _;
| ^^^^^^^^^^^^^ help: try: `core::ptr::null()` | ^^^^^^^^^^^^^ help: try: `core::ptr::null()`