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

Free functions and trait methods that return impl Trait capture lifetimes differently (edition 2021) #132759

Closed
golddranks opened this issue Nov 8, 2024 · 3 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.

Comments

@golddranks
Copy link
Contributor

golddranks commented Nov 8, 2024

I tried this code:

trait MyTrait {}
impl MyTrait for () { }

trait GetMyTrait {
    fn get(&self) -> impl MyTrait;
}

struct MyStruct;
impl GetMyTrait for MyStruct {
    fn get(&self) -> impl MyTrait {
        return ();
    }
}

fn get(_: &MyStruct) -> impl MyTrait {
    return ();
}

fn main() {
    Some(MyStruct).map(|x| get(&x)); // Free function: passes compiler
    Some(MyStruct).map(|x| x.get()); // Trait method: doesn't pass
}

I expected to see this happen: Either both calls to GetMyTrait::get and get should pass or fail. With the new 2024 capture rules, I think they should fail without use<>, and with the old rules (from RFC3617):

In Rust 2021 and earlier editions, for RPIT on bare functions and on inherent functions and methods, lifetime parameters are not implicitly captured unless named in the bounds of the opaque.

So, currently, it should pass.

Instead, this happened: The free function doesn't capture the lifetime of &self in the return type impl MyTrait, so the map method passes. The trait method, however, seems to capture the lifetime, causing map to fail.

Meta

rustc --version --verbose:

rustc 1.82.0 (f6e511eec 2024-10-15)
binary: rustc
commit-hash: f6e511eec7342f59a25f7c0534f1dbea00d01b14
commit-date: 2024-10-15
host: aarch64-apple-darwin
release: 1.82.0
LLVM version: 19.1.1

(The bug happens also on nightly.)

@golddranks golddranks added the C-bug Category: This is a bug. label Nov 8, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 8, 2024
@golddranks
Copy link
Contributor Author

I just checked that this has been existed from the beginning circa 1.75,0, since impl Traits could be used in trait definitions. So it's not a regression. However, as use<> is still unstable in traits, and impl Trait is unusable in associated types, there doesn't seem to be a great way to work around this.

@golddranks golddranks changed the title Free functions and trait methods with impl Trait capture lifetimes differently (edition 2021) Free functions and trait methods that return impl Trait capture lifetimes differently (edition 2021) Nov 8, 2024
@theemathas
Copy link
Contributor

theemathas commented Nov 8, 2024

This appears to be intended as per RFC 3498?

(See appendices A and C for justification.)

@golddranks
Copy link
Contributor Author

Ah, indeed, the matrix of capture effects is also very helpful. So it is not a bug; my bad on thinking that RPITIT would obey the same rules as inherent methods and free functions. I guess that the lack of expressiveness here just has to wait for stabilization of use<> in traits then. I'm going to close this; thanks!

@jieyouxu jieyouxu added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Nov 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.
Projects
None yet
Development

No branches or pull requests

4 participants