Skip to content

Commit

Permalink
Rollup merge of #88782 - asquared31415:issue-79559, r=cjgillot
Browse files Browse the repository at this point in the history
Fix ICE when `start` lang item has wrong generics

In my previous pr #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 #79559, fixes #73584, fixes #83117 (all duplicates)
Relevant to #9307

r? ````@cjgillot````
  • Loading branch information
Manishearth committed Oct 1, 2021
2 parents aa7aca3 + 05460d0 commit 3d86aac
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 15 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ language_item_table! {
Oom, sym::oom, oom, Target::Fn, GenericRequirement::None;
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;

Start, sym::start, start_fn, Target::Fn, GenericRequirement::None;
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);

EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None;
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-make-fulldeps/target-specs/foo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ trait Sized {}
auto trait Freeze {}

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

Expand Down
16 changes: 13 additions & 3 deletions src/test/ui/lang-items/lang-item-generic-requirements.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Checks whether declaring a lang item with the wrong number
// of generic arguments crashes the compiler (issue #83893, #87573, and part of #9307).
// Checks that declaring a lang item with the wrong number
// of generic arguments errors rather than crashing (issue #83893, #87573, part of #9307, #79559).

#![feature(lang_items, no_core)]
#![no_core]
#![crate_type = "lib"]

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

// When the `start` lang item is missing generics very odd things can happen, especially when
// it comes to cross-crate monomorphization
#[lang = "start"]
//~^ ERROR `start` language item must be applied to a function with 1 generic argument [E0718]
fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
0
}

fn ice() {
// Use add
let r = 5;
Expand All @@ -42,3 +49,6 @@ fn ice() {
// Use phantomdata
let _ = MyPhantomData::<(), i32>;
}

// use `start`
fn main() {}
23 changes: 16 additions & 7 deletions src/test/ui/lang-items/lang-item-generic-requirements.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error[E0718]: `add` language item must be applied to a trait with 1 generic argument
--> $DIR/lang-item-generic-requirements.rs:11:1
--> $DIR/lang-item-generic-requirements.rs:10:1
|
LL | #[lang = "add"]
| ^^^^^^^^^^^^^^^
LL | trait MyAdd<'a, T> {}
| ------- this trait has 2 generic arguments

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

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

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

error[E0718]: `start` language item must be applied to a function with 1 generic argument
--> $DIR/lang-item-generic-requirements.rs:30:1
|
LL | #[lang = "start"]
| ^^^^^^^^^^^^^^^^^
LL |
LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
| - this function has 0 generic arguments

error[E0392]: parameter `T` is never used
--> $DIR/lang-item-generic-requirements.rs:25:22
--> $DIR/lang-item-generic-requirements.rs:24:22
|
LL | struct MyPhantomData<T, U>;
| ^ unused parameter
Expand All @@ -42,15 +51,15 @@ LL | struct MyPhantomData<T, U>;
= help: if you intended `T` to be a const parameter, use `const T: usize` instead

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

error: aborting due to 6 previous errors
error: aborting due to 7 previous errors

Some errors have detailed explanations: E0392, E0718.
For more information about an error, try `rustc --explain E0392`.
5 changes: 3 additions & 2 deletions src/tools/clippy/tests/ui/def_id_nocore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ pub trait Copy {}
pub unsafe trait Freeze {}

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

fn main() {}

struct A;

impl A {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/def_id_nocore.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
--> $DIR/def_id_nocore.rs:26:19
--> $DIR/def_id_nocore.rs:27:19
|
LL | pub fn as_ref(self) -> &'static str {
| ^^^^
Expand Down

0 comments on commit 3d86aac

Please sign in to comment.