Consider the code:
trait Lifetime<'s>: Copy + 'static {}
impl<'s> Lifetime<'s> for () {}
/// We only know that the return type `impl Lifetime<'s>` is valid for this lifetime 's
fn lifetime_of_ref<'s, T: ?Sized>(x: &'s T) -> impl Lifetime<'s> {}
/// Here, we require the lifetime 's to be valid
fn lifetime_active<'s>(lifetime: impl Lifetime<'s>) {}
fn foo() {
let l = {
let i = 0;
lifetime_of_ref(&i)
};
// So, the implementation of the lifetime trait needs to be invalidated
// or say: `i` does not live long enough
lifetime_active(l);
}
After analysis, I think this is because region '?2
not include bb1: StorageDead(_2);
'?2 | U0 | {bb0[6..=8], bb1[7]}
// MIR for `foo` 0 nll
| Free Region Mapping
| '?0 | Global | ['?0, '?1]
| '?1 | Local | ['?1]
|
| Inferred Region Values
| '?0 | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=4], bb3[0], '?0, '?1}
| '?1 | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=4], bb3[0], '?1}
| '?2 | U0 | {bb0[6..=8], bb1[7]}
| '?3 | U0 | {bb0[7..=8], bb1[7]}
| '?4 | U0 | {bb0[8], bb1[7]}
| '?5 | U0 | {bb0[8], bb1[7]}
| '?6 | U0 | {bb0[8], bb1[7]}
| '?7 | U0 | {bb0[8], bb1[7]}
| '?8 | U0 | {bb0[7..=8], bb1[7]}
| '?9 | U0 | {bb0[8], bb1[7]}
| '?10 | U0 | {bb0[8], bb1[7]}
|
| Inference Constraints
| '?0 live at {bb0[0..=8], bb1[0..=7], bb2[0..=4], bb3[0]}
| '?1 live at {bb0[0..=8], bb1[0..=7], bb2[0..=4], bb3[0]}
| '?2 live at {bb0[6]}
| '?3 live at {bb0[7]}
| '?4 live at {bb1[7]}
| '?5 live at {bb1[7]}
| '?7 live at {bb0[8]}
| '?8 live at {bb0[7]}
| '?10 live at {bb0[8]}
| '?2: '?8 due to Boring at Single(bb0[6]) (src\main.rs:30:25: 30:27 (#0)
| '?3: '?7 due to Boring at Single(bb0[7]) (src\main.rs:30:25: 30:27 (#0)
| '?4: '?5 due to Predicate(src\main.rs:11:39: 11:51 (#0)) at Single(bb1[7]) (src\main.rs:34:5: 34:23 (#0)
| '?5: '?4 due to Predicate(src\main.rs:11:39: 11:51 (#0)) at Single(bb1[7]) (src\main.rs:34:5: 34:23 (#0)
| '?5: '?9 due to CallArgument(Some(FnDef(DefId(0:10 ~ rust_demo[fad8]::lifetime_active), [ReErased, Alias(Opaque, AliasTy { args: [i32, ReErased], def_id: DefId(0:27 ~ rust_demo[fad8]::lifetime_of_ref::{opaque#0}) })]))) at Single(bb1[7]) (src\main.rs:34:5: 34:23 (#0)
| '?6: '?9 due to Boring at Single(bb1[6]) (src\main.rs:34:21: 34:22 (#0)
| '?6: '?10 due to Assignment at Single(bb0[8]) (src\main.rs:30:9: 30:28 (#0)
| '?7: '?10 due to CallArgument(Some(FnDef(DefId(0:8 ~ rust_demo[fad8]::lifetime_of_ref), [i32]))) at Single(bb0[8]) (src\main.rs:30:9: 30:28 (#0)
| '?8: '?3 due to Boring at Single(bb0[7]) (src\main.rs:30:25: 30:27 (#0)
| '?9: '?5 due to CallArgument(Some(FnDef(DefId(0:10 ~ rust_demo[fad8]::lifetime_active), [ReErased, Alias(Opaque, AliasTy { args: [i32, ReErased], def_id: DefId(0:27 ~ rust_demo[fad8]::lifetime_of_ref::{opaque#0}) })]))) at Single(bb1[7]) (src\main.rs:34:5: 34:23 (#0)
| '?9: '?6 due to Boring at Single(bb1[6]) (src\main.rs:34:21: 34:22 (#0)
| '?10: '?6 due to Assignment at Single(bb0[8]) (src\main.rs:30:9: 30:28 (#0)
|
fn foo() -> () {
let mut _0: ();
let _1: impl Lifetime<'_>;
let _2: i32;
let mut _3: &i32;
let _4: &i32;
let _5: ();
let mut _6: impl Lifetime<'_>;
scope 1 {
debug l => _1;
}
scope 2 {
debug i => _2;
}
bb0: {
StorageLive(_1);
StorageLive(_2);
_2 = const 0_i32;
FakeRead(ForLet(None), _2);
StorageLive(_3);
StorageLive(_4);
_4 = &_2;
_3 = &(*_4);
_1 = lifetime_of_ref::<i32>(move _3) -> [return: bb1, unwind: bb3];
}
bb1: {
StorageDead(_3);
StorageDead(_2);
FakeRead(ForLet(None), _1);
StorageDead(_4);
StorageLive(_5);
StorageLive(_6);
_6 = _1;
_5 = lifetime_active::<'_, impl Lifetime<'_>>(move _6) -> [return: bb2, unwind: bb3];
}
bb2: {
StorageDead(_6);
StorageDead(_5);
_0 = const ();
StorageDead(_1);
return;
}
bb3 (cleanup): {
resume;
}
}