Skip to content

[NLL] mutability difference #50897

Closed
@leonardo-m

Description

@leonardo-m
#![feature(generator_trait, generators)]
#![feature(nll)]

use std::ops::{Generator, GeneratorState};

fn generator_to_iterator<G>(g: G) -> impl Iterator<Item = G::Yield>
where G: Generator<Return = ()> {
    struct It<G>(G);

    impl<G: Generator<Return = ()>> Iterator for It<G> {
        type Item = G::Yield;

        fn next(&mut self) -> Option<Self::Item> {
            unsafe {
                match self.0.resume() {
                    GeneratorState::Yielded(y) => Some(y),
                    GeneratorState::Complete(()) => None,
                }
            }
        }
    }

    It(g)
}

fn foo(mut n: u32) -> impl Iterator<Item=u32> {
    generator_to_iterator(move || {
        while n != 0 {
            yield n;
            n -= 1;
        }
    })
}

fn main() {
    for d in foo(10) {
        println!("{}", d);
    }
}

Gives a warning:

warning: variable does not need to be mutable
  --> ...\test.rs:26:8
   |
26 | fn foo(mut n: u32) -> impl Iterator<Item=u32> {
   |        ----^
   |        |
   |        help: remove this `mut`
   |
   = note: #[warn(unused_mut)] on by default

If I remove the "mut" that warning goes away and the program runs correctly.

But if I comment out the feature(nll) line (without the "mut" in foo signature) it gives:

error[E0594]: cannot assign to immutable captured outer variable in an `FnOnce` closure `n`
  --> ...\test.rs:30:13
   |
30 |             n -= 1;
   |             ^^^^^^

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions