Skip to content

Commit

Permalink
remove support for the #[start] attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Dec 14, 2024
1 parent a1740a9 commit 6d6693a
Show file tree
Hide file tree
Showing 24 changed files with 15 additions and 300 deletions.
10 changes: 1 addition & 9 deletions compiler/rustc_ast/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ pub enum EntryPointType {
/// fn main() {}
/// ```
RustcMainAttr,
/// This is a function with the `#[start]` attribute.
/// ```ignore (clashes with test entrypoint)
/// #[start]
/// fn main() {}
/// ```
Start,
/// This function is **not** an entrypoint but simply named `main` (not at the root).
/// This is only used for diagnostics.
/// ```
Expand All @@ -41,9 +35,7 @@ pub fn entry_point_type(
at_root: bool,
name: Option<Symbol>,
) -> EntryPointType {
if attr::contains_name(attrs, sym::start) {
EntryPointType::Start
} else if attr::contains_name(attrs, sym::rustc_main) {
if attr::contains_name(attrs, sym::rustc_main) {
EntryPointType::RustcMainAttr
} else if let Some(name) = name
&& name == sym::main
Expand Down
12 changes: 0 additions & 12 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,18 +231,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}

ast::ItemKind::Fn(..) => {
if attr::contains_name(&i.attrs, sym::start) {
gate!(
&self,
start,
i.span,
"`#[start]` functions are experimental and their signature may change \
over time"
);
}
}

ast::ItemKind::Struct(..) => {
for attr in attr::filter_by_name(&i.attrs, sym::repr) {
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_builtin_macros/src/test_harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
ast::mut_visit::walk_item(self, item);
self.depth -= 1;

// Remove any #[rustc_main] or #[start] from the AST so it doesn't
// Remove any #[rustc_main] from the AST so it doesn't
// clash with the one we're going to add, but mark it as
// #[allow(dead_code)] to avoid printing warnings.
match entry_point_type(&item, self.depth == 0) {
EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => {
EntryPointType::MainNamed | EntryPointType::RustcMainAttr => {
let allow_dead_code = attr::mk_attr_nested_word(
&self.sess.psess.attr_id_generator,
ast::AttrStyle::Outer,
Expand All @@ -218,8 +218,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
sym::dead_code,
self.def_site,
);
item.attrs
.retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start));
item.attrs.retain(|attr| !attr.has_name(sym::rustc_main));
item.attrs.push(allow_dead_code);
}
EntryPointType::None | EntryPointType::OtherMain => {}
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let ptr_ty = cx.type_ptr();
let (arg_argc, arg_argv) = get_argc_argv(&mut bx);

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

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

/// Obtain the `argc` and `argv` values to pass to the rust start function.
/// Obtain the `argc` and `argv` values to pass to the rust start function
/// (i.e., the "start" lang item).
fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(bx: &mut Bx) -> (Bx::Value, Bx::Value) {
if bx.cx().sess().target.os.contains("uefi") {
// Params for UEFI
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0138.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#### Note: this error code is no longer emitted by the compiler.

More than one function was declared with the `#[start]` attribute.

Erroneous code example:
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),

// Entry point:
ungated!(start, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(no_start, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),

Expand Down
15 changes: 0 additions & 15 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -477,21 +477,6 @@ hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is hi
hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable
.help = add `#![feature(min_specialization)]` to the crate attributes to enable
hir_analysis_start_function_parameters = `#[start]` function is not allowed to have type parameters
.label = `#[start]` function cannot have type parameters
hir_analysis_start_function_where = `#[start]` function is not allowed to have a `where` clause
.label = `#[start]` function cannot have a `where` clause
hir_analysis_start_not_async = `#[start]` function is not allowed to be `async`
.label = `#[start]` is not allowed to be `async`
hir_analysis_start_not_target_feature = `#[start]` function is not allowed to have `#[target_feature]`
.label = `#[start]` function is not allowed to have `#[target_feature]`
hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]`
.label = `#[start]` function is not allowed to be `#[track_caller]`
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
Expand Down
83 changes: 1 addition & 82 deletions compiler/rustc_hir_analysis/src/check/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_hir as hir;
use rustc_hir::Node;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt, TypingMode};
use rustc_middle::ty::{self, TyCtxt, TypingMode};
use rustc_session::config::EntryFnType;
use rustc_span::Span;
use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
Expand All @@ -19,7 +19,6 @@ use crate::errors;
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
match tcx.entry_fn(()) {
Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
_ => {}
}
}
Expand Down Expand Up @@ -193,83 +192,3 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
});
}
}

fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
let start_def_id = start_def_id.expect_local();
let start_id = tcx.local_def_id_to_hir_id(start_def_id);
let start_span = tcx.def_span(start_def_id);
let start_t = tcx.type_of(start_def_id).instantiate_identity();
match start_t.kind() {
ty::FnDef(..) => {
if let Node::Item(it) = tcx.hir_node(start_id) {
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
let mut error = false;
if !generics.params.is_empty() {
tcx.dcx().emit_err(errors::StartFunctionParameters { span: generics.span });
error = true;
}
if generics.has_where_clause_predicates {
tcx.dcx().emit_err(errors::StartFunctionWhere {
span: generics.where_clause_span,
});
error = true;
}
if sig.header.asyncness.is_async() {
let span = tcx.def_span(it.owner_id);
tcx.dcx().emit_err(errors::StartAsync { span });
error = true;
}

let attrs = tcx.hir().attrs(start_id);
for attr in attrs {
if attr.has_name(sym::track_caller) {
tcx.dcx().emit_err(errors::StartTrackCaller {
span: attr.span,
start: start_span,
});
error = true;
}
if attr.has_name(sym::target_feature)
// Calling functions with `#[target_feature]` is
// not unsafe on WASM, see #84988
&& !tcx.sess.target.is_like_wasm
&& !tcx.sess.opts.actually_rustdoc
{
tcx.dcx().emit_err(errors::StartTargetFeature {
span: attr.span,
start: start_span,
});
error = true;
}
}

if error {
return;
}
}
}

let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
[tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
tcx.types.isize,
false,
hir::Safety::Safe,
ExternAbi::Rust,
));

