about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir/src/lang_items.rs2
-rw-r--r--src/test/run-make-fulldeps/target-specs/foo.rs2
-rw-r--r--src/test/ui/lang-items/lang-item-generic-requirements.rs16
-rw-r--r--src/test/ui/lang-items/lang-item-generic-requirements.stderr23
-rw-r--r--src/tools/clippy/tests/ui/def_id_nocore.rs5
-rw-r--r--src/tools/clippy/tests/ui/def_id_nocore.stderr2
6 files changed, 35 insertions, 15 deletions
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index d69a2470540..814054c5518 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -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;
diff --git a/src/test/run-make-fulldeps/target-specs/foo.rs b/src/test/run-make-fulldeps/target-specs/foo.rs
index 9ff33e24d04..d576a1dd281 100644
--- a/src/test/run-make-fulldeps/target-specs/foo.rs
+++ b/src/test/run-make-fulldeps/target-specs/foo.rs
@@ -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
 }
 
diff --git a/src/test/ui/lang-items/lang-item-generic-requirements.rs b/src/test/ui/lang-items/lang-item-generic-requirements.rs
index d785749afc9..c0b958f2bf2 100644
--- a/src/test/ui/lang-items/lang-item-generic-requirements.rs
+++ b/src/test/ui/lang-items/lang-item-generic-requirements.rs
@@ -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 {}
@@ -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;
@@ -42,3 +49,6 @@ fn ice() {
     // Use phantomdata
     let _ = MyPhantomData::<(), i32>;
 }
+
+// use `start`
+fn main() {}
diff --git a/src/test/ui/lang-items/lang-item-generic-requirements.stderr b/src/test/ui/lang-items/lang-item-generic-requirements.stderr
index add5938811c..df5a77850f1 100644
--- a/src/test/ui/lang-items/lang-item-generic-requirements.stderr
+++ b/src/test/ui/lang-items/lang-item-generic-requirements.stderr
@@ -1,5 +1,5 @@
 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"]
    | ^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ 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"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ 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"]
    | ^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ 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"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,8 +32,17 @@ 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
@@ -42,7 +51,7 @@ 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
@@ -50,7 +59,7 @@ LL | struct MyPhantomData<T, U>;
    = 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`.
diff --git a/src/tools/clippy/tests/ui/def_id_nocore.rs b/src/tools/clippy/tests/ui/def_id_nocore.rs
index cba7666c2d8..1ed78547a60 100644
--- a/src/tools/clippy/tests/ui/def_id_nocore.rs
+++ b/src/tools/clippy/tests/ui/def_id_nocore.rs
@@ -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 {
diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr
index 702684f6b43..6210d7c6cfd 100644
--- a/src/tools/clippy/tests/ui/def_id_nocore.stderr
+++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr
@@ -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 {
    |                   ^^^^