-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
ICE when constructing monomorphic vtable in a static in dependent crate. #63226
Comments
cc @oli-obk |
I think we have another issue open for another symptom of this bug but I can't find it. Basically the problem is that we fail to recognize that the allocation containing the function pointer came from another crate and thus was already collected. Since we don't realize we don't need to collect the alloc, we do so and try to collect the function pointers in it. Maybe we can cause the same bug by having a const fn return a function pointer and then storing that in a constant. |
These also produce the same error(when running doctests): #![feature(const_fn)]
/// ```
/// const ICE_ICE:fn()=playground::returns_fn_ptr();
/// ```
pub const fn returns_fn_ptr()-> fn() {
state
}
fn state(){ } #![feature(const_fn)]
/// ```
/// const ICE_ICE:fn()=playground::FN_PTR;
/// ```
pub const fn returns_fn_ptr()-> fn() {
state
}
pub const FN_PTR:fn()=returns_fn_ptr();
fn state(){ } Error:
|
OK, so essentially it boils down to "don't try to monomorphize functions that can't be monomorphized locally, and assume they have been monomorphized upstream". Going for that logic will fix all of the ICEs we've had at this site, but also turn hypothetical compiler bugs that were ICEs into linker errors (undefined reference) |
cc @rust-lang/compiler I see no other way (see previous post) to prevent the collector from trying to collect function pointers in constants if the function comes from a different crate, without breaking the case where we need to collect the function pointer because the function comes from the local crate. We may have local constants with function pointers to functions from other crates and constants with references to constants from other crates that contain function pointers. So there's no use in checking where the constant came from. Const eval could theoretically return a list of created function pointers, but that would just be a complicated way of subverting the ICE. We can make sure to just silence the ICE in the constant case, to ensure it still catches bugs in the regular case. Opinions? |
Assigning @oli-obk and @michaelwoerister to discuss options here. P-high to revisit. |
I think the way we handled situations like this in the past was to make the reachable pass expand the set of items that are considered to be reachable by downstream crates. However, I'm not sure if it is powerful enough to provide a permanent solution. Some backround: IIRC, the privacy pass collects the set of items that are publicly visible from outside the crate, and the reachable expands this set by things that might be needed to instantiate the initial set of items in a downstream crate. E.g. if there is a public generic function that calls a private generic function, then it is the So, maybe the right solution here would be to make the reachable pass add things reachable from constants. Then the following check would make sure that we link to the upstream item:
Looking through the code in reachable, it looks like this should already be the case. Maybe it's just a subtle bug somewhere? |
The problem isn't constants (which are checked correctly). It's const fns. So presumably all we need to do is make rust/src/librustc/middle/reachable.rs Lines 30 to 43 in 813a3a5
const fn as inline ?
|
If the problem is that things in |
Impl instructions:
|
Rollup of 9 pull requests Successful merges: - #63155 (Add UWP MSVC targets) - #63165 (Add builtin targets for mips64(el)-unknown-linux-muslabi64) - #63306 (Adapt AddRetag for shallow retagging) - #63467 (Add Catalyst (iOS apps running on macOS) target) - #63546 (Remove uses of `mem::uninitialized()` from cloudabi) - #63572 (remove unused Level::PhaseFatal) - #63577 (Test HRTB issue accepted by compiler) - #63582 (Fix ICE #63226) - #63586 (cleanup: Remove `Spanned` where possible) Failed merges: r? @ghost
Nice! Thanks @oli-obk for writing up the instructions and @JohnTitor for implementing them! |
This is ICE happens when I call
ROnce::new
from the abi_stable crate in const contexts in dependent crates/doctests,but not when using the
ROnce::NEW
associated constant.Reproducing
It can be reproduced using a doctest in the playground:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=27b35d06267adeacb7334388600c96be
It can also be reproduced by cloning this repository,and then build lib_1.
Code
The code for the linked repositories is :
lib_0:
lib_1:
Error
This is the error message:
The text was updated successfully, but these errors were encountered: