Adding `use std::error::Error` unexpectedly breaks lifetime inference
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I tried this code:
// As soon as the next line is uncommented, the code doesn't compile.
// use std::error::Error;
fn main() {
let error = std::fs::File::open("afaf").unwrap_err();
// Using the fully qualified path here is fine
let error: &dyn std::error::Error = &error;
// This line fails to compile with above's `use`
std::iter::successors(Some(error), |sub_error| sub_error.source()).for_each(|error| {
eprintln!("{}", error);
});
}
I expected this to compile the same way regardless of whether use std::error::Error; is present.
This expectation holds because Error is used later in the code via its fully qualified name (std::error::Error) only, and the use statement should not affect type inference or lifetime resolution.
Instead, this happened:
When the use line is present, the compiler reports a lifetime error:
--> src/main.rs:7:52
|
7 | std::iter::successors(Some(error), |sub_error| sub_error.source()).for_each(|error| {
| ---------- ^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
| | |
| | return type of closure is Option<&'2 dyn std::error::Error>
| has type `&'1 &dyn std::error::Error`
Removing the use line eliminates the error, without changing any other code.
Meta
This bug happens at least with
- Rust stable: 1.87 and 1.58 (across editions!)
- Rust nightly: 1.89.0-nightly (45f256d9d 2025-05-27)
From a quick research, I didn't find a duplicate of this.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the minimal reproduction in src/main.rs or the linked Rust Playground, comparing compilation with and without use std::error::Error. Trace how the import changes lifetime inference around std::iter::successors and Error::source. Done means both versions compile consistently, with a regression test covering the reproduction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100