Skip to content

Commit ed43cbc

Browse files
committed
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](#29633 (comment)) and so far nobody spoke up in that issue with a usecase that would require keeping the attribute.* Closes #29633 try-job: x86_64-gnu-nopt try-job: x86_64-msvc-1 try-job: x86_64-msvc-2 try-job: test-various
2 parents cd805f0 + 56c90dc commit ed43cbc

File tree

176 files changed

+454
-1260
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

176 files changed

+454
-1260
lines changed

compiler/rustc_ast/src/entry.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ pub enum EntryPointType {
1818
/// fn main() {}
1919
/// ```
2020
RustcMainAttr,
21-
/// This is a function with the `#[start]` attribute.
22-
/// ```ignore (clashes with test entrypoint)
23-
/// #[start]
24-
/// fn main() {}
25-
/// ```
26-
Start,
2721
/// This function is **not** an entrypoint but simply named `main` (not at the root).
2822
/// This is only used for diagnostics.
2923
/// ```
@@ -40,9 +34,7 @@ pub fn entry_point_type(
4034
at_root: bool,
4135
name: Option<Symbol>,
4236
) -> EntryPointType {
43-
if attr::contains_name(attrs, sym::start) {
44-
EntryPointType::Start
45-
} else if attr::contains_name(attrs, sym::rustc_main) {
37+
if attr::contains_name(attrs, sym::rustc_main) {
4638
EntryPointType::RustcMainAttr
4739
} else if let Some(name) = name
4840
&& name == sym::main

compiler/rustc_ast_passes/src/feature_gate.rs

-12
Original file line numberDiff line numberDiff line change
@@ -230,18 +230,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
230230
}
231231
}
232232

233-
ast::ItemKind::Fn(..) => {
234-
if attr::contains_name(&i.attrs, sym::start) {
235-
gate!(
236-
&self,
237-
start,
238-
i.span,
239-
"`#[start]` functions are experimental and their signature may change \
240-
over time"
241-
);
242-
}
243-
}
244-
245233
ast::ItemKind::Struct(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Union(..) => {
246234
for attr in attr::filter_by_name(&i.attrs, sym::repr) {
247235
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {

compiler/rustc_builtin_macros/src/test_harness.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,11 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
204204
ast::mut_visit::walk_item(self, item);
205205
self.depth -= 1;
206206

207-
// Remove any #[rustc_main] or #[start] from the AST so it doesn't
207+
// Remove any #[rustc_main] from the AST so it doesn't
208208
// clash with the one we're going to add, but mark it as
209209
// #[allow(dead_code)] to avoid printing warnings.
210210
match entry_point_type(&item, self.depth == 0) {
211-
EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => {
211+
EntryPointType::MainNamed | EntryPointType::RustcMainAttr => {
212212
let allow_dead_code = attr::mk_attr_nested_word(
213213
&self.sess.psess.attr_id_generator,
214214
ast::AttrStyle::Outer,
@@ -217,8 +217,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
217217
sym::dead_code,
218218
self.def_site,
219219
);
220-
item.attrs
221-
.retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start));
220+
item.attrs.retain(|attr| !attr.has_name(sym::rustc_main));
222221
item.attrs.push(allow_dead_code);
223222
}
224223
EntryPointType::None | EntryPointType::OtherMain => {}

compiler/rustc_codegen_cranelift/src/main_shim.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
22
use rustc_hir::LangItem;
33
use rustc_middle::ty::{AssocKind, GenericArg};
4-
use rustc_session::config::{EntryFnType, sigpipe};
4+
use rustc_session::config::EntryFnType;
55
use rustc_span::{DUMMY_SP, Ident};
66

77
use crate::prelude::*;
@@ -14,10 +14,9 @@ pub(crate) fn maybe_create_entry_wrapper(
1414
is_jit: bool,
1515
is_primary_cgu: bool,
1616
) {
17-
let (main_def_id, (is_main_fn, sigpipe)) = match tcx.entry_fn(()) {
17+
let (main_def_id, sigpipe) = match tcx.entry_fn(()) {
1818
Some((def_id, entry_ty)) => (def_id, match entry_ty {
19-
EntryFnType::Main { sigpipe } => (true, sigpipe),
20-
EntryFnType::Start => (false, sigpipe::DEFAULT),
19+
EntryFnType::Main { sigpipe } => sigpipe,
2120
}),
2221
None => return,
2322
};
@@ -31,14 +30,13 @@ pub(crate) fn maybe_create_entry_wrapper(
3130
return;
3231
}
3332

34-
create_entry_fn(tcx, module, main_def_id, is_jit, is_main_fn, sigpipe);
33+
create_entry_fn(tcx, module, main_def_id, is_jit, sigpipe);
3534

3635
fn create_entry_fn(
3736
tcx: TyCtxt<'_>,
3837
m: &mut dyn Module,
3938
rust_main_def_id: DefId,
4039
ignore_lang_start_wrapper: bool,
41-
is_main_fn: bool,
4240
sigpipe: u8,
4341
) {
4442
let main_ret_ty = tcx.fn_sig(rust_main_def_id).no_bound_vars().unwrap().output();
@@ -94,8 +92,8 @@ pub(crate) fn maybe_create_entry_wrapper(
9492

9593
let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func);
9694

97-
let result = if is_main_fn && ignore_lang_start_wrapper {
98-
// regular main fn, but ignoring #[lang = "start"] as we are running in the jit
95+
let result = if ignore_lang_start_wrapper {
96+
// ignoring #[lang = "start"] as we are running in the jit
9997
// FIXME set program arguments somehow
10098
let call_inst = bcx.ins().call(main_func_ref, &[]);
10199
let call_results = bcx.func.dfg.inst_results(call_inst).to_owned();
@@ -133,7 +131,8 @@ pub(crate) fn maybe_create_entry_wrapper(
133131
types::I64 => bcx.ins().sextend(types::I64, res),
134132
_ => unimplemented!("16bit systems are not yet supported"),
135133
}
136-
} else if is_main_fn {
134+
} else {
135+
// Regular main fn invoked via start lang item.
137136
let start_def_id = tcx.require_lang_item(LangItem::Start, None);
138137
let start_instance = Instance::expect_resolve(
139138
tcx,
@@ -150,10 +149,6 @@ pub(crate) fn maybe_create_entry_wrapper(
150149
let call_inst =
151150
bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv, arg_sigpipe]);
152151
bcx.inst_results(call_inst)[0]
153-
} else {
154-
// using user-defined start fn
155-
let call_inst = bcx.ins().call(main_func_ref, &[arg_argc, arg_argv]);
156-
bcx.inst_results(call_inst)[0]
157152
};
158153

159154
bcx.ins().return_(&[result]);

compiler/rustc_codegen_gcc/build_system/src/test.rs

-26
Original file line numberDiff line numberDiff line change
@@ -426,19 +426,6 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> {
426426
run_command_with_env(&command, None, Some(env))?;
427427
maybe_run_command_in_vm(&[&cargo_target_dir.join("track-caller-attribute")], env, args)?;
428428

429-
// FIXME: create a function "display_if_not_quiet" or something along the line.
430-
println!("[AOT] mod_bench");
431-
let mut command = args.config_info.rustc_command_vec();
432-
command.extend_from_slice(&[
433-
&"example/mod_bench.rs",
434-
&"--crate-type",
435-
&"bin",
436-
&"--target",
437-
&args.config_info.target_triple,
438-
]);
439-
run_command_with_env(&command, None, Some(env))?;
440-
// FIXME: the compiled binary is not run.
441-
442429
Ok(())
443430
}
444431

@@ -696,19 +683,6 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
696683
Ok(())
697684
}
698685

699-
// echo "[BENCH COMPILE] mod_bench"
700-
//
701-
// COMPILE_MOD_BENCH_INLINE="$RUSTC example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline"
702-
// COMPILE_MOD_BENCH_LLVM_0="rustc example/mod_bench.rs --crate-type bin -Copt-level=0 -o $cargo_target_dir/mod_bench_llvm_0 -Cpanic=abort"
703-
// COMPILE_MOD_BENCH_LLVM_1="rustc example/mod_bench.rs --crate-type bin -Copt-level=1 -o $cargo_target_dir/mod_bench_llvm_1 -Cpanic=abort"
704-
// COMPILE_MOD_BENCH_LLVM_2="rustc example/mod_bench.rs --crate-type bin -Copt-level=2 -o $cargo_target_dir/mod_bench_llvm_2 -Cpanic=abort"
705-
// COMPILE_MOD_BENCH_LLVM_3="rustc example/mod_bench.rs --crate-type bin -Copt-level=3 -o $cargo_target_dir/mod_bench_llvm_3 -Cpanic=abort"
706-
//
707-
// Use 100 runs, because a single compilations doesn't take more than ~150ms, so it isn't very slow
708-
// hyperfine --runs ${COMPILE_RUNS:-100} "$COMPILE_MOD_BENCH_INLINE" "$COMPILE_MOD_BENCH_LLVM_0" "$COMPILE_MOD_BENCH_LLVM_1" "$COMPILE_MOD_BENCH_LLVM_2" "$COMPILE_MOD_BENCH_LLVM_3"
709-
// echo "[BENCH RUN] mod_bench"
710-
// hyperfine --runs ${RUN_RUNS:-10} $cargo_target_dir/mod_bench{,_inline} $cargo_target_dir/mod_bench_llvm_*
711-
712686
fn extended_rand_tests(env: &Env, args: &TestArg) -> Result<(), String> {
713687
if !args.is_using_gcc_master_branch() {
714688
println!("Not using GCC master branch. Skipping `extended_rand_tests`.");

compiler/rustc_codegen_gcc/example/alloc_example.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
#![feature(start, core_intrinsics, alloc_error_handler, lang_items)]
1+
#![feature(core_intrinsics, alloc_error_handler, lang_items)]
22
#![no_std]
3+
#![no_main]
34
#![allow(internal_features)]
45

56
extern crate alloc;
@@ -37,8 +38,8 @@ unsafe extern "C" fn _Unwind_Resume() {
3738
core::intrinsics::unreachable();
3839
}
3940

40-
#[start]
41-
fn main(_argc: isize, _argv: *const *const u8) -> isize {
41+
#[no_mangle]
42+
extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
4243
let world: Box<&str> = Box::new("Hello World!\0");
4344
unsafe {
4445
puts(*world as *const str as *const u8);

compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
22

33
#![feature(
4-
no_core, unboxed_closures, start, lang_items, never_type, linkage,
4+
no_core, unboxed_closures, lang_items, never_type, linkage,
55
extern_types, thread_local
66
)]
77
#![no_core]

compiler/rustc_codegen_gcc/example/mod_bench.rs

-36
This file was deleted.

compiler/rustc_codegen_gcc/src/context.rs

-1
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
513513
} else {
514514
// If the symbol already exists, it is an error: for example, the user wrote
515515
// #[no_mangle] extern "C" fn main(..) {..}
516-
// instead of #[start]
517516
None
518517
}
519518
}

compiler/rustc_codegen_gcc/tests/run/abort1.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
// Run-time:
44
// status: signal
55

6-
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
6+
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
77
#![allow(internal_features)]
88

99
#![no_std]
1010
#![no_core]
11+
#![no_main]
1112

1213
/*
1314
* Core
@@ -49,7 +50,7 @@ fn test_fail() -> ! {
4950
unsafe { intrinsics::abort() };
5051
}
5152

52-
#[start]
53-
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
53+
#[no_mangle]
54+
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
5455
test_fail();
5556
}

compiler/rustc_codegen_gcc/tests/run/abort2.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
// Run-time:
44
// status: signal
55

6-
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
6+
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
77
#![allow(internal_features)]
88

99
#![no_std]
1010
#![no_core]
11+
#![no_main]
1112

1213
/*
1314
* Core
@@ -50,8 +51,8 @@ fn fail() -> i32 {
5051
0
5152
}
5253

53-
#[start]
54-
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
54+
#[no_mangle]
55+
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
5556
fail();
5657
0
5758
}

compiler/rustc_codegen_gcc/tests/run/array.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
// 5
88
// 10
99

10-
#![feature(no_core, start)]
10+
#![feature(no_core)]
1111

1212
#![no_std]
1313
#![no_core]
14+
#![no_main]
1415

1516
extern crate mini_core;
1617

@@ -28,8 +29,8 @@ fn make_array() -> [u8; 3] {
2829
[42, 10, 5]
2930
}
3031

31-
#[start]
32-
fn main(argc: isize, _argv: *const *const u8) -> isize {
32+
#[no_mangle]
33+
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
3334
let array = [42, 7, 5];
3435
let array2 = make_array();
3536
unsafe {

compiler/rustc_codegen_gcc/tests/run/assign.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
// 10
77

88
#![allow(internal_features, unused_attributes)]
9-
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
9+
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
1010

1111
#![no_std]
1212
#![no_core]
13+
#![no_main]
1314

1415
/*
1516
* Core
@@ -142,8 +143,8 @@ fn inc(num: isize) -> isize {
142143
}
143144

144145

145-
#[start]
146-
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
146+
#[no_mangle]
147+
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
147148
argc = inc(argc);
148149
unsafe {
149150
libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);

compiler/rustc_codegen_gcc/tests/run/closure.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
// Int argument: 2
99
// Both args: 11
1010

11-
#![feature(no_core, start)]
11+
#![feature(no_core)]
1212

1313
#![no_std]
1414
#![no_core]
15+
#![no_main]
1516

1617
extern crate mini_core;
1718

@@ -22,8 +23,8 @@ mod libc {
2223
}
2324
}
2425

25-
#[start]
26-
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
26+
#[no_mangle]
27+
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
2728
let string = "Arg: %d\n\0";
2829
let mut closure = || {
2930
unsafe {

compiler/rustc_codegen_gcc/tests/run/condition.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
// stdout: true
66
// 1
77

8-
#![feature(no_core, start)]
8+
#![feature(no_core)]
99

1010
#![no_std]
1111
#![no_core]
12+
#![no_main]
1213

1314
extern crate mini_core;
1415

@@ -19,8 +20,8 @@ mod libc {
1920
}
2021
}
2122

22-
#[start]
23-
fn main(argc: isize, _argv: *const *const u8) -> isize {
23+
#[no_mangle]
24+
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
2425
unsafe {
2526
if argc == 1 {
2627
libc::printf(b"true\n\0" as *const u8 as *const i8);

0 commit comments

Comments
 (0)