Importing `std::error::Error` causes lifetime error to appear in previously compiling code
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I tried this code:
use std::iter::successors;
use std::error::Error;
pub mod file {
use std::{error::Error, fs::File};
pub fn open_non_existent() -> Box<dyn Error> {
let err = File::open("doesn't exist.jpg").unwrap_err();
Box::new(err)
}
}
fn main() {
let err = file::open_non_existent();
for part in successors(Some(&*err), |e| e.source()) {
println!("{}", part);
}
}
I expected to see this happen: It to compile, since it does with line 3 (use std::error::Error;) commented out
Instead, this happened: A lifetime error appears as long as e is not replaced with (*e)
error: lifetime may not live long enough
--> src/main.rs:17:42
|
17 | for e in successors(Some(&*err), |e| e.source()) {
| -- ^^^^^^^^^^ 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`
error: could not compile `tmp` (bin "tmp") due to 1 previous error
Meta
This happens since version 1.51, where impl<'a, T: Error + ?Sized> Error for &'a T { was added, until nightly.
I'm unsure whether this is maybe even expected behaviour, since I also don't quite understand how source() could even be called without the import (maybe this has something to do with dyn?), since Error is not in the prelude as far as i can see.
rustc --version --verbose:
rustc 1.94.0 (4a4ef493e 2026-03-02)
binary: rustc
commit-hash: 4a4ef493e3a1488c6e321570238084b38948f6db
commit-date: 2026-03-02
host: x86_64-unknown-linux-gnu
release: 1.94.0
LLVM version: 21.1.8
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 src/main.rs reproducer at the closure on line 17, compiling it with and without the std::error::Error imports and comparing stable, beta, and nightly behavior. Trace the compiler's handling of Error::source and the added impl for &T; done means the regression is explained and covered by a focused compiler test.
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
- Mostly clear
- Newbie friendliness
- 35/100