There's an extra layer of indirection in that struct definition. A &'a fn()
is a pointer to a pointer to a function. A statement like "self_.statefn =
&finished;" expands to "let foo = finished; self_.statefn = &foo". That's
obviously creating a dangling pointer onto the stack which is why it ends
up crashing. Adjusting the struct definition to
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.
Steven Fackler
On Fri, Apr 18, 2014 at 8:30 AM, Ziad Hatahet <[email protected]> wrote:
> Confirm repro on an older rustc version. Ubuntu 13.10 running rustc
> 0.11-pre (ecc774f 2014-04-11 13:46:45 -0700).
>
>
> --
> Ziad
>
>
> On Fri, Apr 18, 2014 at 4:38 AM, Phil Dawes <[email protected]>wrote:
>
>> Hello everyone,
>>
>> I was trying to create an iterator that used a function pointer to
>> alternate between different states, and ended up core dumping. I've pasted
>> a version that generates the issue on my box (Ubuntu 12.04 LTS,
>> rust-nightly pulled just now). Can anybody reproduce this on their
>> machines? If so I'll file a bug.
>>
>> Cheers,
>>
>> Phil
>>
>> struct StateMachineIter<'a> {
>> statefn: &'a fn(&mut StateMachineIter<'a>) -> Option<&'static str>
>> }
>>
>> impl<'a> Iterator<&'static str> for StateMachineIter<'a> {
>> fn next(&mut self) -> Option<&'static str> {
>> return (*self.statefn)(self);
>> }
>> }
>>
>> fn state1(self_: &mut StateMachineIter) -> Option<&'static str> {
>> self_.statefn = &state2;
>> return Some("state1");
>> }
>>
>> fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> {
>> self_.statefn = &state3;
>> return Some("state2");
>> }
>>
>> fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> {
>> self_.statefn = &finished;
>> return Some("state3");
>> }
>>
>> fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> {
>> return None;
>> }
>>
>> fn state_iter() -> StateMachineIter {
>> StateMachineIter { statefn: &state1 }
>> }
>>
>>
>> fn main() {
>> let mut it = state_iter();
>> println!("{}",it.next());
>> println!("{}",it.next());
>> println!("{}",it.next());
>> println!("{}",it.next());
>> println!("{}",it.next());
>> }
>>
>>
>> _______________________________________________
>> Rust-dev mailing list
>> [email protected]
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
>
>
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev