Skip to content

Behavior of lifetime elision on RPITIT is not similar with RPIT #119575

Closed
@ethe

Description

@ethe

I tried this code:

pub trait Foo<'a> {
    fn apply(_: &mut ()) -> Result<Self, impl Bar>
    where
        Self: Sized;
}

trait Bar {
    fn apply(&self, _: &mut ());
}

impl Bar for () {
    fn apply(&self, _: &mut ()) {
        todo!()
    }
}

struct F<'a>(&'a ());

impl<'a> F<'a> {
    fn apply(arg: &mut ()) -> Result<F<'a>, impl Bar> {
        Err(())
    }
}

impl<'a> Foo<'a> for F<'a> {
    fn apply(arg: &mut ()) -> Result<F<'a>, impl Bar> {
        Err(())
    }
}

fn check(arg: &mut ()) {
    if let Err(e) = F::apply(arg) {
        e.apply(arg);
    } else {
        todo!()
    }

    if let Err(e) = <F as Foo>::apply(arg) {
        e.apply(arg);
    } else {
        todo!()
    }
}

I expected to see this happen: lifetime checking passed

Instead, this happened:

error[E0499]: cannot borrow `*arg` as mutable more than once at a time
  --> src/main.rs:39:17
   |
38 |     if let Err(e) = <F as Foo>::apply(arg) {
   |                     ----------------------
   |                     |                 |
   |                     |                 first mutable borrow occurs here
   |                     a temporary with access to the first borrow is created here ...
39 |         e.apply(arg);
   |                 ^^^ second mutable borrow occurs here
...
43 | }
   | - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `std::result::Result<F<'_>, impl Bar>`

Meta

rustc --version --verbose:

rustc 1.77.0-nightly (e51e98dde 2023-12-31)
binary: rustc
commit-hash: e51e98dde6a60637b6a71b8105245b629ac3fe77
commit-date: 2023-12-31
host: x86_64-unknown-linux-gnu
release: 1.77.0-nightly
LLVM version: 17.0.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lifetimesArea: Lifetimes / regions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions