Skip to content

Commit db930c6

Browse files
committed
Stop mentioning internal lang items in no_std binary errors
When writing a no_std binary, you'll be greeted with nonsensical errors mentioning lang items like eh_personality and start. That's pretty bad because it makes you think that you need to define them somewhere! But oh no, now you're getting the `internal_features` lint telling you that you shouldn't use them! But you need a no_std binary! What now? No problem! Writing a no_std binary is super easy. Just use panic=abort and supply your own platform specific entrypoint symbol (like `main`) and you're good to go. Would be nice if the compiler told you that, right? This makes it so that it does do that.
1 parent 5cb2e7d commit db930c6

16 files changed

+85
-16
lines changed

compiler/rustc_monomorphize/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ monomorphize_recursion_limit =
2020
reached the recursion limit while instantiating `{$shrunk}`
2121
.note = `{$def_path_str}` defined here
2222
23+
monomorphize_start_not_found = using `fn main` requires the standard library
24+
.help = use `#![no_main]` to bypass the Rust generated entrypoint and declare a platform specific entrypoint yourself, usually with `#[no_mangle]`
25+
2326
monomorphize_symbol_already_defined = symbol `{$symbol}` is already defined
2427
2528
monomorphize_type_length_limit = reached the type-length limit while instantiating `{$shrunk}`

compiler/rustc_monomorphize/src/collector.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ use rustc_target::abi::Size;
194194
use std::path::PathBuf;
195195

196196
use crate::errors::{
197-
EncounteredErrorWhileInstantiating, LargeAssignmentsLint, NoOptimizedMir, RecursionLimit,
197+
self, EncounteredErrorWhileInstantiating, LargeAssignmentsLint, NoOptimizedMir, RecursionLimit,
198198
TypeLengthLimit,
199199
};
200200

@@ -1272,7 +1272,9 @@ impl<'v> RootCollector<'_, 'v> {
12721272
return;
12731273
};
12741274

1275-
let start_def_id = self.tcx.require_lang_item(LangItem::Start, None);
1275+
let Some(start_def_id) = self.tcx.lang_items().start_fn() else {
1276+
self.tcx.dcx().emit_fatal(errors::StartNotFound);
1277+
};
12761278
let main_ret_ty = self.tcx.fn_sig(main_def_id).no_bound_vars().unwrap().output();
12771279

12781280
// Given that `main()` has no arguments,

compiler/rustc_monomorphize/src/errors.rs

+5
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ pub struct EncounteredErrorWhileInstantiating {
9494
pub formatted_item: String,
9595
}
9696

97+
#[derive(Diagnostic)]
98+
#[diag(monomorphize_start_not_found)]
99+
#[help]
100+
pub struct StartNotFound;
101+
97102
#[derive(Diagnostic)]
98103
#[diag(monomorphize_unknown_cgu_collection_mode)]
99104
pub struct UnknownCguCollectionMode<'a> {

compiler/rustc_passes/messages.ftl

+5
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,11 @@ passes_outside_loop =
575575
576576
passes_outside_loop_suggestion = consider labeling this block to be able to break within it
577577
578+
passes_panic_unwind_without_std =
579+
unwinding panics are not supported without std
580+
.note = since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
581+
.help = using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
582+
578583
passes_params_not_allowed =
579584
referencing function parameters is not allowed in naked functions
580585
.help = follow the calling convention in asm block to use parameters

compiler/rustc_passes/src/errors.rs

+6
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,12 @@ pub struct UnknownExternLangItem {
812812
#[diag(passes_missing_panic_handler)]
813813
pub struct MissingPanicHandler;
814814

815+
#[derive(Diagnostic)]
816+
#[diag(passes_panic_unwind_without_std)]
817+
#[help]
818+
#[note]
819+
pub struct PanicUnwindWithoutStd;
820+
815821
#[derive(Diagnostic)]
816822
#[diag(passes_missing_lang_item)]
817823
#[note]

compiler/rustc_passes/src/weak_lang_items.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ use rustc_middle::middle::lang_items::required;
99
use rustc_middle::ty::TyCtxt;
1010
use rustc_session::config::CrateType;
1111

12-
use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem};
12+
use crate::errors::{
13+
MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd, UnknownExternLangItem,
14+
};
1315

