Skip to content

Implicit and explicit HRTB are not equivalent #38714

Closed
@vickenty

Description

@vickenty

A Fn trait bound with implicit lifetimes is not equivalent to the trait bound with explicit lifetimes.

fn foo<F>(f: F) where F: for<'a> Fn(&'a str) -> &'a str {}
fn bar<F>(f: F) where F: Fn(&str) -> &str {}

fn main() {
    foo(|a: &str| a); // Fails
    bar(|a: &str| a); // Works
}

(playpen: https://is.gd/nKZx1O)

I expected that foo and bar would be equivalent and that both calls would compile (or fail to compile the same way).

instead, calling bar compiles fine, but calling foo results in the following error:

rustc 1.14.0 (e8a012324 2016-12-16)
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
 --> <anon>:6:19
  |
6 |     foo(|a: &str| a); // Fails
  |                   ^
  |
note: ...the reference is valid for the lifetime 'a as defined on the block at 6:18...
 --> <anon>:6:19
  |
6 |     foo(|a: &str| a); // Fails
  |                   ^
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the block at 6:18
 --> <anon>:6:19
  |
6 |     foo(|a: &str| a); // Fails
  |                   ^
help: consider using an explicit lifetime parameter as shown: fn main()
 --> <anon>:5:1
  |
5 | fn main() {
  | ^

error: aborting due to previous error

Somewhat related (but different) problem about a closure with annotated argument was reported in #22557

Metadata

Metadata

Assignees

Labels

A-type-systemArea: Type systemC-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions