-
Notifications
You must be signed in to change notification settings - Fork 13.3k
core dump: fn pointer in iterator #13595
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
Comments
There's an extra layer of indirection in that struct definition. A struct StateMachineIter {
statefn: fn(&mut StateMachineIter) -> Option<&'static str>
} should make things work as you want. There's also a bug in rustc for even letting that program compile. I'm not sure if it's already been run into and filed. |
This fixes it: ...
fn finished(self_: &mut StateMachineIter) -> Option<(&'static str)> {
self_.statefn = &finished;
return None;
}
... But I didn't quite understand why. |
@edwardw it probably happens to reset that part of the stack to the right value. |
@alexcrichton @nikomatsakis @huonw p.s. This is still crashing in |
Nominating, something fishy is going on here. |
Here's the simplest possible reduction I could make: struct A<'a> {
func: &'a fn() -> Option<int>
}
impl<'a> A<'a> {
fn call(&self) -> Option<int> {
(*self.func)()
}
}
fn foo() -> Option<int> {
None
}
fn create() -> A<'static> {
A { func: &foo }
}
fn main() {
let a = create();
a.call();
} |
Is the compiler mixing up the function pointer with the actual function code? That is, fn foo() {}
fn main() { let x = foo; } is like static foo_code: [u8, .. N] = [/*machine code*/];
fn main() { let x = &foo_code; } // *not* let x = foo_code; So writing |
@huonw It's just creating an alloca, storing the function pointer into it, borrowing that, and returning the borrowed pointer. For example, on the program fn foo() { }
fn bar() -> &'static fn() {
&'static foo
} I get this LLVM IR: define internal void @_ZN3foo20h98be24cee3d646d9eaa4v0.0E() unnamed_addr #0 {
entry-block:
ret void
}
define internal nonnull void ()** @_ZN3bar20hb2bd4683ab9952d6haa4v0.0E() unnamed_addr #0 {
entry-block:
%addr_of = alloca void ()*
store void ()* @_ZN3foo20h98be24cee3d646d9eaa4v0.0E, void ()** %addr_of
ret void ()** %addr_of
} Basically, the borrow checker doesn't seem to be in on the joke that |
That is the behaviour I would expect if my statement were true. (The double |
1.0 backcompat-lang |
This is probably a mismatch between trans/mem-categorization. I expect mem-categorization is saying that the "reference to the fn" is a static item, but trans is translating it into an rvalue (and hence on the stack). |
This breaks code like: struct A<'a> { func: &'a fn() -> Option<int> } fn foo() -> Option<int> { ... } fn create() -> A<'static> { A { func: &foo } } Change this code to not take functions by reference. For example: struct A { func: extern "Rust" fn() -> Option<int> } fn foo() -> Option<int> { ... } fn create() -> A { A { func: foo } } Closes rust-lang#13595. [breaking-change]
This breaks code like: struct A<'a> { func: &'a fn() -> Option<int> } fn foo() -> Option<int> { ... } fn create() -> A<'static> { A { func: &foo } } Change this code to not take functions by reference. For example: struct A { func: extern "Rust" fn() -> Option<int> } fn foo() -> Option<int> { ... } fn create() -> A { A { func: foo } } Closes #13595. [breaking-change] r? @huonw
Hello! The following dumps core when run on my machine (Ubuntu 12.04 LTS, rust-nightly downloaded today (18th Apr)). Ziad Hatahet confirmed the same on a slightly older version of rust.
The text was updated successfully, but these errors were encountered: