Skip to content

Commit e7fe12c

Browse files
authored
Rollup merge of rust-lang#88782 - asquared31415:issue-79559, r=cjgillot
Fix ICE when `start` lang item has wrong generics In my previous pr rust-lang#87875 I missed the requirements on the `start` lang item due to its relative difficulty to test and opting for more conservative estimates. This fixes that by updating the requirement to be exactly one generic type. The `start` lang item should have exactly one generic type for the return type of the `main` fn ptr passed to it. I believe having zero would previously *sometimes* compile (often with the use of `fn() -> ()` as the fn ptr but it was likely UB to call if the return type of `main` was not `()` as far as I know) however it also sometimes would not for various errors including ICEs and LLVM errors depending on exact situations. Having more than 1 generic has always failed with an ICE because only the one generic type is expected and provided. Fixes rust-lang#79559, fixes rust-lang#73584, fixes rust-lang#83117 (all duplicates) Relevant to rust-lang#9307 r? ``@cjgillot``
2 parents 6dc08b9 + 05460d0 commit e7fe12c

File tree

6 files changed

+35
-15
lines changed

6 files changed

+35
-15
lines changed

compiler/rustc_hir/src/lang_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ language_item_table! {
300300
Oom, sym::oom, oom, Target::Fn, GenericRequirement::None;
301301
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
302302

303-
Start, sym::start, start_fn, Target::Fn, GenericRequirement::None;
303+
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);
304304

305305
EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
306306
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None;

src/test/run-make-fulldeps/target-specs/foo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ trait Sized {}
1111
auto trait Freeze {}
1212

1313
#[lang = "start"]
14-
fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize {
14+
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
1515
0
1616
}
1717

src/test/ui/lang-items/lang-item-generic-requirements.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
// Checks whether declaring a lang item with the wrong number
2-
// of generic arguments crashes the compiler (issue #83893, #87573, and part of #9307).
1+
// Checks that declaring a lang item with the wrong number
2+
// of generic arguments errors rather than crashing (issue #83893, #87573, part of #9307, #79559).
33

44
#![feature(lang_items, no_core)]
55
#![no_core]
6-
#![crate_type = "lib"]
76

87
#[lang = "sized"]
98
trait MySized {}
@@ -26,6 +25,14 @@ struct MyPhantomData<T, U>;
2625
//~^ ERROR parameter `T` is never used
2726
//~| ERROR parameter `U` is never used
2827

28+
// When the `start` lang item is missing generics very odd things can happen, especially when
29+
// it comes to cross-crate monomorphization
30+
#[lang = "start"]
31+
//~^ ERROR `start` language item must be applied to a function with 1 generic argument [E0718]
32+
fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
33+
0
34+
}
35+
2936
fn ice() {
3037
// Use add
3138
let r = 5;
@@ -42,3 +49,6 @@ fn ice() {
4249
// Use phantomdata
4350
let _ = MyPhantomData::<(), i32>;
4451
}
52+
53+
// use `start`
54+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0718]: `add` language item must be applied to a trait with 1 generic argument
2-
--> $DIR/lang-item-generic-requirements.rs:11:1
2+
--> $DIR/lang-item-generic-requirements.rs:10:1
33
|
44
LL | #[lang = "add"]
55
| ^^^^^^^^^^^^^^^
66
LL | trait MyAdd<'a, T> {}
77
| ------- this trait has 2 generic arguments
88

99
error[E0718]: `drop_in_place` language item must be applied to a function with at least 1 generic argument
10-
--> $DIR/lang-item-generic-requirements.rs:15:1
10+
--> $DIR/lang-item-generic-requirements.rs:14:1
1111
|
1212
LL | #[lang = "drop_in_place"]
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,24 +16,33 @@ LL | fn my_ptr_drop() {}
1616
| - this function has 0 generic arguments
1717

1818
error[E0718]: `index` language item must be applied to a trait with 1 generic argument
19-
--> $DIR/lang-item-generic-requirements.rs:19:1
19+
--> $DIR/lang-item-generic-requirements.rs:18:1
2020
|
2121
LL | #[lang = "index"]
2222
| ^^^^^^^^^^^^^^^^^
2323
LL | trait MyIndex<'a, T> {}
2424
| ------- this trait has 2 generic arguments
2525

2626
error[E0718]: `phantom_data` language item must be applied to a struct with 1 generic argument
27-
--> $DIR/lang-item-generic-requirements.rs:23:1
27+
--> $DIR/lang-item-generic-requirements.rs:22:1
2828
|
2929
LL | #[lang = "phantom_data"]
3030
| ^^^^^^^^^^^^^^^^^^^^^^^^
3131
LL |
3232
LL | struct MyPhantomData<T, U>;
3333
| ------ this struct has 2 generic arguments
3434

35+
error[E0718]: `start` language item must be applied to a function with 1 generic argument
36+
--> $DIR/lang-item-generic-requirements.rs:30:1
37+
|
38+
LL | #[lang = "start"]
39+
| ^^^^^^^^^^^^^^^^^
40+
LL |
41+
LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
42+
| - this function has 0 generic arguments
43+
3544
error[E0392]: parameter `T` is never used
36-
--> $DIR/lang-item-generic-requirements.rs:25:22
45+
--> $DIR/lang-item-generic-requirements.rs:24:22
3746
|
3847
LL | struct MyPhantomData<T, U>;
3948
| ^ unused parameter
@@ -42,15 +51,15 @@ LL | struct MyPhantomData<T, U>;
4251
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
4352

4453
error[E0392]: parameter `U` is never used
45-
--> $DIR/lang-item-generic-requirements.rs:25:25
54+
--> $DIR/lang-item-generic-requirements.rs:24:25
4655
|
4756
LL | struct MyPhantomData<T, U>;
4857
| ^ unused parameter
4958
|
5059
= help: consider removing `U` or referring to it in a field
5160
= help: if you intended `U` to be a const parameter, use `const U: usize` instead
5261

53-
error: aborting due to 6 previous errors
62+
error: aborting due to 7 previous errors
5463

5564
Some errors have detailed explanations: E0392, E0718.
5665
For more information about an error, try `rustc --explain E0392`.

src/tools/clippy/tests/ui/def_id_nocore.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ pub trait Copy {}
1515
pub unsafe trait Freeze {}
1616

1717
#[lang = "start"]
18-
#[start]
19-
fn start(_argc: isize, _argv: *const *const u8) -> isize {
18+
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
2019
0
2120
}
2221

22+
fn main() {}
23+
2324
struct A;
2425

2526
impl A {

src/tools/clippy/tests/ui/def_id_nocore.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
2-
--> $DIR/def_id_nocore.rs:26:19
2+
--> $DIR/def_id_nocore.rs:27:19
33
|
44
LL | pub fn as_ref(self) -> &'static str {
55
| ^^^^

0 commit comments

Comments
 (0)