mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 03:38:29 +00:00
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
@ -18,12 +18,6 @@ pub enum EntryPointType {
|
|||||||
/// fn main() {}
|
/// fn main() {}
|
||||||
/// ```
|
/// ```
|
||||||
RustcMainAttr,
|
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 function is **not** an entrypoint but simply named `main` (not at the root).
|
||||||
/// This is only used for diagnostics.
|
/// This is only used for diagnostics.
|
||||||
/// ```
|
/// ```
|
||||||
@ -40,9 +34,7 @@ pub fn entry_point_type(
|
|||||||
at_root: bool,
|
at_root: bool,
|
||||||
name: Option<Symbol>,
|
name: Option<Symbol>,
|
||||||
) -> EntryPointType {
|
) -> EntryPointType {
|
||||||
if attr::contains_name(attrs, sym::start) {
|
if attr::contains_name(attrs, sym::rustc_main) {
|
||||||
EntryPointType::Start
|
|
||||||
} else if attr::contains_name(attrs, sym::rustc_main) {
|
|
||||||
EntryPointType::RustcMainAttr
|
EntryPointType::RustcMainAttr
|
||||||
} else if let Some(name) = name
|
} else if let Some(name) = name
|
||||||
&& name == sym::main
|
&& name == sym::main
|
||||||
|
@ -230,18 +230,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(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Union(..) => {
|
ast::ItemKind::Struct(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Union(..) => {
|
||||||
for attr in attr::filter_by_name(&i.attrs, sym::repr) {
|
for attr in attr::filter_by_name(&i.attrs, sym::repr) {
|
||||||
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
|
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
|
||||||
|
@ -204,11 +204,11 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
|
|||||||
ast::mut_visit::walk_item(self, item);
|
ast::mut_visit::walk_item(self, item);
|
||||||
self.depth -= 1;
|
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
|
// clash with the one we're going to add, but mark it as
|
||||||
// #[allow(dead_code)] to avoid printing warnings.
|
// #[allow(dead_code)] to avoid printing warnings.
|
||||||
match entry_point_type(&item, self.depth == 0) {
|
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(
|
let allow_dead_code = attr::mk_attr_nested_word(
|
||||||
&self.sess.psess.attr_id_generator,
|
&self.sess.psess.attr_id_generator,
|
||||||
ast::AttrStyle::Outer,
|
ast::AttrStyle::Outer,
|
||||||
@ -217,8 +217,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
|
|||||||
sym::dead_code,
|
sym::dead_code,
|
||||||
self.def_site,
|
self.def_site,
|
||||||
);
|
);
|
||||||
item.attrs
|
item.attrs.retain(|attr| !attr.has_name(sym::rustc_main));
|
||||||
.retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start));
|
|
||||||
item.attrs.push(allow_dead_code);
|
item.attrs.push(allow_dead_code);
|
||||||
}
|
}
|
||||||
EntryPointType::None | EntryPointType::OtherMain => {}
|
EntryPointType::None | EntryPointType::OtherMain => {}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
|
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
|
||||||
use rustc_hir::LangItem;
|
use rustc_hir::LangItem;
|
||||||
use rustc_middle::ty::{AssocKind, GenericArg};
|
use rustc_middle::ty::{AssocKind, GenericArg};
|
||||||
use rustc_session::config::{EntryFnType, sigpipe};
|
use rustc_session::config::EntryFnType;
|
||||||
use rustc_span::{DUMMY_SP, Ident};
|
use rustc_span::{DUMMY_SP, Ident};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
@ -14,10 +14,9 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||||||
is_jit: bool,
|
is_jit: bool,
|
||||||
is_primary_cgu: bool,
|
is_primary_cgu: bool,
|
||||||
) {
|
) {
|
||||||
let (main_def_id, (is_main_fn, sigpipe)) = match tcx.entry_fn(()) {
|
let (main_def_id, sigpipe) = match tcx.entry_fn(()) {
|
||||||
Some((def_id, entry_ty)) => (def_id, match entry_ty {
|
Some((def_id, entry_ty)) => (def_id, match entry_ty {
|
||||||
EntryFnType::Main { sigpipe } => (true, sigpipe),
|
EntryFnType::Main { sigpipe } => sigpipe,
|
||||||
EntryFnType::Start => (false, sigpipe::DEFAULT),
|
|
||||||
}),
|
}),
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
@ -31,14 +30,13 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_entry_fn(tcx, module, main_def_id, is_jit, is_main_fn, sigpipe);
|
create_entry_fn(tcx, module, main_def_id, is_jit, sigpipe);
|
||||||
|
|
||||||
fn create_entry_fn(
|
fn create_entry_fn(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
m: &mut dyn Module,
|
m: &mut dyn Module,
|
||||||
rust_main_def_id: DefId,
|
rust_main_def_id: DefId,
|
||||||
ignore_lang_start_wrapper: bool,
|
ignore_lang_start_wrapper: bool,
|
||||||
is_main_fn: bool,
|
|
||||||
sigpipe: u8,
|
sigpipe: u8,
|
||||||
) {
|
) {
|
||||||
let main_ret_ty = tcx.fn_sig(rust_main_def_id).no_bound_vars().unwrap().output();
|
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(
|
|||||||
|
|
||||||
let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func);
|
let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func);
|
||||||
|
|
||||||
let result = if is_main_fn && ignore_lang_start_wrapper {
|
let result = if ignore_lang_start_wrapper {
|
||||||
// regular main fn, but ignoring #[lang = "start"] as we are running in the jit
|
// ignoring #[lang = "start"] as we are running in the jit
|
||||||
// FIXME set program arguments somehow
|
// FIXME set program arguments somehow
|
||||||
let call_inst = bcx.ins().call(main_func_ref, &[]);
|
let call_inst = bcx.ins().call(main_func_ref, &[]);
|
||||||
let call_results = bcx.func.dfg.inst_results(call_inst).to_owned();
|
let call_results = bcx.func.dfg.inst_results(call_inst).to_owned();
|
||||||
@ -133,7 +131,8 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||||||
types::I64 => bcx.ins().sextend(types::I64, res),
|
types::I64 => bcx.ins().sextend(types::I64, res),
|
||||||
_ => unimplemented!("16bit systems are not yet supported"),
|
_ => unimplemented!("16bit systems are not yet supported"),
|
||||||
}
|
}
|
||||||
} else if is_main_fn {
|
} else {
|
||||||
|
// Regular main fn invoked via start lang item.
|
||||||
let start_def_id = tcx.require_lang_item(LangItem::Start, None);
|
let start_def_id = tcx.require_lang_item(LangItem::Start, None);
|
||||||
let start_instance = Instance::expect_resolve(
|
let start_instance = Instance::expect_resolve(
|
||||||
tcx,
|
tcx,
|
||||||
@ -150,10 +149,6 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||||||
let call_inst =
|
let call_inst =
|
||||||
bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv, arg_sigpipe]);
|
bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv, arg_sigpipe]);
|
||||||
bcx.inst_results(call_inst)[0]
|
bcx.inst_results(call_inst)[0]
|
||||||
} else {
|
|
||||||
// using user-defined start fn
|
|
||||||
let call_inst = bcx.ins().call(main_func_ref, &[arg_argc, arg_argv]);
|
|
||||||
bcx.inst_results(call_inst)[0]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bcx.ins().return_(&[result]);
|
bcx.ins().return_(&[result]);
|
||||||
|
@ -426,19 +426,6 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> {
|
|||||||
run_command_with_env(&command, None, Some(env))?;
|
run_command_with_env(&command, None, Some(env))?;
|
||||||
maybe_run_command_in_vm(&[&cargo_target_dir.join("track-caller-attribute")], env, args)?;
|
maybe_run_command_in_vm(&[&cargo_target_dir.join("track-caller-attribute")], env, args)?;
|
||||||
|
|
||||||
// FIXME: create a function "display_if_not_quiet" or something along the line.
|
|
||||||
println!("[AOT] mod_bench");
|
|
||||||
let mut command = args.config_info.rustc_command_vec();
|
|
||||||
command.extend_from_slice(&[
|
|
||||||
&"example/mod_bench.rs",
|
|
||||||
&"--crate-type",
|
|
||||||
&"bin",
|
|
||||||
&"--target",
|
|
||||||
&args.config_info.target_triple,
|
|
||||||
]);
|
|
||||||
run_command_with_env(&command, None, Some(env))?;
|
|
||||||
// FIXME: the compiled binary is not run.
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,19 +683,6 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// echo "[BENCH COMPILE] mod_bench"
|
|
||||||
//
|
|
||||||
// COMPILE_MOD_BENCH_INLINE="$RUSTC example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline"
|
|
||||||
// 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"
|
|
||||||
// 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"
|
|
||||||
// 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"
|
|
||||||
// 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"
|
|
||||||
//
|
|
||||||
// Use 100 runs, because a single compilations doesn't take more than ~150ms, so it isn't very slow
|
|
||||||
// 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"
|
|
||||||
// echo "[BENCH RUN] mod_bench"
|
|
||||||
// hyperfine --runs ${RUN_RUNS:-10} $cargo_target_dir/mod_bench{,_inline} $cargo_target_dir/mod_bench_llvm_*
|
|
||||||
|
|
||||||
fn extended_rand_tests(env: &Env, args: &TestArg) -> Result<(), String> {
|
fn extended_rand_tests(env: &Env, args: &TestArg) -> Result<(), String> {
|
||||||
if !args.is_using_gcc_master_branch() {
|
if !args.is_using_gcc_master_branch() {
|
||||||
println!("Not using GCC master branch. Skipping `extended_rand_tests`.");
|
println!("Not using GCC master branch. Skipping `extended_rand_tests`.");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![feature(start, core_intrinsics, alloc_error_handler, lang_items)]
|
#![feature(core_intrinsics, alloc_error_handler, lang_items)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
@ -37,8 +38,8 @@ unsafe extern "C" fn _Unwind_Resume() {
|
|||||||
core::intrinsics::unreachable();
|
core::intrinsics::unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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 {
|
||||||
let world: Box<&str> = Box::new("Hello World!\0");
|
let world: Box<&str> = Box::new("Hello World!\0");
|
||||||
unsafe {
|
unsafe {
|
||||||
puts(*world as *const str as *const u8);
|
puts(*world as *const str as *const u8);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
|
// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
|
||||||
|
|
||||||
#![feature(
|
#![feature(
|
||||||
no_core, unboxed_closures, start, lang_items, never_type, linkage,
|
no_core, unboxed_closures, lang_items, never_type, linkage,
|
||||||
extern_types, thread_local
|
extern_types, thread_local
|
||||||
)]
|
)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
#![feature(start, core_intrinsics, lang_items)]
|
|
||||||
#![no_std]
|
|
||||||
#![allow(internal_features)]
|
|
||||||
|
|
||||||
#[link(name = "c")]
|
|
||||||
extern "C" {}
|
|
||||||
|
|
||||||
#[panic_handler]
|
|
||||||
fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! {
|
|
||||||
core::intrinsics::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[lang="eh_personality"]
|
|
||||||
fn eh_personality(){}
|
|
||||||
|
|
||||||
// Required for rustc_codegen_llvm
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn _Unwind_Resume() {
|
|
||||||
core::intrinsics::unreachable();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
|
||||||
for i in 2..100_000_000 {
|
|
||||||
black_box((i + 1) % i);
|
|
||||||
}
|
|
||||||
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(never)]
|
|
||||||
fn black_box(i: u32) {
|
|
||||||
if i != 1 {
|
|
||||||
core::intrinsics::abort();
|
|
||||||
}
|
|
||||||
}
|
|
@ -513,7 +513,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
// If the symbol already exists, it is an error: for example, the user wrote
|
// If the symbol already exists, it is an error: for example, the user wrote
|
||||||
// #[no_mangle] extern "C" fn main(..) {..}
|
// #[no_mangle] extern "C" fn main(..) {..}
|
||||||
// instead of #[start]
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
// Run-time:
|
// Run-time:
|
||||||
// status: signal
|
// status: signal
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -49,7 +50,7 @@ fn test_fail() -> ! {
|
|||||||
unsafe { intrinsics::abort() };
|
unsafe { intrinsics::abort() };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
test_fail();
|
test_fail();
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
// Run-time:
|
// Run-time:
|
||||||
// status: signal
|
// status: signal
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -50,8 +51,8 @@ fn fail() -> i32 {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
fail();
|
fail();
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,11 @@
|
|||||||
// 5
|
// 5
|
||||||
// 10
|
// 10
|
||||||
|
|
||||||
#![feature(no_core, start)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern crate mini_core;
|
extern crate mini_core;
|
||||||
|
|
||||||
@ -28,8 +29,8 @@ fn make_array() -> [u8; 3] {
|
|||||||
[42, 10, 5]
|
[42, 10, 5]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
let array = [42, 7, 5];
|
let array = [42, 7, 5];
|
||||||
let array2 = make_array();
|
let array2 = make_array();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -6,10 +6,11 @@
|
|||||||
// 10
|
// 10
|
||||||
|
|
||||||
#![allow(internal_features, unused_attributes)]
|
#![allow(internal_features, unused_attributes)]
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -142,8 +143,8 @@ fn inc(num: isize) -> isize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
argc = inc(argc);
|
argc = inc(argc);
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);
|
libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);
|
||||||
|
@ -8,10 +8,11 @@
|
|||||||
// Int argument: 2
|
// Int argument: 2
|
||||||
// Both args: 11
|
// Both args: 11
|
||||||
|
|
||||||
#![feature(no_core, start)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern crate mini_core;
|
extern crate mini_core;
|
||||||
|
|
||||||
@ -22,8 +23,8 @@ mod libc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
let string = "Arg: %d\n\0";
|
let string = "Arg: %d\n\0";
|
||||||
let mut closure = || {
|
let mut closure = || {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -5,10 +5,11 @@
|
|||||||
// stdout: true
|
// stdout: true
|
||||||
// 1
|
// 1
|
||||||
|
|
||||||
#![feature(no_core, start)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern crate mini_core;
|
extern crate mini_core;
|
||||||
|
|
||||||
@ -19,8 +20,8 @@ mod libc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
if argc == 1 {
|
if argc == 1 {
|
||||||
libc::printf(b"true\n\0" as *const u8 as *const i8);
|
libc::printf(b"true\n\0" as *const u8 as *const i8);
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
// Run-time:
|
// Run-time:
|
||||||
// status: 0
|
// status: 0
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start)]
|
#![feature(auto_traits, lang_items, no_core)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {}
|
|||||||
* Code
|
* Code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
// Run-time:
|
// Run-time:
|
||||||
// status: 2
|
// status: 2
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
mod libc {
|
mod libc {
|
||||||
#[link(name = "c")]
|
#[link(name = "c")]
|
||||||
@ -41,8 +42,8 @@ pub(crate) unsafe auto trait Freeze {}
|
|||||||
* Code
|
* Code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::exit(2);
|
libc::exit(2);
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
// Run-time:
|
// Run-time:
|
||||||
// status: 1
|
// status: 1
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start)]
|
#![feature(auto_traits, lang_items, no_core)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {}
|
|||||||
* Code
|
* Code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
// status: 0
|
// status: 0
|
||||||
// stdout: 1
|
// stdout: 1
|
||||||
|
|
||||||
#![feature(no_core, start)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern crate mini_core;
|
extern crate mini_core;
|
||||||
|
|
||||||
@ -26,8 +27,8 @@ fn call_func(func: fn(i16) -> i8, param: i16) -> i8 {
|
|||||||
func(param)
|
func(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let result = call_func(i16_as_i8, argc as i16) as isize;
|
let result = call_func(i16_as_i8, argc as i16) as isize;
|
||||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, result);
|
libc::printf(b"%ld\n\0" as *const u8 as *const i8, result);
|
||||||
|
@ -8,10 +8,11 @@
|
|||||||
// 11
|
// 11
|
||||||
|
|
||||||
#![allow(internal_features, unused_attributes)]
|
#![allow(internal_features, unused_attributes)]
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -148,8 +149,8 @@ fn update_num(num: &mut isize) {
|
|||||||
*num = *num + 5;
|
*num = *num + 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
let mut test = test(argc);
|
let mut test = test(argc);
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field);
|
libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field);
|
||||||
|
@ -6,10 +6,11 @@
|
|||||||
// 10
|
// 10
|
||||||
|
|
||||||
#![allow(internal_features, unused_attributes)]
|
#![allow(internal_features, unused_attributes)]
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types, rustc_attrs)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics, arbitrary_self_types, rustc_attrs)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -231,8 +232,8 @@ pub fn panic_const_mul_overflow() -> ! {
|
|||||||
* Code
|
* Code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 + argc);
|
libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 + argc);
|
||||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 - argc);
|
libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 - argc);
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
// status: 0
|
// status: 0
|
||||||
// stdout: 1
|
// stdout: 1
|
||||||
|
|
||||||
#![feature(no_core, start)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern crate mini_core;
|
extern crate mini_core;
|
||||||
|
|
||||||
@ -24,8 +25,8 @@ fn make_array() -> [u8; 3] {
|
|||||||
[42, 10, 5]
|
[42, 10, 5]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = ONE as *mut usize;
|
let ptr = ONE as *mut usize;
|
||||||
let value = ptr as usize;
|
let value = ptr as usize;
|
||||||
|
@ -6,11 +6,12 @@
|
|||||||
// 10
|
// 10
|
||||||
// 42
|
// 42
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
#[lang = "copy"]
|
#[lang = "copy"]
|
||||||
pub unsafe trait Copy {}
|
pub unsafe trait Copy {}
|
||||||
@ -61,8 +62,8 @@ fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u3
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
let (a, b, c, d, e, f, g, h, i, j) = int_cast(10, 42);
|
let (a, b, c, d, e, f, g, h, i, j) = int_cast(10, 42);
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::printf(b"%d\n\0" as *const u8 as *const i8, c);
|
libc::printf(b"%d\n\0" as *const u8 as *const i8, c);
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
// status: 0
|
// status: 0
|
||||||
// stdout: 5
|
// stdout: 5
|
||||||
|
|
||||||
#![feature(no_core, start)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern crate mini_core;
|
extern crate mini_core;
|
||||||
|
|
||||||
@ -26,8 +27,8 @@ fn index_slice(s: &[u32]) -> u32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
let array = [42, 7, 5];
|
let array = [42, 7, 5];
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, index_slice(&array));
|
libc::printf(b"%ld\n\0" as *const u8 as *const i8, index_slice(&array));
|
||||||
|
@ -9,11 +9,12 @@
|
|||||||
// 12
|
// 12
|
||||||
// 1
|
// 1
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -98,8 +99,8 @@ static mut WITH_REF: WithRef = WithRef {
|
|||||||
refe: unsafe { &TEST },
|
refe: unsafe { &TEST },
|
||||||
};
|
};
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, CONSTANT);
|
libc::printf(b"%ld\n\0" as *const u8 as *const i8, CONSTANT);
|
||||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field);
|
libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field);
|
||||||
|
@ -5,11 +5,12 @@
|
|||||||
// stdout: 1
|
// stdout: 1
|
||||||
// 2
|
// 2
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -55,8 +56,8 @@ fn one() -> isize {
|
|||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
let test = Test {
|
let test = Test {
|
||||||
field: one(),
|
field: one(),
|
||||||
};
|
};
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
// status: 0
|
// status: 0
|
||||||
// stdout: 3
|
// stdout: 3
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, intrinsics)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core
|
* Core
|
||||||
@ -42,8 +43,8 @@ mod libc {
|
|||||||
* Code
|
* Code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
let test: (isize, isize, isize) = (3, 1, 4);
|
let test: (isize, isize, isize) = (3, 1, 4);
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.0);
|
libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.0);
|
||||||
|
@ -751,7 +751,6 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
// If the symbol already exists, it is an error: for example, the user wrote
|
// If the symbol already exists, it is an error: for example, the user wrote
|
||||||
// #[no_mangle] extern "C" fn main(..) {..}
|
// #[no_mangle] extern "C" fn main(..) {..}
|
||||||
// instead of #[start]
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but
|
|||||||
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
|
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
|
||||||
|
|
||||||
codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times
|
codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times
|
||||||
.help = did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead
|
.help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point
|
||||||
|
|
||||||
codegen_ssa_no_field = no field `{$name}`
|
codegen_ssa_no_field = no field `{$name}`
|
||||||
|
|
||||||
|
@ -490,8 +490,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||||||
let ptr_ty = cx.type_ptr();
|
let ptr_ty = cx.type_ptr();
|
||||||
let (arg_argc, arg_argv) = get_argc_argv(&mut bx);
|
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_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
|
||||||
let start_instance = ty::Instance::expect_resolve(
|
let start_instance = ty::Instance::expect_resolve(
|
||||||
cx.tcx(),
|
cx.tcx(),
|
||||||
@ -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],
|
vec![rust_main, arg_argc, arg_argv, arg_sigpipe],
|
||||||
Some(start_instance),
|
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);
|
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>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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) {
|
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") {
|
if bx.cx().sess().target.os.contains("uefi") {
|
||||||
// Params for UEFI
|
// Params for UEFI
|
||||||
|
@ -1,32 +1,3 @@
|
|||||||
|
#### Note: this error code is no longer emitted by the compiler.
|
||||||
|
|
||||||
A function with the `start` attribute was declared with type parameters.
|
A function with the `start` attribute was declared with type parameters.
|
||||||
|
|
||||||
Erroneous code example:
|
|
||||||
|
|
||||||
```compile_fail,E0132
|
|
||||||
#![feature(start)]
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn f<T>() {}
|
|
||||||
```
|
|
||||||
|
|
||||||
It is not possible to declare type parameters on a function that has the `start`
|
|
||||||
attribute. Such a function must have the following type signature (for more
|
|
||||||
information, view [the unstable book][1]):
|
|
||||||
|
|
||||||
[1]: https://doc.rust-lang.org/unstable-book/language-features/start.html
|
|
||||||
|
|
||||||
```
|
|
||||||
# let _:
|
|
||||||
fn(isize, *const *const u8) -> isize;
|
|
||||||
```
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
#![feature(start)]
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn my_start(argc: isize, argv: *const *const u8) -> isize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
@ -1,25 +1,3 @@
|
|||||||
|
#### Note: this error code is no longer emitted by the compiler.
|
||||||
|
|
||||||
More than one function was declared with the `#[start]` attribute.
|
More than one function was declared with the `#[start]` attribute.
|
||||||
|
|
||||||
Erroneous code example:
|
|
||||||
|
|
||||||
```compile_fail,E0138
|
|
||||||
#![feature(start)]
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn foo(argc: isize, argv: *const *const u8) -> isize {}
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn f(argc: isize, argv: *const *const u8) -> isize {}
|
|
||||||
// error: multiple 'start' functions
|
|
||||||
```
|
|
||||||
|
|
||||||
This error indicates that the compiler found multiple functions with the
|
|
||||||
`#[start]` attribute. This is an error because there must be a unique entry
|
|
||||||
point into a Rust program. Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
#![feature(start)]
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
|
|
||||||
```
|
|
||||||
|
@ -1,13 +1,3 @@
|
|||||||
|
#### Note: this error code is no longer emitted by the compiler.
|
||||||
|
|
||||||
The `start` function was defined with a where clause.
|
The `start` function was defined with a where clause.
|
||||||
|
|
||||||
Erroneous code example:
|
|
||||||
|
|
||||||
```compile_fail,E0647
|
|
||||||
#![feature(start)]
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn start(_: isize, _: *const *const u8) -> isize where (): Copy {
|
|
||||||
//^ error: `#[start]` function is not allowed to have a where clause
|
|
||||||
0
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
//
|
//
|
||||||
// Both columns are necessary because it's not possible in Rust to create a new identifier such as
|
// Both columns are necessary because it's not possible in Rust to create a new identifier such as
|
||||||
// `E0123` from an integer literal such as `0123`, unfortunately.
|
// `E0123` from an integer literal such as `0123`, unfortunately.
|
||||||
|
//
|
||||||
|
// Do *not* remove entries from this list. Instead, just add a note th the corresponding markdown
|
||||||
|
// file saying that this error is not emitted by the compiler any more (see E0001.md for an
|
||||||
|
// example), and remove all code examples that do not build any more.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! error_codes {
|
macro_rules! error_codes {
|
||||||
($macro:path) => (
|
($macro:path) => (
|
||||||
|
@ -448,7 +448,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
),
|
),
|
||||||
|
|
||||||
// Entry point:
|
// Entry point:
|
||||||
ungated!(start, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
|
|
||||||
ungated!(no_start, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
|
ungated!(no_start, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
|
||||||
ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
|
ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
|
||||||
|
|
||||||
|
@ -220,8 +220,9 @@ declare_features! (
|
|||||||
(removed, rustc_diagnostic_macros, "1.38.0", None, None),
|
(removed, rustc_diagnostic_macros, "1.38.0", None, None),
|
||||||
/// Allows identifying crates that contain sanitizer runtimes.
|
/// Allows identifying crates that contain sanitizer runtimes.
|
||||||
(removed, sanitizer_runtime, "1.17.0", None, None),
|
(removed, sanitizer_runtime, "1.17.0", None, None),
|
||||||
(removed, simd, "1.0.0", Some(27731),
|
(removed, simd, "1.0.0", Some(27731), Some("removed in favor of `#[repr(simd)]`")),
|
||||||
Some("removed in favor of `#[repr(simd)]`")),
|
/// Allows using `#[start]` on a function indicating that it is the program entrypoint.
|
||||||
|
(removed, start, "1.0.0", Some(29633), Some("not portable enough and never RFC'd")),
|
||||||
/// Allows `#[link(kind = "static-nobundle", ...)]`.
|
/// Allows `#[link(kind = "static-nobundle", ...)]`.
|
||||||
(removed, static_nobundle, "1.16.0", Some(37403),
|
(removed, static_nobundle, "1.16.0", Some(37403),
|
||||||
Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#)),
|
Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#)),
|
||||||
|
@ -300,8 +300,6 @@ declare_features! (
|
|||||||
(internal, rustdoc_internals, "1.58.0", Some(90418)),
|
(internal, rustdoc_internals, "1.58.0", Some(90418)),
|
||||||
/// Allows using the `rustdoc::missing_doc_code_examples` lint
|
/// Allows using the `rustdoc::missing_doc_code_examples` lint
|
||||||
(unstable, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730)),
|
(unstable, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730)),
|
||||||
/// Allows using `#[start]` on a function indicating that it is the program entrypoint.
|
|
||||||
(unstable, start, "1.0.0", Some(29633)),
|
|
||||||
/// Allows using `#[structural_match]` which indicates that a type is structurally matchable.
|
/// Allows using `#[structural_match]` which indicates that a type is structurally matchable.
|
||||||
/// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library
|
/// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library
|
||||||
/// feature with the same name exists.
|
/// feature with the same name exists.
|
||||||
|
@ -332,6 +332,10 @@ language_item_table! {
|
|||||||
FallbackSurfaceDrop, sym::fallback_surface_drop, fallback_surface_drop_fn, Target::Fn, GenericRequirement::None;
|
FallbackSurfaceDrop, sym::fallback_surface_drop, fallback_surface_drop_fn, Target::Fn, GenericRequirement::None;
|
||||||
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
|
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
|
||||||
|
|
||||||
|
/// For all binary crates without `#![no_main]`, Rust will generate a "main" function.
|
||||||
|
/// The exact name and signature are target-dependent. The "main" function will invoke
|
||||||
|
/// this lang item, passing it the `argc` and `argv` (or null, if those don't exist
|
||||||
|
/// on the current target) as well as the user-defined `fn main` from the binary crate.
|
||||||
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);
|
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);
|
||||||
|
|
||||||
EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
|
EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
|
||||||
|
@ -489,21 +489,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
|
hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable
|
||||||
.help = add `#![feature(min_specialization)]` to the crate attributes to enable
|
.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_static_specialize = cannot specialize on `'static` lifetime
|
||||||
|
|
||||||
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
|
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
|
||||||
|
@ -5,7 +5,7 @@ use rustc_hir as hir;
|
|||||||
use rustc_hir::Node;
|
use rustc_hir::Node;
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_middle::span_bug;
|
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_session::config::EntryFnType;
|
||||||
use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
|
use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
@ -18,7 +18,6 @@ use crate::errors;
|
|||||||
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
|
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
|
||||||
match tcx.entry_fn(()) {
|
match tcx.entry_fn(()) {
|
||||||
Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
|
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,
|
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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_main_function_return_type_generic, code = E0131)]
|
#[diag(hir_analysis_main_function_return_type_generic, code = E0131)]
|
||||||
pub(crate) struct MainFunctionReturnTypeGeneric {
|
pub(crate) struct MainFunctionReturnTypeGeneric {
|
||||||
|
@ -345,9 +345,6 @@ pub enum ObligationCauseCode<'tcx> {
|
|||||||
/// `main` has wrong type
|
/// `main` has wrong type
|
||||||
MainFunctionType,
|
MainFunctionType,
|
||||||
|
|
||||||
/// `start` has wrong type
|
|
||||||
StartFunctionType,
|
|
||||||
|
|
||||||
/// language function has wrong type
|
/// language function has wrong type
|
||||||
LangFunctionType(Symbol),
|
LangFunctionType(Symbol),
|
||||||
|
|
||||||
|
@ -502,11 +502,6 @@ passes_multiple_rustc_main =
|
|||||||
.first = first `#[rustc_main]` function
|
.first = first `#[rustc_main]` function
|
||||||
.additional = additional `#[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 =
|
passes_must_not_suspend =
|
||||||
`must_not_suspend` attribute should be applied to a struct, enum, union, or trait
|
`must_not_suspend` attribute should be applied to a struct, enum, union, or trait
|
||||||
.label = is not a struct, enum, union, or trait
|
.label = is not a struct, enum, union, or trait
|
||||||
|
@ -275,7 +275,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||||||
| sym::lang
|
| sym::lang
|
||||||
| sym::needs_allocator
|
| sym::needs_allocator
|
||||||
| sym::default_lib_allocator
|
| sym::default_lib_allocator
|
||||||
| sym::start
|
|
||||||
| sym::custom_mir,
|
| sym::custom_mir,
|
||||||
..
|
..
|
||||||
] => {}
|
] => {}
|
||||||
@ -2655,7 +2654,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
|||||||
sym::repr,
|
sym::repr,
|
||||||
sym::path,
|
sym::path,
|
||||||
sym::automatically_derived,
|
sym::automatically_derived,
|
||||||
sym::start,
|
|
||||||
sym::rustc_main,
|
sym::rustc_main,
|
||||||
sym::derive,
|
sym::derive,
|
||||||
sym::test,
|
sym::test,
|
||||||
|
@ -10,9 +10,7 @@ use rustc_session::RemapFileNameExt;
|
|||||||
use rustc_session::config::{CrateType, EntryFnType, RemapPathScopeComponents, sigpipe};
|
use rustc_session::config::{CrateType, EntryFnType, RemapPathScopeComponents, sigpipe};
|
||||||
use rustc_span::{Span, Symbol, sym};
|
use rustc_span::{Span, Symbol, sym};
|
||||||
|
|
||||||
use crate::errors::{
|
use crate::errors::{AttrOnlyInFunctions, ExternMain, MultipleRustcMain, NoMainErr};
|
||||||
AttrOnlyInFunctions, ExternMain, MultipleRustcMain, MultipleStartFunctions, NoMainErr,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EntryContext<'tcx> {
|
struct EntryContext<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
@ -20,9 +18,6 @@ struct EntryContext<'tcx> {
|
|||||||
/// The function has the `#[rustc_main]` attribute.
|
/// The function has the `#[rustc_main]` attribute.
|
||||||
rustc_main_fn: Option<(LocalDefId, Span)>,
|
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.
|
/// The functions that one might think are `main` but aren't, e.g.
|
||||||
/// main functions not defined at the top level. For diagnostics.
|
/// main functions not defined at the top level. For diagnostics.
|
||||||
non_main_fns: Vec<Span>,
|
non_main_fns: Vec<Span>,
|
||||||
@ -40,8 +35,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ctxt =
|
let mut ctxt = EntryContext { tcx, rustc_main_fn: None, non_main_fns: Vec::new() };
|
||||||
EntryContext { tcx, rustc_main_fn: None, start_fn: None, non_main_fns: Vec::new() };
|
|
||||||
|
|
||||||
for id in tcx.hir().items() {
|
for id in tcx.hir().items() {
|
||||||
check_and_search_item(id, &mut ctxt);
|
check_and_search_item(id, &mut ctxt);
|
||||||
@ -57,7 +51,7 @@ fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Opti
|
|||||||
|
|
||||||
fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
|
fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
|
||||||
if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) {
|
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) {
|
if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
|
||||||
ctxt.tcx.dcx().emit_err(AttrOnlyInFunctions { span, attr });
|
ctxt.tcx.dcx().emit_err(AttrOnlyInFunctions { span, attr });
|
||||||
}
|
}
|
||||||
@ -91,24 +85,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)> {
|
fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
|
||||||
if let Some((def_id, _)) = visitor.start_fn {
|
if let Some((local_def_id, _)) = visitor.rustc_main_fn {
|
||||||
Some((def_id.to_def_id(), EntryFnType::Start))
|
|
||||||
} else if let Some((local_def_id, _)) = visitor.rustc_main_fn {
|
|
||||||
let def_id = local_def_id.to_def_id();
|
let def_id = local_def_id.to_def_id();
|
||||||
Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }))
|
Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1313,17 +1313,6 @@ pub(crate) struct MultipleRustcMain {
|
|||||||
pub additional: Span,
|
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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(passes_extern_main)]
|
#[diag(passes_extern_main)]
|
||||||
pub(crate) struct ExternMain {
|
pub(crate) struct ExternMain {
|
||||||
|
@ -1268,7 +1268,6 @@ pub enum EntryFnType {
|
|||||||
/// and an `include!()`.
|
/// and an `include!()`.
|
||||||
sigpipe: u8,
|
sigpipe: u8,
|
||||||
},
|
},
|
||||||
Start,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)]
|
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)]
|
||||||
|
@ -261,7 +261,6 @@ trait_selection_oc_fn_lang_correct_type = {$lang_item_name ->
|
|||||||
*[lang_item_name] lang item `{$lang_item_name}`
|
*[lang_item_name] lang item `{$lang_item_name}`
|
||||||
} function has wrong type
|
} function has wrong type
|
||||||
trait_selection_oc_fn_main_correct_type = `main` function has wrong type
|
trait_selection_oc_fn_main_correct_type = `main` function has wrong type
|
||||||
trait_selection_oc_fn_start_correct_type = `#[start]` function has wrong type
|
|
||||||
trait_selection_oc_generic = mismatched types
|
trait_selection_oc_generic = mismatched types
|
||||||
|
|
||||||
trait_selection_oc_if_else_different = `if` and `else` have incompatible types
|
trait_selection_oc_if_else_different = `if` and `else` have incompatible types
|
||||||
@ -396,7 +395,6 @@ trait_selection_subtype = ...so that the {$requirement ->
|
|||||||
[if_else_different] `if` and `else` have incompatible types
|
[if_else_different] `if` and `else` have incompatible types
|
||||||
[no_else] `if` missing an `else` returns `()`
|
[no_else] `if` missing an `else` returns `()`
|
||||||
[fn_main_correct_type] `main` function has the correct type
|
[fn_main_correct_type] `main` function has the correct type
|
||||||
[fn_start_correct_type] `#[start]` function has the correct type
|
|
||||||
[fn_lang_correct_type] lang item function has the correct type
|
[fn_lang_correct_type] lang item function has the correct type
|
||||||
[intrinsic_correct_type] intrinsic has the correct type
|
[intrinsic_correct_type] intrinsic has the correct type
|
||||||
[method_correct_type] method receiver has the correct type
|
[method_correct_type] method receiver has the correct type
|
||||||
@ -410,7 +408,6 @@ trait_selection_subtype_2 = ...so that {$requirement ->
|
|||||||
[if_else_different] `if` and `else` have incompatible types
|
[if_else_different] `if` and `else` have incompatible types
|
||||||
[no_else] `if` missing an `else` returns `()`
|
[no_else] `if` missing an `else` returns `()`
|
||||||
[fn_main_correct_type] `main` function has the correct type
|
[fn_main_correct_type] `main` function has the correct type
|
||||||
[fn_start_correct_type] `#[start]` function has the correct type
|
|
||||||
[fn_lang_correct_type] lang item function has the correct type
|
[fn_lang_correct_type] lang item function has the correct type
|
||||||
[intrinsic_correct_type] intrinsic has the correct type
|
[intrinsic_correct_type] intrinsic has the correct type
|
||||||
[method_correct_type] method receiver has the correct type
|
[method_correct_type] method receiver has the correct type
|
||||||
|
@ -2318,7 +2318,6 @@ impl<'tcx> ObligationCause<'tcx> {
|
|||||||
| ObligationCauseCode::MatchExpressionArm(_)
|
| ObligationCauseCode::MatchExpressionArm(_)
|
||||||
| ObligationCauseCode::IfExpression { .. }
|
| ObligationCauseCode::IfExpression { .. }
|
||||||
| ObligationCauseCode::LetElse
|
| ObligationCauseCode::LetElse
|
||||||
| ObligationCauseCode::StartFunctionType
|
|
||||||
| ObligationCauseCode::LangFunctionType(_)
|
| ObligationCauseCode::LangFunctionType(_)
|
||||||
| ObligationCauseCode::IntrinsicType
|
| ObligationCauseCode::IntrinsicType
|
||||||
| ObligationCauseCode::MethodReceiver => FailureCode::Error0308,
|
| ObligationCauseCode::MethodReceiver => FailureCode::Error0308,
|
||||||
@ -2376,9 +2375,6 @@ impl<'tcx> ObligationCause<'tcx> {
|
|||||||
ObligationCauseCode::MainFunctionType => {
|
ObligationCauseCode::MainFunctionType => {
|
||||||
ObligationCauseFailureCode::FnMainCorrectType { span }
|
ObligationCauseFailureCode::FnMainCorrectType { span }
|
||||||
}
|
}
|
||||||
ObligationCauseCode::StartFunctionType => {
|
|
||||||
ObligationCauseFailureCode::FnStartCorrectType { span, subdiags }
|
|
||||||
}
|
|
||||||
&ObligationCauseCode::LangFunctionType(lang_item_name) => {
|
&ObligationCauseCode::LangFunctionType(lang_item_name) => {
|
||||||
ObligationCauseFailureCode::FnLangCorrectType { span, subdiags, lang_item_name }
|
ObligationCauseFailureCode::FnLangCorrectType { span, subdiags, lang_item_name }
|
||||||
}
|
}
|
||||||
@ -2421,7 +2417,6 @@ impl<'tcx> ObligationCause<'tcx> {
|
|||||||
"const is compatible with trait"
|
"const is compatible with trait"
|
||||||
}
|
}
|
||||||
ObligationCauseCode::MainFunctionType => "`main` function has the correct type",
|
ObligationCauseCode::MainFunctionType => "`main` function has the correct type",
|
||||||
ObligationCauseCode::StartFunctionType => "`#[start]` function has the correct type",
|
|
||||||
ObligationCauseCode::LangFunctionType(_) => "lang item function has the correct type",
|
ObligationCauseCode::LangFunctionType(_) => "lang item function has the correct type",
|
||||||
ObligationCauseCode::IntrinsicType => "intrinsic has the correct type",
|
ObligationCauseCode::IntrinsicType => "intrinsic has the correct type",
|
||||||
ObligationCauseCode::MethodReceiver => "method receiver has the correct type",
|
ObligationCauseCode::MethodReceiver => "method receiver has the correct type",
|
||||||
@ -2442,7 +2437,6 @@ impl IntoDiagArg for ObligationCauseAsDiagArg<'_> {
|
|||||||
"const_compat"
|
"const_compat"
|
||||||
}
|
}
|
||||||
ObligationCauseCode::MainFunctionType => "fn_main_correct_type",
|
ObligationCauseCode::MainFunctionType => "fn_main_correct_type",
|
||||||
ObligationCauseCode::StartFunctionType => "fn_start_correct_type",
|
|
||||||
ObligationCauseCode::LangFunctionType(_) => "fn_lang_correct_type",
|
ObligationCauseCode::LangFunctionType(_) => "fn_lang_correct_type",
|
||||||
ObligationCauseCode::IntrinsicType => "intrinsic_correct_type",
|
ObligationCauseCode::IntrinsicType => "intrinsic_correct_type",
|
||||||
ObligationCauseCode::MethodReceiver => "method_correct_type",
|
ObligationCauseCode::MethodReceiver => "method_correct_type",
|
||||||
|
@ -2740,7 +2740,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
| ObligationCauseCode::IfExpression { .. }
|
| ObligationCauseCode::IfExpression { .. }
|
||||||
| ObligationCauseCode::IfExpressionWithNoElse
|
| ObligationCauseCode::IfExpressionWithNoElse
|
||||||
| ObligationCauseCode::MainFunctionType
|
| ObligationCauseCode::MainFunctionType
|
||||||
| ObligationCauseCode::StartFunctionType
|
|
||||||
| ObligationCauseCode::LangFunctionType(_)
|
| ObligationCauseCode::LangFunctionType(_)
|
||||||
| ObligationCauseCode::IntrinsicType
|
| ObligationCauseCode::IntrinsicType
|
||||||
| ObligationCauseCode::MethodReceiver
|
| ObligationCauseCode::MethodReceiver
|
||||||
|
@ -1695,13 +1695,6 @@ pub enum ObligationCauseFailureCode {
|
|||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
#[diag(trait_selection_oc_fn_start_correct_type, code = E0308)]
|
|
||||||
FnStartCorrectType {
|
|
||||||
#[primary_span]
|
|
||||||
span: Span,
|
|
||||||
#[subdiagnostic]
|
|
||||||
subdiags: Vec<TypeErrorAdditionalDiags>,
|
|
||||||
},
|
|
||||||
#[diag(trait_selection_oc_fn_lang_correct_type, code = E0308)]
|
#[diag(trait_selection_oc_fn_lang_correct_type, code = E0308)]
|
||||||
FnLangCorrectType {
|
FnLangCorrectType {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
@ -78,7 +78,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
pub extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
|
||||||
const HELLO: &'static str = "Hello World, the answer is %d\n\0";
|
const HELLO: &'static str = "Hello World, the answer is %d\n\0";
|
||||||
unsafe {
|
unsafe {
|
||||||
printf(HELLO.as_ptr() as *const _, 42);
|
printf(HELLO.as_ptr() as *const _, 42);
|
||||||
|
@ -46,14 +46,15 @@ allocation. A freestanding program that uses the `Box` sugar for dynamic
|
|||||||
allocations via `malloc` and `free`:
|
allocations via `malloc` and `free`:
|
||||||
|
|
||||||
```rust,ignore (libc-is-finicky)
|
```rust,ignore (libc-is-finicky)
|
||||||
#![feature(lang_items, start, core_intrinsics, rustc_private, panic_unwind, rustc_attrs)]
|
#![feature(lang_items, core_intrinsics, rustc_private, panic_unwind, rustc_attrs)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate unwind;
|
extern crate unwind;
|
||||||
|
|
||||||
use core::ffi::c_void;
|
use core::ffi::{c_int, c_void};
|
||||||
use core::intrinsics;
|
use core::intrinsics;
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
@ -91,8 +92,8 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
|||||||
p
|
p
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
extern "C" fn main(_argc: c_int, _argv: *const *const u8) -> c_int {
|
||||||
let _x = Box::new(1);
|
let _x = Box::new(1);
|
||||||
|
|
||||||
0
|
0
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
# `start`
|
|
||||||
|
|
||||||
The tracking issue for this feature is: [#29633]
|
|
||||||
|
|
||||||
[#29633]: https://github.com/rust-lang/rust/issues/29633
|
|
||||||
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
Allows you to mark a function as the entry point of the executable, which is
|
|
||||||
necessary in `#![no_std]` environments.
|
|
||||||
|
|
||||||
The function marked `#[start]` is passed the command line parameters in the same
|
|
||||||
format as the C main function (aside from the integer types being used).
|
|
||||||
It has to be non-generic and have the following signature:
|
|
||||||
|
|
||||||
```rust,ignore (only-for-syntax-highlight)
|
|
||||||
# let _:
|
|
||||||
fn(isize, *const *const u8) -> isize
|
|
||||||
# ;
|
|
||||||
```
|
|
||||||
|
|
||||||
This feature should not be confused with the `start` *lang item* which is
|
|
||||||
defined by the `std` crate and is written `#[lang = "start"]`.
|
|
||||||
|
|
||||||
## Usage together with the `std` crate
|
|
||||||
|
|
||||||
`#[start]` can be used in combination with the `std` crate, in which case the
|
|
||||||
normal `main` function (which would get called from the `std` crate) won't be
|
|
||||||
used as an entry point.
|
|
||||||
The initialization code in `std` will be skipped this way.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(start)]
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Unwinding the stack past the `#[start]` function is currently considered
|
|
||||||
Undefined Behavior (for any unwinding implementation):
|
|
||||||
|
|
||||||
```rust,ignore (UB)
|
|
||||||
#![feature(start)]
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
|
||||||
std::panic::catch_unwind(|| {
|
|
||||||
panic!(); // panic safely gets caught or safely aborts execution
|
|
||||||
});
|
|
||||||
|
|
||||||
panic!(); // UB!
|
|
||||||
|
|
||||||
0
|
|
||||||
}
|
|
||||||
```
|
|
@ -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() {}
|
|
||||||
|
@ -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() {}
|
|
||||||
|
@ -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)`
|
||||||
|
@ -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() {}
|
|
||||||
|
@ -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() {}
|
|
||||||
|
@ -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() {}
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
... |
|
... |
|
||||||
|
@ -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)]
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
@ -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() {}
|
|
||||||
|
@ -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)
|
||||||
|
@ -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() {}
|
|
||||||
|
@ -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() {}
|
|
||||||
|
@ -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() }`
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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, ()> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -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() {}
|
|
||||||
|
@ -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() {}
|
|
||||||
|
@ -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()`
|
||||||
|
@ -33,7 +33,7 @@ use std::sync::atomic::{AtomicI32, Ordering};
|
|||||||
use std::sync::{Arc, Once};
|
use std::sync::{Arc, Once};
|
||||||
|
|
||||||
use miri::{
|
use miri::{
|
||||||
BacktraceStyle, BorrowTrackerMethod, MiriConfig, ProvenanceMode, RetagFields, ValidationMode,
|
BacktraceStyle, BorrowTrackerMethod, MiriConfig, MiriEntryFnType,ProvenanceMode, RetagFields, ValidationMode,
|
||||||
};
|
};
|
||||||
use rustc_abi::ExternAbi;
|
use rustc_abi::ExternAbi;
|
||||||
use rustc_data_structures::sync;
|
use rustc_data_structures::sync;
|
||||||
@ -51,7 +51,7 @@ use rustc_middle::query::LocalCrate;
|
|||||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_middle::util::Providers;
|
use rustc_middle::util::Providers;
|
||||||
use rustc_session::config::{CrateType, EntryFnType, ErrorOutputType, OptLevel};
|
use rustc_session::config::{CrateType, ErrorOutputType, OptLevel};
|
||||||
use rustc_session::search_paths::PathKind;
|
use rustc_session::search_paths::PathKind;
|
||||||
use rustc_session::{CtfeBacktrace, EarlyDiagCtxt};
|
use rustc_session::{CtfeBacktrace, EarlyDiagCtxt};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
@ -73,9 +73,9 @@ impl MiriCompilerCalls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, EntryFnType) {
|
fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) {
|
||||||
if let Some(entry_def) = tcx.entry_fn(()) {
|
if let Some((def_id, entry_type)) = tcx.entry_fn(()) {
|
||||||
return entry_def;
|
return (def_id, MiriEntryFnType::Rustc(entry_type));
|
||||||
}
|
}
|
||||||
// Look for a symbol in the local crate named `miri_start`, and treat that as the entry point.
|
// Look for a symbol in the local crate named `miri_start`, and treat that as the entry point.
|
||||||
let sym = tcx.exported_symbols(LOCAL_CRATE).iter().find_map(|(sym, _)| {
|
let sym = tcx.exported_symbols(LOCAL_CRATE).iter().find_map(|(sym, _)| {
|
||||||
@ -102,7 +102,7 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, EntryFnType) {
|
|||||||
.is_ok();
|
.is_ok();
|
||||||
|
|
||||||
if correct_func_sig {
|
if correct_func_sig {
|
||||||
(*id, EntryFnType::Start)
|
(*id, MiriEntryFnType::MiriStart)
|
||||||
} else {
|
} else {
|
||||||
tcx.dcx().fatal(
|
tcx.dcx().fatal(
|
||||||
"`miri_start` must have the following signature:\n\
|
"`miri_start` must have the following signature:\n\
|
||||||
|
@ -19,6 +19,12 @@ use crate::diagnostics::report_leaks;
|
|||||||
use crate::shims::tls;
|
use crate::shims::tls;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum MiriEntryFnType {
|
||||||
|
MiriStart,
|
||||||
|
Rustc(EntryFnType),
|
||||||
|
}
|
||||||
|
|
||||||
/// When the main thread would exit, we will yield to any other thread that is ready to execute.
|
/// When the main thread would exit, we will yield to any other thread that is ready to execute.
|
||||||
/// But we must only do that a finite number of times, or a background thread running `loop {}`
|
/// But we must only do that a finite number of times, or a background thread running `loop {}`
|
||||||
/// will hang the program.
|
/// will hang the program.
|
||||||
@ -272,7 +278,7 @@ impl<'tcx> MainThreadState<'tcx> {
|
|||||||
pub fn create_ecx<'tcx>(
|
pub fn create_ecx<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
entry_id: DefId,
|
entry_id: DefId,
|
||||||
entry_type: EntryFnType,
|
entry_type: MiriEntryFnType,
|
||||||
config: &MiriConfig,
|
config: &MiriConfig,
|
||||||
) -> InterpResult<'tcx, InterpCx<'tcx, MiriMachine<'tcx>>> {
|
) -> InterpResult<'tcx, InterpCx<'tcx, MiriMachine<'tcx>>> {
|
||||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||||
@ -300,7 +306,7 @@ pub fn create_ecx<'tcx>(
|
|||||||
// Setup first stack frame.
|
// Setup first stack frame.
|
||||||
let entry_instance = ty::Instance::mono(tcx, entry_id);
|
let entry_instance = ty::Instance::mono(tcx, entry_id);
|
||||||
|
|
||||||
// First argument is constructed later, because it's skipped if the entry function uses #[start].
|
// First argument is constructed later, because it's skipped for `miri_start.`
|
||||||
|
|
||||||
// Second argument (argc): length of `config.args`.
|
// Second argument (argc): length of `config.args`.
|
||||||
let argc =
|
let argc =
|
||||||
@ -373,11 +379,9 @@ pub fn create_ecx<'tcx>(
|
|||||||
// Call start function.
|
// Call start function.
|
||||||
|
|
||||||
match entry_type {
|
match entry_type {
|
||||||
EntryFnType::Main { .. } => {
|
MiriEntryFnType::Rustc(EntryFnType::Main { .. }) => {
|
||||||
let start_id = tcx.lang_items().start_fn().unwrap_or_else(|| {
|
let start_id = tcx.lang_items().start_fn().unwrap_or_else(|| {
|
||||||
tcx.dcx().fatal(
|
tcx.dcx().fatal("could not find start lang item");
|
||||||
"could not find start function. Make sure the entry point is marked with `#[start]`."
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
let main_ret_ty = tcx.fn_sig(entry_id).no_bound_vars().unwrap().output();
|
let main_ret_ty = tcx.fn_sig(entry_id).no_bound_vars().unwrap().output();
|
||||||
let main_ret_ty = main_ret_ty.no_bound_vars().unwrap();
|
let main_ret_ty = main_ret_ty.no_bound_vars().unwrap();
|
||||||
@ -413,7 +417,7 @@ pub fn create_ecx<'tcx>(
|
|||||||
StackPopCleanup::Root { cleanup: true },
|
StackPopCleanup::Root { cleanup: true },
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
EntryFnType::Start => {
|
MiriEntryFnType::MiriStart => {
|
||||||
ecx.call_function(
|
ecx.call_function(
|
||||||
entry_instance,
|
entry_instance,
|
||||||
ExternAbi::Rust,
|
ExternAbi::Rust,
|
||||||
@ -434,7 +438,7 @@ pub fn create_ecx<'tcx>(
|
|||||||
pub fn eval_entry<'tcx>(
|
pub fn eval_entry<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
entry_id: DefId,
|
entry_id: DefId,
|
||||||
entry_type: EntryFnType,
|
entry_type: MiriEntryFnType,
|
||||||
config: MiriConfig,
|
config: MiriConfig,
|
||||||
) -> Option<i32> {
|
) -> Option<i32> {
|
||||||
// Copy setting before we move `config`.
|
// Copy setting before we move `config`.
|
||||||
|
@ -135,8 +135,8 @@ pub use crate::diagnostics::{
|
|||||||
EvalContextExt as _, NonHaltingDiagnostic, TerminationInfo, report_error,
|
EvalContextExt as _, NonHaltingDiagnostic, TerminationInfo, report_error,
|
||||||
};
|
};
|
||||||
pub use crate::eval::{
|
pub use crate::eval::{
|
||||||
AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith, ValidationMode,
|
AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, MiriEntryFnType, RejectOpWith,
|
||||||
create_ecx, eval_entry,
|
ValidationMode, create_ecx, eval_entry,
|
||||||
};
|
};
|
||||||
pub use crate::helpers::{AccessKind, EvalContextExt as _};
|
pub use crate::helpers::{AccessKind, EvalContextExt as _};
|
||||||
pub use crate::intrinsics::EvalContextExt as _;
|
pub use crate::intrinsics::EvalContextExt as _;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
// Copied from tests/pass/no-std.rs
|
// Copied from tests/pass/no-std.rs
|
||||||
|
|
||||||
#![feature(start)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
// Plumbing to let us use `writeln!` to host stdout:
|
// Plumbing to let us use `writeln!` to host stdout:
|
||||||
@ -22,8 +21,8 @@ impl Write for Host {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
fn miri_start(_: isize, _: *const *const u8) -> isize {
|
||||||
writeln!(Host, "hello, world!").unwrap();
|
writeln!(Host, "hello, world!").unwrap();
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
//@compile-flags: -Cpanic=abort
|
//@compile-flags: -Cpanic=abort
|
||||||
#![feature(start, core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
#![feature(allocator_api)]
|
#![feature(allocator_api)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ mod plumbing {
|
|||||||
static GLOBAL: NoAlloc = NoAlloc;
|
static GLOBAL: NoAlloc = NoAlloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
fn miri_start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
handle_alloc_error(Layout::for_value(&0));
|
handle_alloc_error(Layout::for_value(&0));
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ LL | fn alloc_error_handler(layout: Layout) -> ! {
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
= note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||||
= note: inside `alloc::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
= note: inside `alloc::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||||
note: inside `start`
|
note: inside `miri_start`
|
||||||
--> tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC
|
--> tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | handle_alloc_error(Layout::for_value(&0));
|
LL | handle_alloc_error(Layout::for_value(&0));
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
//@compile-flags: -Cpanic=abort
|
//@compile-flags: -Cpanic=abort
|
||||||
#![feature(start, core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
#![feature(allocator_api)]
|
#![feature(allocator_api)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ mod plumbing {
|
|||||||
static GLOBAL: NoAlloc = NoAlloc;
|
static GLOBAL: NoAlloc = NoAlloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
fn miri_start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
handle_alloc_error(Layout::for_value(&0));
|
handle_alloc_error(Layout::for_value(&0));
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ LL | core::intrinsics::abort();
|
|||||||
= note: inside `alloc::alloc::__alloc_error_handler::__rdl_oom` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
= note: inside `alloc::alloc::__alloc_error_handler::__rdl_oom` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||||
= note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
= note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||||
= note: inside `alloc::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
= note: inside `alloc::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||||
note: inside `start`
|
note: inside `miri_start`
|
||||||
--> tests/fail/alloc/alloc_error_handler_no_std.rs:LL:CC
|
--> tests/fail/alloc/alloc_error_handler_no_std.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | handle_alloc_error(Layout::for_value(&0));
|
LL | handle_alloc_error(Layout::for_value(&0));
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
//@normalize-stderr-test: "OS `.*`" -> "$$OS"
|
//@normalize-stderr-test: "OS `.*`" -> "$$OS"
|
||||||
// Make sure we pretend the allocation symbols don't exist when there is no allocator
|
// Make sure we pretend the allocation symbols don't exist when there is no allocator
|
||||||
|
|
||||||
#![feature(start)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
|
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
fn miri_start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
unsafe {
|
unsafe {
|
||||||
__rust_alloc(1, 1); //~ERROR: unsupported operation: can't call foreign function `__rust_alloc`
|
__rust_alloc(1, 1); //~ERROR: unsupported operation: can't call foreign function `__rust_alloc`
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ LL | __rust_alloc(1, 1);
|
|||||||
= help: if this is a basic API commonly used on this target, please report an issue with Miri
|
= help: if this is a basic API commonly used on this target, please report an issue with Miri
|
||||||
= help: however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases
|
= help: however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE:
|
||||||
= note: inside `start` at tests/fail/alloc/no_global_allocator.rs:LL:CC
|
= note: inside `miri_start` at tests/fail/alloc/no_global_allocator.rs:LL:CC
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
//@compile-flags: -Cpanic=abort
|
//@compile-flags: -Cpanic=abort
|
||||||
#![feature(start, core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
|
||||||
#[path = "../../utils/mod.no_std.rs"]
|
#[path = "../../utils/mod.no_std.rs"]
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
fn miri_start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
panic!("blarg I am dead")
|
panic!("blarg I am dead")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ LL | core::intrinsics::abort();
|
|||||||
|
|
|
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE:
|
||||||
= note: inside `panic_handler` at tests/fail/panic/no_std.rs:LL:CC
|
= note: inside `panic_handler` at tests/fail/panic/no_std.rs:LL:CC
|
||||||
note: inside `start`
|
note: inside `miri_start`
|
||||||
--> tests/fail/panic/no_std.rs:LL:CC
|
--> tests/fail/panic/no_std.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | panic!("blarg I am dead")
|
LL | panic!("blarg I am dead")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![feature(start)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
//@compile-flags: -Zmiri-track-alloc-id=21 -Zmiri-track-alloc-accesses -Cpanic=abort
|
//@compile-flags: -Zmiri-track-alloc-id=21 -Zmiri-track-alloc-accesses -Cpanic=abort
|
||||||
//@normalize-stderr-test: "id 21" -> "id $$ALLOC"
|
//@normalize-stderr-test: "id 21" -> "id $$ALLOC"
|
||||||
//@only-target: linux # alloc IDs differ between OSes (due to extern static allocations)
|
//@only-target: linux # alloc IDs differ between OSes (due to extern static allocations)
|
||||||
@ -9,8 +9,8 @@ extern "Rust" {
|
|||||||
fn miri_dealloc(ptr: *mut u8, size: usize, align: usize);
|
fn miri_dealloc(ptr: *mut u8, size: usize, align: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
fn miri_start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = miri_alloc(123, 1);
|
let ptr = miri_alloc(123, 1);
|
||||||
*ptr = 42; // Crucially, only a write is printed here, no read!
|
*ptr = 42; // Crucially, only a write is printed here, no read!
|
||||||
|
@ -5,7 +5,7 @@ LL | let ptr = miri_alloc(123, 1);
|
|||||||
| ^^^^^^^^^^^^^^^^^^ created Miri bare-metal heap allocation of 123 bytes (alignment ALIGN bytes) with id $ALLOC
|
| ^^^^^^^^^^^^^^^^^^ created Miri bare-metal heap allocation of 123 bytes (alignment ALIGN bytes) with id $ALLOC
|
||||||
|
|
|
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE:
|
||||||
= note: inside `start` at tests/pass/alloc-access-tracking.rs:LL:CC
|
= note: inside `miri_start` at tests/pass/alloc-access-tracking.rs:LL:CC
|
||||||
|
|
||||||
note: tracking was triggered
|
note: tracking was triggered
|
||||||
--> tests/pass/alloc-access-tracking.rs:LL:CC
|
--> tests/pass/alloc-access-tracking.rs:LL:CC
|
||||||
@ -14,7 +14,7 @@ LL | *ptr = 42; // Crucially, only a write is printed here, no read!
|
|||||||
| ^^^^^^^^^ write access to allocation with id $ALLOC
|
| ^^^^^^^^^ write access to allocation with id $ALLOC
|
||||||
|
|
|
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE:
|
||||||
= note: inside `start` at tests/pass/alloc-access-tracking.rs:LL:CC
|
= note: inside `miri_start` at tests/pass/alloc-access-tracking.rs:LL:CC
|
||||||
|
|
||||||
note: tracking was triggered
|
note: tracking was triggered
|
||||||
--> tests/pass/alloc-access-tracking.rs:LL:CC
|
--> tests/pass/alloc-access-tracking.rs:LL:CC
|
||||||
@ -23,7 +23,7 @@ LL | assert_eq!(*ptr, 42);
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^ read access to allocation with id $ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^ read access to allocation with id $ALLOC
|
||||||
|
|
|
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE:
|
||||||
= note: inside `start` at RUSTLIB/core/src/macros/mod.rs:LL:CC
|
= note: inside `miri_start` at RUSTLIB/core/src/macros/mod.rs:LL:CC
|
||||||
= note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
note: tracking was triggered
|
note: tracking was triggered
|
||||||
@ -33,5 +33,5 @@ LL | miri_dealloc(ptr, 123, 1);
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ freed allocation with id $ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ freed allocation with id $ALLOC
|
||||||
|
|
|
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE:
|
||||||
= note: inside `start` at tests/pass/alloc-access-tracking.rs:LL:CC
|
= note: inside `miri_start` at tests/pass/alloc-access-tracking.rs:LL:CC
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![feature(start)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
//@compile-flags: -Cpanic=abort
|
//@compile-flags: -Cpanic=abort
|
||||||
// windows tls dtors go through libstd right now, thus this test
|
// windows tls dtors go through libstd right now, thus this test
|
||||||
// cannot pass. When windows tls dtors go through the special magic
|
// cannot pass. When windows tls dtors go through the special magic
|
||||||
@ -11,8 +11,8 @@ extern "Rust" {
|
|||||||
fn miri_dealloc(ptr: *mut u8, size: usize, align: usize);
|
fn miri_dealloc(ptr: *mut u8, size: usize, align: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
fn miri_start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = miri_alloc(123, 1);
|
let ptr = miri_alloc(123, 1);
|
||||||
core::ptr::write_bytes(ptr, 0u8, 123);
|
core::ptr::write_bytes(ptr, 0u8, 123);
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Hello from miri_start!
|
|
@ -1,19 +0,0 @@
|
|||||||
//@compile-flags: -Cpanic=abort
|
|
||||||
#![feature(start)]
|
|
||||||
#![no_std]
|
|
||||||
|
|
||||||
use core::fmt::Write;
|
|
||||||
|
|
||||||
#[path = "../utils/mod.no_std.rs"]
|
|
||||||
mod utils;
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
|
||||||
writeln!(utils::MiriStdout, "hello, world!").unwrap();
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[panic_handler]
|
|
||||||
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
|
|
||||||
loop {}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
//@compile-flags: -Cpanic=abort
|
//@compile-flags: -Cpanic=abort
|
||||||
#![no_main]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ mod utils;
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
fn miri_start(_argc: isize, _argv: *const *const u8) -> isize {
|
fn miri_start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
writeln!(utils::MiriStdout, "Hello from miri_start!").unwrap();
|
writeln!(utils::MiriStdout, "hello, world!").unwrap();
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
#![feature(start)]
|
|
||||||
|
|
||||||
#[start]
|
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
|
||||||
println!("Hello from start!");
|
|
||||||
|
|
||||||
0
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
Hello from start!
|
|
@ -183,7 +183,6 @@ ui/async-await/issue-67252-unnamed-future.rs
|
|||||||
ui/async-await/issue-67651.rs
|
ui/async-await/issue-67651.rs
|
||||||
ui/async-await/issue-67765-async-diagnostic.rs
|
ui/async-await/issue-67765-async-diagnostic.rs
|
||||||
ui/async-await/issue-68112.rs
|
ui/async-await/issue-68112.rs
|
||||||
ui/async-await/issue-68523-start.rs
|
|
||||||
ui/async-await/issue-68523.rs
|
ui/async-await/issue-68523.rs
|
||||||
ui/async-await/issue-69446-fnmut-capture.rs
|
ui/async-await/issue-69446-fnmut-capture.rs
|
||||||
ui/async-await/issue-70594.rs
|
ui/async-await/issue-70594.rs
|
||||||
@ -2395,7 +2394,6 @@ ui/issues/issue-50618.rs
|
|||||||
ui/issues/issue-5062.rs
|
ui/issues/issue-5062.rs
|
||||||
ui/issues/issue-5067.rs
|
ui/issues/issue-5067.rs
|
||||||
ui/issues/issue-50688.rs
|
ui/issues/issue-50688.rs
|
||||||
ui/issues/issue-50714-1.rs
|
|
||||||
ui/issues/issue-50714.rs
|
ui/issues/issue-50714.rs
|
||||||
ui/issues/issue-50761.rs
|
ui/issues/issue-50761.rs
|
||||||
ui/issues/issue-50781.rs
|
ui/issues/issue-50781.rs
|
||||||
@ -2630,7 +2628,6 @@ ui/issues/issue-9259.rs
|
|||||||
ui/issues/issue-92741.rs
|
ui/issues/issue-92741.rs
|
||||||
ui/issues/issue-9382.rs
|
ui/issues/issue-9382.rs
|
||||||
ui/issues/issue-9446.rs
|
ui/issues/issue-9446.rs
|
||||||
ui/issues/issue-9575.rs
|
|
||||||
ui/issues/issue-9719.rs
|
ui/issues/issue-9719.rs
|
||||||
ui/issues/issue-9725.rs
|
ui/issues/issue-9725.rs
|
||||||
ui/issues/issue-9737.rs
|
ui/issues/issue-9737.rs
|
||||||
@ -2645,7 +2642,6 @@ ui/issues/issue-9968.rs
|
|||||||
ui/issues/issue-99838.rs
|
ui/issues/issue-99838.rs
|
||||||
ui/iterators/issue-28098.rs
|
ui/iterators/issue-28098.rs
|
||||||
ui/iterators/issue-58952-filter-type-length.rs
|
ui/iterators/issue-58952-filter-type-length.rs
|
||||||
ui/lang-items/issue-19660.rs
|
|
||||||
ui/lang-items/issue-83471.rs
|
ui/lang-items/issue-83471.rs
|
||||||
ui/lang-items/issue-87573.rs
|
ui/lang-items/issue-87573.rs
|
||||||
ui/late-bound-lifetimes/issue-36381.rs
|
ui/late-bound-lifetimes/issue-36381.rs
|
||||||
@ -3702,7 +3698,6 @@ ui/rfcs/rfc-2005-default-binding-mode/issue-44912-or.rs
|
|||||||
ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
|
ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
|
||||||
ui/rfcs/rfc-2093-infer-outlives/issue-54467.rs
|
ui/rfcs/rfc-2093-infer-outlives/issue-54467.rs
|
||||||
ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-main.rs
|
ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-main.rs
|
||||||
ui/rfcs/rfc-2396-target_feature-11/issue-108645-target-feature-on-start.rs
|
|
||||||
ui/rfcs/rfc-2396-target_feature-11/issue-108655-inline-always-closure.rs
|
ui/rfcs/rfc-2396-target_feature-11/issue-108655-inline-always-closure.rs
|
||||||
ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs
|
ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs
|
||||||
ui/rfcs/rfc-2497-if-let-chains/issue-88498.rs
|
ui/rfcs/rfc-2497-if-let-chains/issue-88498.rs
|
||||||
|
@ -17,7 +17,7 @@ use ignore::Walk;
|
|||||||
const ENTRY_LIMIT: u32 = 901;
|
const ENTRY_LIMIT: u32 = 901;
|
||||||
// FIXME: The following limits should be reduced eventually.
|
// FIXME: The following limits should be reduced eventually.
|
||||||
|
|
||||||
const ISSUES_ENTRY_LIMIT: u32 = 1667;
|
const ISSUES_ENTRY_LIMIT: u32 = 1663;
|
||||||
|
|
||||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||||
"rs", // test source files
|
"rs", // test source files
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
//@ compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
|
//@ compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
|
||||||
|
|
||||||
#![deny(dead_code)]
|
#![deny(dead_code)]
|
||||||
#![feature(start)]
|
#![no_main]
|
||||||
|
|
||||||
//@ aux-build:cgu_extern_closures.rs
|
//@ aux-build:cgu_extern_closures.rs
|
||||||
extern crate cgu_extern_closures;
|
extern crate cgu_extern_closures;
|
||||||
|
|
||||||
//~ MONO_ITEM fn start @@ cross_crate_closures-cgu.0[Internal]
|
//~ MONO_ITEM fn main @@ cross_crate_closures-cgu.0[External]
|
||||||
#[start]
|
#[no_mangle]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
extern "C" fn main(_: core::ffi::c_int, _: *const *const u8) -> core::ffi::c_int {
|
||||||
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn @@ cross_crate_closures-cgu.0[Internal]
|
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn @@ cross_crate_closures-cgu.0[Internal]
|
||||||
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn::{closure#0} @@ cross_crate_closures-cgu.0[Internal]
|
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn::{closure#0} @@ cross_crate_closures-cgu.0[Internal]
|
||||||
let _ = cgu_extern_closures::inlined_fn(1, 2);
|
let _ = cgu_extern_closures::inlined_fn(1, 2);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user