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:
commit
ed43cbcb88
176 changed files with 454 additions and 1260 deletions
|
@ -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::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
|
||||
use rustc_span::{Span, sym};
|
||||
|
@ -18,7 +18,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),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -192,83 +191,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -619,48 +619,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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue