Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
ethe opened this issue Jan 4, 2024 · 4 comments
Closed

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

ethe opened this issue Jan 4, 2024 · 4 comments
Labels
A-lifetimes Area: Lifetimes / regions

Comments

@ethe
Copy link

ethe commented Jan 4, 2024

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
@ethe ethe added the C-bug Category: This is a bug. label Jan 4, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jan 4, 2024
@csmoe
Copy link
Member

csmoe commented Jan 4, 2024

The difference seems specified in the RFC https://rustc-dev-guide.rust-lang.org/return-position-impl-trait-in-trait.html#projections-dont-have-variances

@compiler-errors compiler-errors removed the C-bug Category: This is a bug. label Jan 4, 2024
@QuineDot
Copy link

CC #117587

@jieyouxu
Copy link
Member

@rustbot label +A-lifetimes +F-impl_trait_in_fn_trait_return -needs-triage

@rustbot rustbot added A-lifetimes Area: Lifetimes / regions F-impl_trait_in_fn_trait_return `#![feature(impl_trait_in_fn_trait_return)]` and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Feb 14, 2024
@compiler-errors compiler-errors removed the F-impl_trait_in_fn_trait_return `#![feature(impl_trait_in_fn_trait_return)]` label Jan 3, 2025
@compiler-errors
Copy link
Member

This is not a bug, and this also has nothing to do with feature(impl_trait_in_fn_trait_return).

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-lifetimes Area: Lifetimes / regions
Projects
None yet
Development

No branches or pull requests

6 participants