Skip to content
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

Tracking issue for mutable_borrow_reservation_conflict compatibility lint #59159

Closed
1 of 3 tasks
Tracked by #57895
pnkfelix opened this issue Mar 13, 2019 · 15 comments · Fixed by #96268
Closed
1 of 3 tasks
Tracked by #57895

Tracking issue for mutable_borrow_reservation_conflict compatibility lint #59159

pnkfelix opened this issue Mar 13, 2019 · 15 comments · Fixed by #96268
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. A-NLL Area: Non-lexical lifetimes (NLL) C-future-incompatibility Category: Future-incompatibility lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@pnkfelix
Copy link
Member

pnkfelix commented Mar 13, 2019

This is the summary issue for the mutable_borrow_reservation_conflict future-compatibility warning and other related errors. The goal of this page is describe why this change was made and how you can fix code that is affected by it. It also provides a place to ask questions or register a complaint if you feel the change should not be made. For more information on the policy around future-compatibility warnings, see our breaking change policy guidelines.

What is this lint about

A two-phase borrow is a mutable-borrow that is initially reserved at one point in the program's control-flow, and then subsequently activated at a later point in the control-flow.

For example, given a vector v, v.push(v.len()) first reserves a borrow of v when it evaluates the method receiver, but does not activate that borrow until later when transferring control to the push method itself, after v.len() has been evaluated.

This lint detects instances where the reservation itself conflicts with some pre-existing borrow. For example:

   let mut v = vec![0, 1, 2];
   let shared = &v;
             // ~~ 
             // a shared borrow of `v` starts here ...
   v.push(shared.len());
// ~      ~~~~~~
// |      ... and that shared borrow is used here...
// |
// ... but that comes after the reservation of the
//     mutable borrow of `v` here (the reservation
//     is subsequently activated when `push` is invoked)

The latter code is an example of code that was accepted when two-phased borrows (2PB) initially landed, as part of non-lexical lifetimes (NLL) deployment in the 2018 edition.

This lint detects such cases, and warns that this pattern may be rejected by a future version of the compiler.

This is much further discussion of this at the following places:

How to fix this warning/error

Revise the code so that the initial evaluation of the mutable borrow (the "reservation") always comes after all uses of shared borrows it conflicts with.

One example revision of the example above:

let mut v = vec![0, 1, 2];
let shared = &v;
let len = shared.len();
v.push(len);

Now, the last use of shared comes before the reservation in v.push(len), and thus there is no conflict between the shared borrow and the mutable borrow reservation.

Historical background

At the time NLL was stabilized, this borrowing pattern was not meant to be accepted, because it complicates the abstract model for borrows and thus poses problems for unsafe code authors and for future compiler optimizations. (How much complication it introduces is a matter of debate, which is in part why this restriction is being given treatment different from other future compatibility lints.)

In other words: at the time that NLL was stabilized, the compiler's acceptance of this borrowing pattern was categorized by the NLL team as a "known bug". The NLL team assumed that, as a bug fix, the compiler would be allowed to start rejecting the pattern in the future.

Whether a future version of the compiler rejects the code will depend on an investigation of potential abstract models of the language semantics; we will not convert the lint to a hard error without first performing an evaluation of such abstract models.

Timeline:

Current status

@pnkfelix pnkfelix added C-future-incompatibility Category: Future-incompatibility lints A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 18, 2019
@pnkfelix
Copy link
Member Author

pnkfelix commented Mar 28, 2019

From #58739 (comment), some follow-up tasks are associated with this 2-phase borrow (2PB) issue:

  • We need to develop and evaluate alternative semantic models,
  • We need to pin down more precisely the optimization impact, even if it is only a potential impact as of now,
  • We need to specify the impact of this choice on the rules for unsafe code.
  • (Also, on a meta-level, the T-lang design team needs do a retrospective on our processes and find changes that would help prevent repeat occurrences of the mistake (or at least misunderstanding) that occurred here.)

bors added a commit that referenced this issue Apr 7, 2019
More restrictive 2 phase borrows - take 2

Signal lint diagnostic `mutable_borrow_reservation_conflict` when borrow-check finds a 2-phase borrow's reservation overlapping with a shared borrow.

(pnkfelix updated description)

cc #56254 , #59159

blocks PR #59114

r? @pnkfelix

cc @RalfJung @nikomatsakis
bors bot added a commit to rust-lang/rust-analyzer that referenced this issue Apr 8, 2019
1121: Avoid two-phase borrow conflict r=matklad a=lnicola

See rust-lang/rust#59159.

Co-authored-by: Laurențiu Nicola <lnicola@dend.ro>
@nox
Copy link
Contributor

nox commented Apr 12, 2019

Why are method receivers even handled before the arguments passed to the method?

@nox
Copy link
Contributor

nox commented Apr 12, 2019

I just connected my two last brain cells alive on this Friday evening and just realised that evaluating the method receiver last would make for a very confusing control flow with chained method calls, disregard me.

rye added a commit to rye/nessify that referenced this issue Apr 15, 2019
Here we needed to revise the code so that the initial evaluation of the
mutable borrow always comes after each use of the shared borrow that it
conflicts with.  In this case, this just meant that I needed to pull
the value out of the function call, so that the calculation of the
value passed into plugins.replace was computed _strictly_ before the
call began?

Something like that.

This is in relation to rust-lang/rust#59159, which is effectively going
to remove two-phase borrows in this context.

Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com>
Tested-by: Kristofer Rye <kristofer.rye@gmail.com>
etaoins added a commit to etaoins/arret that referenced this issue Apr 15, 2019
This is described in rust-lang/rust#59159. This is a warning on nightly
but may become a hard error later.
pnkfelix added a commit to pnkfelix/rust-analyzer that referenced this issue Apr 29, 2019
bors bot added a commit to rust-lang/rust-analyzer that referenced this issue Apr 30, 2019
1217: Sidestep two-phase borrow violation r=matklad a=pnkfelix

Sidestep two-phase borrow violation signaled by mutable_borrow_reservation_conflict.

See rust-lang/rust#59159 for further information/discussion.

Co-authored-by: Felix S. Klock II <pnkfelix@pnkfx.org>
sebpuetz added a commit to sebpuetz/conllx-rs that referenced this issue May 29, 2019
danieldk pushed a commit to danieldk/conllx-rs that referenced this issue May 29, 2019
sunfishcode added a commit to bytecodealliance/wasmtime that referenced this issue May 30, 2019
Fix the following warning from Rust 1.35:

warning: cannot borrow `*self` as mutable because it is also borrowed as immutable
   --> wasmtime-runtime/src/instance.rs:473:25
    |