let _ = check_function_signature(
tcx,
ObligationCause::new(
start_span,
start_def_id,
ObligationCauseCode::StartFunctionType,
),
start_def_id.into(),
expected_sig,
);
}
_ => {
span_bug!(start_span, "start has a non-function type: found `{}`", start_t);
}
}
}
42 changes: 0 additions & 42 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,48 +620,6 @@ pub(crate) struct TargetFeatureOnMain {
pub main: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_start_not_track_caller)]
pub(crate) struct StartTrackCaller {
#[primary_span]
pub span: Span,
#[label]
pub start: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_start_not_target_feature)]
pub(crate) struct StartTargetFeature {
#[primary_span]
pub span: Span,
#[label]
pub start: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_start_not_async, code = E0752)]
pub(crate) struct StartAsync {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_start_function_where, code = E0647)]
pub(crate) struct StartFunctionWhere {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_start_function_parameters, code = E0132)]
pub(crate) struct StartFunctionParameters {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_main_function_return_type_generic, code = E0131)]
pub(crate) struct MainFunctionReturnTypeGeneric {
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -496,11 +496,6 @@ passes_multiple_rustc_main =
.first = first `#[rustc_main]` function
.additional = additional `#[rustc_main]` function
passes_multiple_start_functions =
multiple `start` functions
.label = multiple `start` functions
.previous = previous `#[start]` function here
passes_must_not_suspend =
`must_not_suspend` attribute should be applied to a struct, enum, union, or trait
.label = is not a struct, enum, union, or trait
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::lang
| sym::needs_allocator
| sym::default_lib_allocator
| sym::start
| sym::custom_mir,
..
] => {}
Expand Down Expand Up @@ -2559,7 +2558,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
sym::repr,
sym::path,
sym::automatically_derived,
sym::start,
sym::rustc_main,
sym::derive,
sym::test,
Expand Down
27 changes: 4 additions & 23 deletions compiler/rustc_passes/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,14 @@ use rustc_session::config::{CrateType, EntryFnType, RemapPathScopeComponents, si
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};

use crate::errors::{
AttrOnlyInFunctions, ExternMain, MultipleRustcMain, MultipleStartFunctions, NoMainErr,
};
use crate::errors::{AttrOnlyInFunctions, ExternMain, MultipleRustcMain, NoMainErr};

struct EntryContext<'tcx> {
tcx: TyCtxt<'tcx>,

/// The function has the `#[rustc_main]` attribute.
rustc_main_fn: Option<(LocalDefId, Span)>,

/// The function that has the attribute `#[start]` on it.
start_fn: Option<(LocalDefId, Span)>,

/// The functions that one might think are `main` but aren't, e.g.
/// main functions not defined at the top level. For diagnostics.
non_main_fns: Vec<Span>,
Expand All @@ -41,8 +36,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
return None;
}

let mut ctxt =
EntryContext { tcx, rustc_main_fn: None, start_fn: None, non_main_fns: Vec::new() };
let mut ctxt = EntryContext { tcx, rustc_main_fn: None, non_main_fns: Vec::new() };

for id in tcx.hir().items() {
check_and_search_item(id, &mut ctxt);
Expand All @@ -58,7 +52,7 @@ fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Opti

fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) {
for attr in [sym::start, sym::rustc_main] {
for attr in [sym::rustc_main] {
if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
ctxt.tcx.dcx().emit_err(AttrOnlyInFunctions { span, attr });
}
Expand Down Expand Up @@ -92,24 +86,11 @@ fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
});
}
}
EntryPointType::Start => {
if ctxt.start_fn.is_none() {
ctxt.start_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
} else {
ctxt.tcx.dcx().emit_err(MultipleStartFunctions {
span: ctxt.tcx.def_span(id.owner_id),
labeled: ctxt.tcx.def_span(id.owner_id.to_def_id()),
previous: ctxt.start_fn.unwrap().1,
});
}
}
}
}

fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
if let Some((def_id, _)) = visitor.start_fn {
Some((def_id.to_def_id(), EntryFnType::Start))
} else if let Some((local_def_id, _)) = visitor.rustc_main_fn {
if let Some((local_def_id, _)) = visitor.rustc_main_fn {
let def_id = local_def_id.to_def_id();
Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }))
} else {
Expand Down
11 changes: 0 additions & 11 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1273,17 +1273,6 @@ pub(crate) struct MultipleRustcMain {
pub additional: Span,
}

#[derive(Diagnostic)]
#[diag(passes_multiple_start_functions, code = E0138)]
pub(crate) struct MultipleStartFunctions {
#[primary_span]
pub span: Span,
#[label]
pub labeled: Span,
#[label(passes_previous)]
pub previous: Span,
}

#[derive(Diagnostic)]
#[diag(passes_extern_main)]
pub(crate) struct ExternMain {
Expand Down
Loading

0 comments on commit 6d6693a

Please sign in to comment.