Skip to content
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

type-check lang items #9307

Open
thestinger opened this issue Sep 19, 2013 · 16 comments
Open

type-check lang items #9307

thestinger opened this issue Sep 19, 2013 · 16 comments
Labels
A-frontend Area: frontend (errors, parsing and HIR) A-lang-item Area: lang items A-typesystem Area: The type system C-enhancement Category: An issue proposing an enhancement or a PR with one. E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. glacier ICE tracked in rust-lang/glacier. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. P-low Low priority requires-internal-features This issue requires the use of internal features T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@thestinger
Copy link
Contributor

These aren't currently well-defined by the language. If you define anything with a somewhat matching LLVM signature, it will compile. Not only does it not care about the type signatures matching what it expects, there is no handling for these being defined on the wrong types of AST nodes.

@thestinger
Copy link
Contributor Author

I don't think this is milestone-worthy, because these are already implementation details.

@emberian
Copy link
Member

This leads to craziness like:

#[no_std];

#[main]
#[lang="start"]
fn start() { }
[2:21:07]/tmp> rustc foo.rs
task 'rustc' has overflowed its stack
zsh: illegal hardware instruction (core dumped) rustc foo.rs

or, more benignly:

#[no_std];

#[lang="start"]
fn start() { }

#[main]
fn main() { }

which just plain asserts:

rustc: /build/rust-git/src/rust/src/llvm/lib/IR/Instructions.cpp:276: void llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>, const llvm::Twine&): Assertion `(Args.size() == FTy->getNumParams() || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Calling a function with bad signature!"' failed.

or, more crazily:

#[no_std];

#[lang="start"]
mod a { }

#[main]
fn main() { }

which "just" ICEs:

error: internal compiler error: node_id_to_type: no type for node `mod a (id=2)`
This message reflects a bug in the Rust compiler. 
We would appreciate a bug report: https://github.com/mozilla/rust/wiki/HOWTO-submit-a-Rust-bug-report
task 'rustc' failed at 'explicit failure', /build/rust-git/src/rust/src/libsyntax/diagnostic.rs:102
task '<main>' failed at 'explicit failure', /build/rust-git/src/rust/src/librustc/lib.rs:395

Language items are the interface between the compiler and the language. They need to be well-defined and verified for correctness, IMO.

@emberian
Copy link
Member

(Nominating)

@pnkfelix
Copy link
Member

This should not block 1.0. Assigning P-low.

@nagisa
Copy link
Member

nagisa commented Apr 22, 2015

Still asserts with

#![no_std]
#![feature(no_std,core,lang_items)]

extern crate core;

#[lang="start"]
fn main() {
}

#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop{} }

@steveklabnik
Copy link
Member

Triage: no changes

@steveklabnik steveklabnik added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed A-libs labels Mar 24, 2017
@Mark-Simulacrum Mark-Simulacrum added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jun 24, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 19, 2017
@asquared31415
Copy link
Contributor

I've looked at this a little and I think that the existing detection that #85339 added to traits could be expanded to include most or all of the lang items. This wouldn't be a full solution but it would help to stop some of the ICEs that occur on functions and structs that are lang items.

Manishearth added a commit to Manishearth/rust that referenced this issue Sep 14, 2021
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``
@pnkfelix
Copy link
Member

The point here is that unlike almost everything else in Rust, lang items are always pretty visible and when changing their signature it's almost always done inside libstd/libcore and as such the time investment into checking them (compile time and human time) seems to make this not really worth tracking. If a minimal PR was filed and/or we gradually started doing this, that's reasonable, but IMO we gain almost nothing from having an issue.

I want to push back on one part of the above message.

I understand where @Mark-Simulacrum is coming from: Why do this work, when the thing we're checking is almost always part of libcore/libstd, and thus hopefully receiving significant review for correctness, especially when it comes to something like well-formedness.

But: What about the developers who are making alternative libstds? That's a scenario where it seems like these checks would bring joy, not waste time. (Right?)

In any case, even if it turns out that some of the introduced checks have non-trivial cost, I think we could still justify adding such checks if we can either 1. detect when we're compiling an "unblessed" libcore/libstd, or 2. put them under a -Z or -C flag. That could address the important use case while mitigating the danger of making all the other compiler invocations slower.

@Mark-Simulacrum
Copy link
Member

FWIW, I think my perspective has changed a little since 2019, in part informed by the increased presence of alternative (or at least small change fork implementations of std + alloc (and in some cases core). So I think the checks are mostly valuable these days, particularly for any new lang items.

I do think we should be cautious about making sure added checks are complete (i.e., actually verify correctness). While it is "just a bug" if we get it wrong, it is much easier in practice for folks to assume we're checking everything if we check partially, I think, especially in this area.

bors added a commit to rust-lang-ci/rust that referenced this issue Sep 24, 2021
Add basic checks for well-formedness of `fn`/`fn_mut` lang items

This pull request fixes rust-lang#83471. Lang items are never actually checked for well-formedness (rust-lang#9307). This means that one can get an ICE quite easily, e.g. as follows:
```rust
#![feature(lang_items)]
#[lang = "fn"]
trait MyFn {
    const call: i32 = 42;
}

fn main() {
    (|| 42)();
}
```
or this:
```rust
#![feature(lang_items)]
#[lang = "fn"]
trait MyFn {
    fn call(i: i32, j: i32);
}

fn main() {
    (|| 42)();
}
```
Ideally, there should probably be a more comprehensive strategy for checking lang items for well-formedness, but for the time being, I have added some rudimentary well-formedness checks that prevent rust-lang#83471 and similar issues.
ehuss added a commit to ehuss/rust that referenced this issue Sep 30, 2021
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`
Manishearth added a commit to Manishearth/rust that referenced this issue Sep 30, 2021
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``
Manishearth added a commit to Manishearth/rust that referenced this issue Sep 30, 2021
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```
Manishearth added a commit to Manishearth/rust that referenced this issue Oct 1, 2021
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````
flip1995 pushed a commit to flip1995/rust that referenced this issue Oct 7, 2021
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````
@inquisitivecrystal inquisitivecrystal added the E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. label Jan 6, 2022
@Noratrieb Noratrieb added the requires-internal-features This issue requires the use of internal features label Apr 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-frontend Area: frontend (errors, parsing and HIR) A-lang-item Area: lang items A-typesystem Area: The type system C-enhancement Category: An issue proposing an enhancement or a PR with one. E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. glacier ICE tracked in rust-lang/glacier. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. P-low Low priority requires-internal-features This issue requires the use of internal features T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests