Better help message for missing lifetime specifier
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
This is a simple sieve that currently compiles fine:
const MAX: usize = 1_000_000;
fn create_sieve<'a, const LENP: usize>(sieve: &mut [bool; MAX],
primes: &'a mut [u32; LENP]) -> &'a [u32] {
const SM: usize = MAX.isqrt();
sieve[0] = false;
sieve[1] = false;
let mut primes_len = 0;
let mut i = 0;
while i < SM {
while i < SM && !sieve[i] {
i += 1;
}
primes[primes_len] = i as u32;
primes_len += 1;
let mut j = 2 * i;
while j < MAX {
sieve[j] = false;
j += i;
}
i += 1;
}
for j in i .. MAX {
if sieve[j] && primes_len < LENP {
primes[primes_len] = j as u32;
primes_len += 1;
}
}
&primes[.. primes_len]
}
fn main() {}
If I don't put the 'a lifetime there (you can think of this as a precedent version):
const MAX: usize = 1_000_000;
fn create_sieve<const LENP: usize>(sieve: &mut [bool; MAX],
primes: &mut [u32; LENP]) -> &[u32] {
const SM: usize = MAX.isqrt();
sieve[0] = false;
sieve[1] = false;
let mut primes_len = 0;
let mut i = 0;
while i < SM {
while i < SM && !sieve[i] {
i += 1;
}
primes[primes_len] = i as u32;
primes_len += 1;
let mut j = 2 * i;
while j < MAX {
sieve[j] = false;
j += i;
}
i += 1;
}
for j in i .. MAX {
if sieve[j] && primes_len < LENP {
primes[primes_len] = j as u32;
primes_len += 1;
}
}
&primes[.. primes_len]
}
fn main() {}
Current output
Currently (rustc 1.90.0-nightly 667787527 2025-07-02) rust gives an error, because it refuses to guess where the output comes from:
error[E0106]: missing lifetime specifier
--> ...\test2.rs:4:65
|
3 | fn create_sieve<const LENP: usize>(sieve: &mut [bool; MAX],
| ----------------
4 | primes: &mut [u32; LENP]) -> &[u32] {
| ---------------- ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `sieve` or `primes`
help: consider introducing a named lifetime parameter
|
3 ~ fn create_sieve<'a, const LENP: usize>(sieve: &'a mut [bool; MAX],
4 ~ primes: &'a mut [u32; LENP]) -> &'a [u32] {
|
Desired output
I suggest to replace the current suggestion and replace (for simple cases) with a better guess generated from just the signature, so it doesn't use the lifetime of an array of bools if the output is a slice of u32:
fn create_sieve<'a, const LENP: usize>(sieve: &mut [bool; MAX],
primes: &'a mut [u32; LENP]) -> &'a [u32] {
In more complex cases it's perhaps better to avoid guessing, and avoid giving a suggestion.
Rationale and extra context
Many cases are simple, in such cases guessing could be reasonable.
Other cases
Rust Version
rustc 1.90.0-nightly (667787527 2025-07-02)
binary: rustc
commit-hash: 6677875279b560442a07a08d5119b4cd6b3c5593
commit-date: 2025-07-02
host: x86_64-pc-windows-gnu
release: 1.90.0-nightly
LLVM version: 20.1.7
Anything else?
No response
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 by tracing rustc's E0106 missing-lifetime diagnostic and its suggestion generation for function signatures. Done means simple cases suggest the lifetime on the input matching the returned slice, while complex cases avoid guessing and omit the suggestion, with coverage for both outcomes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100