465 |         } else if let Some(start_export) = self.module.exports.get("_start") {
    |                                            ----------- immutable borrow occurs here
...
473 |                         self.invoke_function(*func_index)
    |                         ^^^^                 ----------- immutable borrow later used here
    |                         |
    |                         mutable borrow occurs here
    |
    = note: #[warn(mutable_borrow_reservation_conflict)] on by default
    = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
    = note: for more information, see issue #59159 <rust-lang/rust#59159>
sunfishcode added a commit to bytecodealliance/wasmtime that referenced this issue May 31, 2019
Fix the following warning from Rust 1.35:

warning: cannot borrow `*self` as mutable because it is also borrowed as immutable
   --> wasmtime-runtime/src/instance.rs:473:25
    |
465 |         } else if let Some(start_export) = self.module.exports.get("_start") {
    |                                            ----------- immutable borrow occurs here
...
473 |                         self.invoke_function(*func_index)
    |                         ^^^^                 ----------- immutable borrow later used here
    |                         |
    |                         mutable borrow occurs here
    |
    = note: #[warn(mutable_borrow_reservation_conflict)] on by default
    = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
    = note: for more information, see issue #59159 <rust-lang/rust#59159>
@andrewchambers
Copy link

andrewchambers commented Jun 1, 2019

I am registering a complaint - Very irritating to be told by users about this warning appearing in previously released crates. So old crates will just break without an edition change? How is that supposed to work?

Has there been a survey of crates.io to determine how many crates will stop compiling?

dabreegster added a commit to a-b-street/abstreet that referenced this issue Jun 9, 2019
hhvm-bot pushed a commit to facebook/hhvm that referenced this issue Jun 12, 2019
Summary:
Previously we had the following warning:

```
warning: cannot borrow `*self` as mutable because it is also borrowed as immutable
    --> hphp/hack/src/parser/lexer.rs:1956:25
     |
1946 |             let original_text = self.current_text_as_str(); //
     |                                 ---- immutable borrow occurs here
...
1956 |                         self.with_error(Errors::uppercase_kw(original_text));
     |                         ^^^^ mutable borrow occurs here      ------------- immutable borrow later used here
     |
     = note: #[warn(mutable_borrow_reservation_conflict)] on by default
     = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
     = note: for more information, see issue #59159 <rust-lang/rust#59159>
```

Refactor the code so that the scope of `original_text` doesn't extend to `self.with_error`. This is consistent with the vector example given in [Rust issue #59159](rust-lang/rust#59159).

Reviewed By: losvald

Differential Revision: D15759079

fbshipit-source-id: f5d067f32243abc75c7d2ac35709628ea34a48e9
nindalf added a commit to nindalf/advent-2018 that referenced this issue Jun 16, 2019
Full context in this issue - rust-lang/rust#59159

It is currently a warning to borrow a map as mutable and then modify it.

Replacing such uses with the entry API.
tschneidereit pushed a commit to tschneidereit/wasmtime that referenced this issue Jun 25, 2019
Fix the following warning from Rust 1.35:

warning: cannot borrow `*self` as mutable because it is also borrowed as immutable
   --> wasmtime-runtime/src/instance.rs:473:25
    |
465 |         } else if let Some(start_export) = self.module.exports.get("_start") {
    |                                            ----------- immutable borrow occurs here
...
473 |                         self.invoke_function(*func_index)
    |                         ^^^^                 ----------- immutable borrow later used here
    |                         |
    |                         mutable borrow occurs here
    |
    = note: #[warn(mutable_borrow_reservation_conflict)] on by default
    = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
    = note: for more information, see issue #59159 <rust-lang/rust#59159>
@pnkfelix
Copy link
Member Author

pnkfelix commented Jul 9, 2019

@andrewchambers 's complaint above included the question:

Has there been a survey of crates.io to determine how many crates will stop compiling?

And the answer is Yes. In particular, the timeline in the issue description includes a bullet from 2019-03-06, describing the crater run we did as part of investigating whether to add the diagnostic detecting violations of the 2 phase borrows restriction.

maloneymr added a commit to quail-lang/quail that referenced this issue Nov 30, 2020
Note that while doing this, I encountered a corner case of the
borrow-checker:

    rust-lang/rust#59159

The following attribute suppresses the warning (which would otherwise
cause continuous integration to fail):

    #[allow(mutable_borrow_reservation_conflict)]

Taking a second look at this, it seems a bit dubious that the eval()
method should be mutating the Runtime at all. This suggests that I
should split the Runtime into two substructures: an immutable part
containing the local context, the builtins, the global context, etc, and
a mutable part which contains the readline Editor and the hole
information. The evaluation part can then be purely functional, while
hole-filling can be mutative.
maloneymr added a commit to quail-lang/quail that referenced this issue Nov 30, 2020
Note that while doing this, I encountered a corner case of the
borrow-checker:

    rust-lang/rust#59159

The following attribute suppresses the warning (which would otherwise
cause continuous integration to fail):

    #[allow(mutable_borrow_reservation_conflict)]

Taking a second look at this, it seems a bit dubious that the eval()
method should be mutating the Runtime at all. This suggests that I
should split the Runtime into two substructures: an immutable part
containing the local context, the builtins, the global context, etc, and
a mutable part which contains the readline Editor and the hole
information. The evaluation part can then be purely functional, while
hole-filling can be mutative.
cundd added a commit to chorddown/chordr that referenced this issue Dec 5, 2020
@svanderbleek
Copy link

svanderbleek commented Feb 17, 2021

This came up for me I had to turn

let parent_name = self.paths.get(&parent).expect(&error);
if param {
  self.paths.insert(id, format!("{}/:{}", parent_name, name));
} else {
  self.paths.insert(id, format!("{}/{}", parent_name, name));
}

into

let parent_name = self.paths.get(&parent).expect(&error);
if param {
  let id_name = format!("{}/:{}", parent_name, name);
  self.paths.insert(id, id_name);
} else {
  let id_name = format!("{}/{}", parent_name, name);
  self.paths.insert(id, id_name);
}

which seems like a misapplication of the trigger for the warning. I was able to reproduce with the following code

let mut h: HashMap<String, String> = HashMap::new();
h.insert(String::from("a"), String::from("a"));
let a = h.get("a").unwrap();
h.insert(String::from("b"), format!("{}", a));

which produces

warning: cannot borrow `h` as mutable because it is also borrowed as immutable
 --> src/main.rs:7:3
  |
6 |   let a = h.get("a").unwrap();
  |           - immutable borrow occurs here
7 |   h.insert(String::from("b"), format!("{}", a));
  |   ^ mutable borrow occurs here              - immutable borrow later used here
  |
  = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default
  = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
  = note: for more information, see issue #59159 <https://github.com/rust-lang/rust/issues/59159>

into

let mut h: HashMap<String, String> = HashMap::new();
h.insert(String::from("a"), String::from("a"));
let a = h.get("a").unwrap();
let v = format!("{}", a);
h.insert(String::from("b"), v);

which produces no warnings.

Is there anywhere I should follow this up? I'm new to Rust.

@kristof-mattei
Copy link
Contributor

kristof-mattei commented Nov 20, 2021

@svanderbleek https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6ed725446c9194c9ad0314cfbdb9967b

If you clone a before inserting you're good.

I ran into this warning-to-become as well:

let mut counts: HashMap<char, u32> = HashMap::new();

self.password
    .chars()
    .for_each(|c| match counts.get(&c) {
        None => {
            counts.insert(c, 1);
        }
        Some(t) => {
            let _ = counts.insert(c, *t + 1);
        }
    });

yielded

warning: cannot borrow `counts` as mutable because it is also borrowed as immutable
  --> src/day_2/part_1.rs:23:29
   |
18 |             .for_each(|c| match counts.get(&c) {
   |                                 ------ immutable borrow occurs here
...
23 |                     let _ = counts.insert(c, *t + 1);
   |                             ^^^^^^           -- immutable borrow later used here
   |                             |
   |                             mutable borrow occurs here
   |
   = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default
   = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future

And I rewrote it as

self.password.chars().for_each(|c| {
    let count = *(counts.get(&c).unwrap_or(&0));

    let _ = counts.insert(c, count + 1);
});

nuxeh added a commit to nuxeh/aoc-2021 that referenced this issue Dec 5, 2021
   Compiling aoc0521 v0.1.0 (/home/ed/git/aoc-2021/05)
warning: cannot borrow `points` as mutable because it is also borrowed as immutable
  --> src/main.rs:85:32
   |
84 |             match points.get(&point) {
   |                   ------ immutable borrow occurs here
85 |                 Some(count) => points.insert(point, count+1),
   |                                ^^^^^^               ----- immutable borrow later used here
   |                                |
   |                                mutable borrow occurs here
   |
   = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default
   = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
   = note: for more information, see issue #59159 <rust-lang/rust#59159>

warning: `aoc0521` (bin "aoc0521") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 1.19s
     Running `target/debug/aoc0521`
[
    Line {
        start: Point {
            x: 0,
            y: 9,
        },
        end: Point {
            x: 5,
            y: 9,
        },
    },
    Line {
        start: Point {
            x: 8,
            y: 0,
        },
        end: Point {
            x: 0,
            y: 8,
        },
    },
    Line {
        start: Point {
            x: 9,
            y: 4,
        },
        end: Point {
            x: 3,
            y: 4,
        },
    },
    Line {
        start: Point {
            x: 2,
            y: 2,
        },
        end: Point {
            x: 2,
            y: 1,
        },
    },
    Line {
        start: Point {
            x: 7,
            y: 0,
        },
        end: Point {
            x: 7,
            y: 4,
        },
    },
    Line {
        start: Point {
            x: 6,
            y: 4,
        },
        end: Point {
            x: 2,
            y: 0,
        },
    },
    Line {
        start: Point {
            x: 0,
            y: 9,
        },
        end: Point {
            x: 2,
            y: 9,
        },
    },
    Line {
        start: Point {
            x: 3,
            y: 4,
        },
        end: Point {
            x: 1,
            y: 4,
        },
    },
    Line {
        start: Point {
            x: 0,
            y: 0,
        },
        end: Point {
            x: 8,
            y: 8,
        },
    },
    Line {
        start: Point {
            x: 5,
            y: 5,
        },
        end: Point {
            x: 8,
            y: 2,
        },
    },
]
Line { start: Point { x: 0, y: 9 }, end: Point { x: 5, y: 9 } }
dx=5 dy=0
n=5 ix=1 iy=0
Line { start: Point { x: 8, y: 0 }, end: Point { x: 0, y: 8 } }
dx=-8 dy=8
n=8 ix=1 iy=-1
Line { start: Point { x: 9, y: 4 }, end: Point { x: 3, y: 4 } }
dx=-6 dy=0
n=6 ix=1 iy=0
Line { start: Point { x: 2, y: 2 }, end: Point { x: 2, y: 1 } }
dx=0 dy=-1
n=1 ix=0 iy=1
Line { start: Point { x: 7, y: 0 }, end: Point { x: 7, y: 4 } }
dx=0 dy=4
n=4 ix=0 iy=1
Line { start: Point { x: 6, y: 4 }, end: Point { x: 2, y: 0 } }
dx=-4 dy=-4
n=4 ix=1 iy=1
Line { start: Point { x: 0, y: 9 }, end: Point { x: 2, y: 9 } }
dx=2 dy=0
n=2 ix=1 iy=0
Line { start: Point { x: 3, y: 4 }, end: Point { x: 1, y: 4 } }
dx=-2 dy=0
n=2 ix=1 iy=0
Line { start: Point { x: 0, y: 0 }, end: Point { x: 8, y: 8 } }
dx=8 dy=8
n=8 ix=1 iy=1
Line { start: Point { x: 5, y: 5 }, end: Point { x: 8, y: 2 } }
dx=3 dy=-3
n=3 ix=1 iy=-1
{Point { x: 8, y: 0 }: 1, Point { x: 8, y: 8 }: 1, Point { x: 6, y: 6 }: 1, Point { x: 10, y: 4 }: 1, Point { x: 7, y: 2 }: 1, Point { x: 2, y: 3 }: 1, Point { x: 4, y: 4 }: 2, Point { x: 11, y: 4 }: 1, Point { x: 7, y: 0 }: 1, Point { x: 7, y: 5 }: 1, Point { x: 12, y: -4 }: 1, Point { x: 3, y: 4 }: 1, Point { x: 7, y: 7 }: 1, Point { x: 10, y: -2 }: 1, Point { x: 1, y: 1 }: 1, Point { x: 8, y: 2 }: 1, Point { x: 11, y: -3 }: 1, Point { x: 2, y: 2 }: 2, Point { x: 7, y: 1 }: 1, Point { x: 7, y: 3 }: 2, Point { x: 6, y: 4 }: 2, Point { x: 9, y: 7 }: 1, Point { x: 13, y: 4 }: 1, Point { x: 3, y: 3 }: 1, Point { x: 15, y: -7 }: 1, Point { x: 2, y: 9 }: 2, Point { x: 10, y: 8 }: 1, Point { x: 3, y: 9 }: 1, Point { x: 9, y: -1 }: 1, Point { x: 13, y: -5 }: 1, Point { x: 5, y: 9 }: 1, Point { x: 5, y: 4 }: 1, Point { x: 4, y: 9 }: 1, Point { x: 16, y: -8 }: 1, Point { x: 9, y: 4 }: 1, Point { x: 12, y: 4 }: 1, Point { x: 0, y: 9 }: 2, Point { x: 14, y: -6 }: 1, Point { x: 15, y: 4 }: 1, Point { x: 8, y: 6 }: 1, Point { x: 5, y: 5 }: 2, Point { x: 7, y: 4 }: 1, Point { x: 1, y: 9 }: 2, Point { x: 14, y: 4 }: 1, Point { x: 0, y: 0 }: 1}
smallstepman added a commit to smallstepman/rs-scrape-kattis that referenced this issue Jan 4, 2022
albx79 pushed a commit to albx79/wordler that referenced this issue Jan 17, 2022
dtolnay added a commit to dtolnay/star-history that referenced this issue Jan 19, 2022
    warning: cannot borrow `*set` as mutable because it is also borrowed as immutable
       --> src/main.rs:451:13
        |
    450 |           if let Some(first) = set.iter().next() {
        |                                ---------- immutable borrow occurs here
    451 | /             set.insert(Star {
    452 | |                 time: first.time - Duration::seconds(1),
        | |                       ---------- immutable borrow later used here
    453 | |                 node: Default::default(),
    454 | |             });
        | |______________^ mutable borrow occurs here
        |
        = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default
        = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
        = note: for more information, see issue #59159 <rust-lang/rust#59159>
burjui added a commit to burjui/rambo that referenced this issue Mar 25, 2022
@bors bors closed this as completed in 9a25164 May 6, 2022
@TonalidadeHidrica
Copy link
Contributor

As this issue was closed by merging #96268 , can we now safely ignore this warning? I'm using 1.61.0 stable. Will this warning disappear if I updated to 1.62.0 in the future?

@nikomatsakis
Copy link
Contributor

@TonalidadeHidrica the warning will be going away in a future release, yes.

jason-h-35 added a commit to jason-h-35/rx that referenced this issue Aug 9, 2022
```
warning: lint `mutable_borrow_reservation_conflict` has been removed: now allowed, see issue #59159 <rust-lang/rust#59159> for more information
    --> src/session.rs:2681:21
     |
2681 |             #[allow(mutable_borrow_reservation_conflict)]
     |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: `#[warn(renamed_and_removed_lints)]` on by default

warning: `rx` (lib) generated 1 warning
```
abrown added a commit to abrown/wasmtime that referenced this issue Aug 11, 2022
In bytecodealliance#4375 we introduced a code pattern that appears as a warning when
building the `cranelift-interpreter` crate:

```
warning: cannot borrow `*state` as mutable because it is also borrowed as immutable
   --> cranelift/interpreter/src/step.rs:412:13
    |
47  |     let arg = |index: usize| -> Result<V, StepError> {
    |               -------------------------------------- immutable borrow occurs here
48  |         let value_ref = inst_context.args()[index];
49  |         state
    |         ----- first borrow occurs due to use of `*state` in closure
...
412 |             state.set_pinned_reg(arg(0)?);
    |             ^^^^^^^^^^^^^^^^^^^^^---^^^^^
    |             |                    |
    |             |                    immutable borrow later used here
    |             mutable borrow occurs here
    |
    = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default
    = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
    = note: for more information, see issue #59159 <rust-lang/rust#59159>
```

This change fixes the warning.
jameysharp pushed a commit to bytecodealliance/wasmtime that referenced this issue Aug 11, 2022
In #4375 we introduced a code pattern that appears as a warning when
building the `cranelift-interpreter` crate:

```
warning: cannot borrow `*state` as mutable because it is also borrowed as immutable
   --> cranelift/interpreter/src/step.rs:412:13
    |
47  |     let arg = |index: usize| -> Result<V, StepError> {
    |               -------------------------------------- immutable borrow occurs here
48  |         let value_ref = inst_context.args()[index];
49  |         state
    |         ----- first borrow occurs due to use of `*state` in closure
...
412 |             state.set_pinned_reg(arg(0)?);
    |             ^^^^^^^^^^^^^^^^^^^^^---^^^^^
    |             |                    |
    |             |                    immutable borrow later used here
    |             mutable borrow occurs here
    |
    = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default
    = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
    = note: for more information, see issue #59159 <rust-lang/rust#59159>
```

This change fixes the warning.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. A-NLL Area: Non-lexical lifetimes (NLL) C-future-incompatibility Category: Future-incompatibility lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants