danielhenrymantilla/polonius-the-crab.rs

Unexpected "unreachable call" warning in macro `polonius_loop` usage

Closed this issue · 0 comments

ethe commented

Crate version:

[dependencies]
polonius-the-crab = "0.3.0"

rustc version:

rustc 1.65.0-nightly (015a824f2 2022-08-22)

Show case:

use polonius_the_crab::prelude::*;

trait ContexIterator<'context, Cx> {
    type Item;

    fn next(&mut self) -> Option<(&mut Cx, Self::Item)>;

    fn find<F>(&mut self, f: &mut F) -> Option<(&Cx, Self::Item)>
    where
        F: FnMut(&mut Cx, &Self::Item) -> bool,
    {
        let mut s = self;
        polonius_loop!(|s| -> Option<(&'polonius Cx, Self::Item)> {
            if let Some((cx, item)) = s.next() {
                if f(cx, &item) {
                    polonius_return!(Some((cx, item)));
                }
            } else {
                polonius_break!();
            }
        });
        None
    }
}

#[cfg(test)]
mod tests {
    use crate::ContexIterator;

    #[derive(Debug)]
    pub struct Iter<'context, 'source, Cx, I> {
        inner: &'source [I],
        context: &'context mut Cx,
        index: usize,
    }

    impl<'context, 'source, Cx, I> ContexIterator<'context, Cx> for Iter<'context, 'source, Cx, I> {
        type Item = &'source I;

        fn next(&mut self) -> Option<(&mut Cx, Self::Item)> {
            let item = self
                .inner
                .get(self.index)
                .map(|item| (&mut *self.context, item));
            self.index += 1;
            item
        }
    }

    #[test]
    fn test() {
        let v = vec![1, 2, 3];
        let mut i = Iter {
            inner: &v,
            context: &mut (),
            index: 0,
        };
        println!("{:?}", i.find(&mut |_, i| **i % 2 == 0));
    }
}

cargo check output:

 ↳ cargo check
warning: unreachable call
  --> src/lib.rs:13:9
   |
13 | /         polonius_loop!(|s| -> Option<(&'polonius Cx, Self::Item)> {
14 | |             if let Some((cx, item)) = s.next() {
15 | |                 if f(cx, &item) {
16 | |                     polonius_return!(Some((cx, item)));
...  |
20 | |             }
21 | |         });
   | |          ^
   | |          |
   | |__________unreachable call
   |            any code following this expression is unreachable
   |
   = note: `#[warn(unreachable_code)]` on by default
   = note: this warning originates in the macro `$crate::polonius_break_dependent` which comes from the expansion of the macro `polonius_loop` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: `iter` (lib) generated 1 warning