Awesome, thanks Steven, that works now.
BTW, I filed bug https://github.com/mozilla/rust/issues/13595 before I read
your reply. I'll leave it for now in case the bug isn't recorded somewhere
else.

Cheers,

Phil

On Fri, Apr 18, 2014 at 4:47 PM, Steven Fackler <sfack...@gmail.com> wrote:

> 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 <hata...@gmail.com> 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 <rustp...@phildawes.net>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
>>> Rust-dev@mozilla.org
>>> https://mail.mozilla.org/listinfo/rust-dev
>>>
>>>
>>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to