Skip to content

Polonius fails to infer lifetimes of borrows #134554

Open
@zeenix

Description

@zeenix

I tried this code:

struct Foo([u8; 10]);

impl Foo {
    fn read_non_empty<'c, P>(&'c mut self) -> P
    where
        P: serde::Deserialize<'c> + std::string::ToString,
    {
        loop {
            let b: P = self.read();
            if !b.to_string().is_empty() {
                return b;
            }
        }
    }

    fn read<'c, P>(&'c mut self) -> P
    where
        P: serde::Deserialize<'c>,
    {
        unimplemented!();
    }
}

I expected to see this happen: Compilation to succeed.

Instead, this happened: Got an error:

RUSTFLAGS='-Zpolonius' cargo +nightly c --tests
    Checking tmp-scdnga v0.1.0 (/home/zeenix/.cache/cargo-temp/tmp-sCDnga)

error[E0499]: cannot borrow `*self` as mutable more than once at a time
 --> src/main.rs:9:24
  |
4 |     fn read_non_empty<'c, P>(&'c mut self) -> P
  |                       -- lifetime `'c` defined here
...
9 |             let b: P = self.read();
  |                        ^^^^-------
  |                        |
  |                        `*self` was mutably borrowed here in the previous iteration of the loop
  |                        argument requires that `*self` is borrowed for `'c`

For more information about this error, try `rustc --explain E0499`.
error: could not compile `tmp-scdnga` (bin "tmp-scdnga" test) due to 1 previous error

If I modify the code to not use a loop, I still get the same:

    fn read_non_empty<'c, P>(&'c mut self) -> P
    where
        P: serde::Deserialize<'c> + std::string::ToString,
    {
        {
            let b: P = self.read();
            if !b.to_string().is_empty() {
                return b;
            }
        }

        {
            let b: P = self.read();
            if !b.to_string().is_empty() {
                return b;
            }
        }

        unimplemented!();
    }

Meta

rustc --version --verbose:

rustc 1.85.0-nightly (9e136a30a 2024-12-19)
binary: rustc
commit-hash: 9e136a30a965bf4e63f03095c57df7257bf96fd6
commit-date: 2024-12-19
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.NLL-poloniusIssues related for using Polonius in the borrow checkerT-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions