Skip to content

Commit f458c1e

Browse files
committed
remove support for the #[start] attribute
1 parent a1740a9 commit f458c1e

File tree

34 files changed

+47
-400
lines changed

34 files changed

+47
-400
lines changed

compiler/rustc_ast/src/entry.rs

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

compiler/rustc_ast_passes/src/feature_gate.rs

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

234-
ast::ItemKind::Fn(..) => {
235-
if attr::contains_name(&i.attrs, sym::start) {
236-
gate!(
237-
&self,
238-
start,
239-
i.span,
240-
"`#[start]` functions are experimental and their signature may change \
241-
over time"
242-
);
243-
}
244-
}
245-
246234
ast::ItemKind::Struct(..) => {
247235
for attr in attr::filter_by_name(&i.attrs, sym::repr) {
248236
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
@@ -205,11 +205,11 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
205205
ast::mut_visit::walk_item(self, item);
206206
self.depth -= 1;
207207

208-
// Remove any #[rustc_main] or #[start] from the AST so it doesn't
208+
// Remove any #[rustc_main] from the AST so it doesn't
209209
// clash with the one we're going to add, but mark it as
210210
// #[allow(dead_code)] to avoid printing warnings.
211211
match entry_point_type(&item, self.depth == 0) {
212-
EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => {
212+
EntryPointType::MainNamed | EntryPointType::RustcMainAttr => {
213213
let allow_dead_code = attr::mk_attr_nested_word(
214214
&self.sess.psess.attr_id_generator,
215215
ast::AttrStyle::Outer,
@@ -218,8 +218,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
218218
sym::dead_code,
219219
self.def_site,
220220
);
221-
item.attrs
222-
.retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start));
221+
item.attrs.retain(|attr| !attr.has_name(sym::rustc_main));
223222
item.attrs.push(allow_dead_code);
224223
}
225224
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;
66
use rustc_span::symbol::Ident;
77

@@ -15,10 +15,9 @@ pub(crate) fn maybe_create_entry_wrapper(
1515
is_jit: bool,
1616
is_primary_cgu: bool,
1717
) {
18-
let (main_def_id, (is_main_fn, sigpipe)) = match tcx.entry_fn(()) {
18+
let (main_def_id, sigpipe) = match tcx.entry_fn(()) {
1919
Some((def_id, entry_ty)) => (def_id, match entry_ty {
20-
EntryFnType::Main { sigpipe } => (true, sigpipe),
21-
EntryFnType::Start => (false, sigpipe::DEFAULT),
20+
EntryFnType::Main { sigpipe } => sigpipe,
2221
}),
2322
None => return,
2423
};
@@ -32,14 +31,13 @@ pub(crate) fn maybe_create_entry_wrapper(
3231
return;
3332
}
3433

35-
create_entry_fn(tcx, module, main_def_id, is_jit, is_main_fn, sigpipe);
34+
create_entry_fn(tcx, module, main_def_id, is_jit, sigpipe);
3635

3736
fn create_entry_fn(
3837
tcx: TyCtxt<'_>,
3938
m: &mut dyn Module,
4039
rust_main_def_id: DefId,
4140
ignore_lang_start_wrapper: bool,
42-
is_main_fn: bool,
4341
sigpipe: u8,
4442
) {
4543
let main_ret_ty = tcx.fn_sig(rust_main_def_id).no_bound_vars().unwrap().output();
@@ -95,8 +93,8 @@ pub(crate) fn maybe_create_entry_wrapper(
9593

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

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

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

compiler/rustc_codegen_ssa/src/base.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
490490
let ptr_ty = cx.type_ptr();
491491
let (arg_argc, arg_argv) = get_argc_argv(&mut bx);
492492

493-
let (start_fn, start_ty, args, instance) = if let EntryFnType::Main { sigpipe } = entry_type
494-
{
493+
let EntryFnType::Main { sigpipe } = entry_type;
494+
let (start_fn, start_ty, args, instance) = {
495495
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
496496
let start_instance = ty::Instance::expect_resolve(
497497
cx.tcx(),
@@ -512,10 +512,6 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
512512
vec![rust_main, arg_argc, arg_argv, arg_sigpipe],
513513
Some(start_instance),
514514
)
515-
} else {
516-
debug!("using user-defined start fn");
517-
let start_ty = cx.type_func(&[isize_ty, ptr_ty], isize_ty);
518-
(rust_main, start_ty, vec![arg_argc, arg_argv], None)
519515
};
520516

521517
let result = bx.call(start_ty, None, None, start_fn, &args, None, instance);
@@ -530,7 +526,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
530526
}
531527
}
532528

533-
/// Obtain the `argc` and `argv` values to pass to the rust start function.
529+
/// Obtain the `argc` and `argv` values to pass to the rust start function
530+
/// (i.e., the "start" lang item).
534531
fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(bx: &mut Bx) -> (Bx::Value, Bx::Value) {
535532
if bx.cx().sess().target.os.contains("uefi") {
536533
// Params for UEFI

compiler/rustc_error_codes/src/error_codes/E0138.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#### Note: this error code is no longer emitted by the compiler.
2+
13
More than one function was declared with the `#[start]` attribute.
24

35
Erroneous code example:

compiler/rustc_feature/src/builtin_attrs.rs

-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
447447
),
448448

449449
// Entry point:
450-
ungated!(start, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
451450
ungated!(no_start, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
452451
ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
453452

compiler/rustc_feature/src/removed.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,9 @@ declare_features! (
223223
(removed, rustc_diagnostic_macros, "1.38.0", None, None),
224224
/// Allows identifying crates that contain sanitizer runtimes.
225225
(removed, sanitizer_runtime, "1.17.0", None, None),
226-
(removed, simd, "1.0.0", Some(27731),
227-
Some("removed in favor of `#[repr(simd)]`")),
226+
(removed, simd, "1.0.0", Some(27731), Some("removed in favor of `#[repr(simd)]`")),
227+
/// Allows using `#[start]` on a function indicating that it is the program entrypoint.
228+
(removed, start, "1.0.0", Some(29633), Some("not portable enough and never RFC'd")),
228229
/// Allows `#[link(kind = "static-nobundle", ...)]`.
229230
(removed, static_nobundle, "1.16.0", Some(37403),
230231
Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#)),

compiler/rustc_feature/src/unstable.rs

-2
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,6 @@ declare_features! (
299299
(internal, rustdoc_internals, "1.58.0", Some(90418)),
300300
/// Allows using the `rustdoc::missing_doc_code_examples` lint
301301
(unstable, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730)),
302-
/// Allows using `#[start]` on a function indicating that it is the program entrypoint.
303-
(unstable, start, "1.0.0", Some(29633)),
304302
/// Allows using `#[structural_match]` which indicates that a type is structurally matchable.
305303
/// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library
306304
/// feature with the same name exists.

compiler/rustc_hir_analysis/messages.ftl

-15
Original file line numberDiff line numberDiff line change
@@ -477,21 +477,6 @@ hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is hi
477477
hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable
478478
.help = add `#![feature(min_specialization)]` to the crate attributes to enable
479479
480-
hir_analysis_start_function_parameters = `#[start]` function is not allowed to have type parameters
481-
.label = `#[start]` function cannot have type parameters
482-
483-
hir_analysis_start_function_where = `#[start]` function is not allowed to have a `where` clause
484-
.label = `#[start]` function cannot have a `where` clause
485-
486-
hir_analysis_start_not_async = `#[start]` function is not allowed to be `async`
487-
.label = `#[start]` is not allowed to be `async`
488-
489-
hir_analysis_start_not_target_feature = `#[start]` function is not allowed to have `#[target_feature]`
490-
.label = `#[start]` function is not allowed to have `#[target_feature]`
491-
492-
hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]`
493-
.label = `#[start]` function is not allowed to be `#[track_caller]`
494-
495480
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
496481
497482
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature

compiler/rustc_hir_analysis/src/check/entry.rs

+1-82
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_hir as hir;
55
use rustc_hir::Node;
66
use rustc_infer::infer::TyCtxtInferExt;
77
use rustc_middle::span_bug;
8-
use rustc_middle::ty::{self, Ty, TyCtxt, TypingMode};
8+
use rustc_middle::ty::{self, TyCtxt, TypingMode};
99
use rustc_session::config::EntryFnType;
1010
use rustc_span::Span;
1111
use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
@@ -19,7 +19,6 @@ use crate::errors;
1919
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
2020
match tcx.entry_fn(()) {
2121
Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
22-
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
2322
_ => {}
2423
}
2524
}
@@ -193,83 +192,3 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
193192
});
194193
}
195194
}
196-
197-
fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
198-
let start_def_id = start_def_id.expect_local();
199-
let start_id = tcx.local_def_id_to_hir_id(start_def_id);
200-
let start_span = tcx.def_span(start_def_id);
201-
let start_t = tcx.type_of(start_def_id).instantiate_identity();
202-
match start_t.kind() {
203-
ty::FnDef(..) => {
204-
if let Node::Item(it) = tcx.hir_node(start_id) {
205-
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
206-
let mut error = false;
207-
if !generics.params.is_empty() {
208-
tcx.dcx().emit_err(errors::StartFunctionParameters { span: generics.span });
209-
error = true;
210-
}
211-
if generics.has_where_clause_predicates {
212-
tcx.dcx().emit_err(errors::StartFunctionWhere {
213-
span: generics.where_clause_span,
214-
});
215-
error = true;
216-
}
217-
if sig.header.asyncness.is_async() {
218-
let span = tcx.def_span(it.owner_id);
219-
tcx.dcx().emit_err(errors::StartAsync { span });
220-
error = true;
221-
}
222-
223-
let attrs = tcx.hir().attrs(start_id);
224-
for attr in attrs {
225-
if attr.has_name(sym::track_caller) {
226-
tcx.dcx().emit_err(errors::StartTrackCaller {
227-
span: attr.span,
228-
start: start_span,
229-
});
230-
error = true;
231-
}
232-
if attr.has_name(sym::target_feature)
233-
// Calling functions with `#[target_feature]` is
234-
// not unsafe on WASM, see #84988
235-
&& !tcx.sess.target.is_like_wasm
236-
&& !tcx.sess.opts.actually_rustdoc
237-
{
238-
tcx.dcx().emit_err(errors::StartTargetFeature {
239-
span: attr.span,
240-
start: start_span,
241-
});
242-
error = true;
243-
}
244-
}
245-
246-
if error {
247-
return;
248-
}
249-
}
250-
}
251-
252-
let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
253-
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
254-
tcx.types.isize,
255-
false,
256-
hir::Safety::Safe,
257-
ExternAbi::Rust,
258-
));
259-
260-
let _ = check_function_signature(
261-
tcx,
262-
ObligationCause::new(
263-
start_span,
264-
start_def_id,
265-
ObligationCauseCode::StartFunctionType,
266-
),
267-
start_def_id.into(),
268-
expected_sig,
269-
);
270-
}
271-
_ => {
272-
span_bug!(start_span, "start has a non-function type: found `{}`", start_t);
273-
}
274-
}
275-
}