1416
/// Checks the crate for usage of weak lang items, returning a vector of all the
1517
/// language items required by this crate, but not defined yet.
@@ -76,6 +78,8 @@ fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {
7678
if missing.contains(&item) && required(tcx, item) && items.get(item).is_none() {
7779
if item == LangItem::PanicImpl {
7880
tcx.dcx().emit_err(MissingPanicHandler);
81+
} else if item == LangItem::EhPersonality {
82+
tcx.dcx().emit_err(PanicUnwindWithoutStd);
7983
} else {
8084
tcx.dcx().emit_err(MissingLangItem { name: item.name() });
8185
}

src/tools/tidy/src/ui_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
1111
const ENTRY_LIMIT: usize = 900;
1212
// FIXME: The following limits should be reduced eventually.
1313
const ISSUES_ENTRY_LIMIT: usize = 1849;
14-
const ROOT_ENTRY_LIMIT: usize = 867;
14+
const ROOT_ENTRY_LIMIT: usize = 868;
1515

1616
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
1717
"rs", // test source files

tests/ui/extern-flag/empty-extern-arg.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ error: extern location for std does not exist:
22

33
error: `#[panic_handler]` function required, but not found
44

5-
error: language item required, but not found: `eh_personality`
5+
error: unwinding panics are not supported without std
66
|
7-
= note: this can occur when a binary crate with `#![no_std]` is compiled for a target where `eh_personality` is defined in the standard library
8-
= help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`
7+
= help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
8+
= note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
99

1010
error: aborting due to 3 previous errors
1111

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
// build-fail
1+
// edition: 2018
22

33
#![feature(lang_items, no_core)]
44
#![no_core]
5+
#![no_main]
56

67
#[lang="copy"] pub trait Copy { }
78
#[lang="sized"] pub trait Sized { }
89

9-
// error-pattern:requires `start` lang_item
10-
11-
fn main() {}
10+
async fn x() {} //~ ERROR requires `ResumeTy` lang_item
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
error: requires `start` lang_item
1+
error: requires `ResumeTy` lang_item
2+
--> $DIR/required-lang-item.rs:10:14
3+
|
4+
LL | async fn x() {}
5+
| ^^
26

37
error: aborting due to 1 previous error
48

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// compile-flags: -Cpanic=abort --emit link
2+
// error-pattern:using `fn main` requires the standard library
3+
4+
// Make sure that we don't emit an error message mentioning internal lang items.
5+
6+
#![no_std]
7+
8+
#[panic_handler]
9+
fn handler(_info: &core::panic::PanicInfo<'_>) -> ! {
10+
loop {}
11+
}
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
error: using `fn main` requires the standard library
2+
|
3+
= help: use `#![no_main]` to bypass the Rust generated entrypoint and declare a platform specific entrypoint yourself, usually with `#[no_mangle]`
4+
5+
error: aborting due to 1 previous error
6+
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// error-pattern:unwinding panics are not supported without std
2+
// needs-unwind
3+
// compile-flags: -Cpanic=unwind
4+
5+
// Make sure that we don't emit an error message mentioning internal lang items.
6+
7+
#![no_std]
8+
#![no_main]
9+
10+
#[panic_handler]
11+
fn handler(_info: &core::panic::PanicInfo<'_>) -> ! {
12+
loop {}
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
error: unwinding panics are not supported without std
2+
|
3+
= help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
4+
= note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
5+
6+
error: aborting due to 1 previous error
7+

tests/ui/panic-handler/weak-lang-item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// aux-build:weak-lang-items.rs
22
// error-pattern: `#[panic_handler]` function required, but not found
3-
// error-pattern: language item required, but not found: `eh_personality`
3+
// error-pattern: unwinding panics are not supported without std
44
// needs-unwind since it affects the error output
55
// ignore-emscripten missing eh_catch_typeinfo lang item
66

tests/ui/panic-handler/weak-lang-item.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ LL | extern crate core as other_core;
1212

1313
error: `#[panic_handler]` function required, but not found
1414

15-
error: language item required, but not found: `eh_personality`
15+
error: unwinding panics are not supported without std
1616
|
17-
= note: this can occur when a binary crate with `#![no_std]` is compiled for a target where `eh_personality` is defined in the standard library
18-
= help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`
17+
= help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
18+
= note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
1919

2020
error: aborting due to 3 previous errors
2121

0 commit comments

Comments
 (0)