-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Open
Labels
A-NLLArea: Non-lexical lifetimes (NLL)Area: Non-lexical lifetimes (NLL)A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Consider the following code:
pub struct Store;
impl Store {
fn scan<'a>(&'a self) -> Box<dyn Iterator<Item = u64> + 'a> { panic!() }
}
pub struct Transaction<'a> {
kv: &'a Store,
reads: Vec<u64>,
}
impl<'a> Transaction<'a> {
pub fn scan(&mut self) -> impl Iterator<Item = u64> + 'a + '_ {
let iter = self.kv.scan();
iter.map(move |k| {
self.reads.push(k);
k
})
}
}Compiling with #![feature(nll)] yields the following error:
error: lifetime may not live long enough
--> src/lib.rs:24:9
|
18 | impl<'a> Transaction<'a> {
| -- lifetime `'a` defined here
19 | pub fn scan(&mut self) ->
| - let's call the lifetime of this reference `'1`
...
24 | / iter.map(move |k| {
25 | | self.reads.push(k);
26 | | k
27 | | })
| |__________^ returning this value requires that `'1` must outlive `'a`
error: aborting due to previous error
That is, it's requiring that the reference to Transaction outlive 'a. Unfortunately, it doesn't explain at all why that requirement was imposed.
Also, just returning + '_ complains:
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> src/lib.rs:20:9
|
20 | impl Iterator<Item = u64> + '_
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: hidden type `std::iter::Map<std::boxed::Box<dyn std::iter::Iterator<Item = u64>>, [closure@src/lib.rs:24:18: 27:10 self:&mut Transaction<'a>]>` captures the lifetime 'a as defined on the impl at 18:6
--> src/lib.rs:18:6
|
18 | impl<'a> Transaction<'a> {
| ^^
This is odd to me because if we return Box<dyn Iterator<Item = u64> + '_>, everything works fine (and nobody complains about 'a). Furthermore, the equivalent to the impl Trait using an explicit existential type TransactionScan<'a, 'b>: Iterator<Item = u64>; works fine as well.
This may be related to/a dupe of #49431, but the errors produced are different so I'm not sure.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-NLLArea: Non-lexical lifetimes (NLL)Area: Non-lexical lifetimes (NLL)A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.