-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
internal compiler error using lang items #79559
Comments
The exact place of the bug seems to be here: rust/compiler/rustc_metadata/src/rmeta/decoder.rs Line 1181 in f8e5209
But interestingly enough not here:
|
I have done some research. The issue seems to be caused by the fact that So now there are two options: Either the main crate uses Alternatively, the main crate doesn't use
This all is very interesting because this exact code is what std uses ( Line 60 in afa995b
I'd like to mention @NULLx76 for helping to trace down the source of this bug. |
Update: rust/compiler/rustc_passes/src/entry.rs Line 160 in afa995b
ctx.entry_fn() . However, it always looks them up in this order:
So in short, it always prefers start over main. But when start is in another crate this fails the monomorphization process. |
We figured out that making lang_start generic in any way (the example in the original post above would become the codeblock below) fixes the ICE but still produces a linking error. use core::panic::PanicInfo;
#[lang = "start"]
#[no_mangle]
fn lang_start<T: 'static>(
main: fn() -> T,
_argc: isize,
_argv: *const *const u8,
) -> isize {
main();
return 0;
}
#[lang = "eh_personality"] extern fn rust_eh_personality() {}
#[lang = "panic_impl"] extern fn rust_begin_panic(_info: &PanicInfo) -> ! {
panic!("Yeet!");
}
#[lang = "oom"]
fn rust_alloc_error(_: core::alloc::Layout) -> ! {
panic!("Yeet oom!");
} This suggest that everything I said about what I thought the problem was may be false. The linking error:
|
You can add the |
That linking error has nothing to do with rustc. It simply means that |
ah of course |
alright, so given that that is linked in, this basically works. So the only problem now is that the lang=start item cannot not be generic or else it's an ICE |
It does work if the |
Either that or at least give a meaningful error |
@bjorn3 Can you give an example of it working correctly in the same crate? Whenever I try to use it in the same crate I get an LLVM error Honestly I'm surprised it gets this far at all because it is meant to be generic always and I would have expected a generic substitutions error. I think the correct course of action is to require the start lang item to have one generic type, because we should substitute in the return type of the |
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``
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`
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``
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```
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````
Code
This bug is isolated to nightly as lang items aren't yet supported in beta and up.
The code for this bug comes as far as I tested down to these two parts:
First some library crate with this in it:
(crate = langstart, src/lib.rs)
(basically a no_std program start similar to how it's done in std)
and then in some other crate (In the example I'll give it's a
example
of the library):I'm not quite sure if it's correct to use lang items in libraries, but in any case it should not give an internal compiler error.
I created a minimal repository demonstrating the bug. To run use
https://github.com/jonay2000/langstartbug
Meta
rustc --version --verbose
:Error output
Backtrace
The text was updated successfully, but these errors were encountered: