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

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

Open
ethe opened this issue Jan 4, 2024 · 3 comments
Open

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

ethe opened this issue Jan 4, 2024 · 3 comments
Labels
A-lifetimes Area: Lifetimes / regions F-impl_trait_in_fn_trait_return `#![feature(impl_trait_in_fn_trait_return)]`

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions F-impl_trait_in_fn_trait_return `#![feature(impl_trait_in_fn_trait_return)]`
Projects
None yet
Development

No branches or pull requests

6 participants