compiler/rustc_hir_analysis/src/errors.rs

-42
Original file line numberDiff line numberDiff line change
@@ -620,48 +620,6 @@ pub(crate) struct TargetFeatureOnMain {
620620
pub main: Span,
621621
}
622622

623-
#[derive(Diagnostic)]
624-
#[diag(hir_analysis_start_not_track_caller)]
625-
pub(crate) struct StartTrackCaller {
626-
#[primary_span]
627-
pub span: Span,
628-
#[label]
629-
pub start: Span,
630-
}
631-
632-
#[derive(Diagnostic)]
633-
#[diag(hir_analysis_start_not_target_feature)]
634-
pub(crate) struct StartTargetFeature {
635-
#[primary_span]
636-
pub span: Span,
637-
#[label]
638-
pub start: Span,
639-
}
640-
641-
#[derive(Diagnostic)]
642-
#[diag(hir_analysis_start_not_async, code = E0752)]
643-
pub(crate) struct StartAsync {
644-
#[primary_span]
645-
#[label]
646-
pub span: Span,
647-
}
648-
649-
#[derive(Diagnostic)]
650-
#[diag(hir_analysis_start_function_where, code = E0647)]
651-
pub(crate) struct StartFunctionWhere {
652-
#[primary_span]
653-
#[label]
654-
pub span: Span,
655-
}
656-
657-
#[derive(Diagnostic)]
658-
#[diag(hir_analysis_start_function_parameters, code = E0132)]
659-
pub(crate) struct StartFunctionParameters {
660-
#[primary_span]
661-
#[label]
662-
pub span: Span,
663-
}
664-
665623
#[derive(Diagnostic)]
666624
#[diag(hir_analysis_main_function_return_type_generic, code = E0131)]
667625
pub(crate) struct MainFunctionReturnTypeGeneric {

compiler/rustc_passes/messages.ftl

-5
Original file line numberDiff line numberDiff line change
@@ -496,11 +496,6 @@ passes_multiple_rustc_main =
496496
.first = first `#[rustc_main]` function
497497
.additional = additional `#[rustc_main]` function
498498
499-
passes_multiple_start_functions =
500-
multiple `start` functions
501-
.label = multiple `start` functions
502-
.previous = previous `#[start]` function here
503-
504499
passes_must_not_suspend =
505500
`must_not_suspend` attribute should be applied to a struct, enum, union, or trait
506501
.label = is not a struct, enum, union, or trait

0 commit comments

Comments
 (0)