Open
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 6677875 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