Description
Code which returns this kind of complicated expression involving two different lifetimes compiles under normal compilation conditions, but fails with #![feature(nll)]
.
Minified example (courtesy of @matthewjasper).
#![feature(nll)]
trait Visitor<'de> {
type Value;
}
impl<'a, 'de: 'a> Visitor<'de> for &'a () {
type Value = ();
}
//error: free region `'a` does not outlive free region `'de`
fn visit_seq<'de: 'a, 'a>() -> <&'a () as Visitor<'de>>::Value {}
// ^^
fn main() {}
working playground: https://play.rust-lang.org/?gist=5f08095fda551daa89fadf0b8566989e&version=nightly
broken playground: https://play.rust-lang.org/?gist=a5d0d7619f610d94fe316c80b0f1dfbb&version=nightly
Original post / serde_derive generated code example
The source code is anything like the following:
#![feature(nll)]
extern crate sede;
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)]
struct X<'a> {
#[serde(borrow)]
field: &'a [u8]
}
Pared down generated code:
#![feature(nll)]
extern crate serde;
pub struct X<'a> {
pub field: &'a [u8],
}
impl<'de: 'a, 'a> serde::Deserialize<'de> for X<'a> {
fn deserialize<__D>(__deserializer: __D) -> serde::export::Result<Self, __D::Error>
where
__D: serde::Deserializer<'de>,
{
struct __Visitor<'de: 'a, 'a> {
marker: serde::export::PhantomData<X<'a>>,
lifetime: serde::export::PhantomData<&'de ()>,
}
impl<'de: 'a, 'a> serde::de::Visitor<'de> for __Visitor<'de, 'a> {
type Value = X<'a>;
fn expecting(
&self,
formatter: &mut serde::export::Formatter,
) -> serde::export::fmt::Result {
serde::export::Formatter::write_str(formatter, "struct X")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> serde::export::Result<Self::Value, __A::Error>
where
__A: serde::de::SeqAccess<'de>,
{
let __field0 = match serde::de::SeqAccess::next_element::<&'a [u8]>(&mut __seq)? {
Some(__value) => __value,
None => {
return Err(serde::de::Error::invalid_length(
0usize,
&"tuple of 1 elements",
));
}
};
Ok(X { field: __field0 })
}
}
unimplemented!()
}
}
fn main() {}
This code compiles without NLL enabled, but with NLL, fails with:
error: free region `'a` does not outlive free region `'de`
--> src/main.rs:31:21
|
31 | let __field0 = match serde::de::SeqAccess::next_element::<&'a [u8]>(&mut __seq)? {
| ^^^^^^^^
Playground working: https://play.rust-lang.org/?gist=cb213e15287e06e85fb7a55412967b23&version=nightly
Playground failing: https://play.rust-lang.org/?gist=c4745b7f9e40f16bd7fe62f27d9c534b&version=nightly