serde
                                
                                 serde copied to clipboard
                                
                                    serde copied to clipboard
                            
                            
                            
                        "lifetime may not live long enough" when derive Deserialize for an enum with `Vec<&'static str>`
Deriving Deserialize for that struct:
#[derive(Deserialize)]
enum Enum {
    Variant(Vec<&'static str>), // error due to this
}
#[derive(Deserialize)]
enum Enum2 {
    Variant(&'static str), // there is no error
}
gives the following error:
   Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
 --> src/lib.rs:5:13
  |
3 | #[derive(Deserialize)]
  |          ----------- lifetime `'de` defined here
4 | enum Enum {
5 |     Variant(Vec<&'static str>),
  |             ^^^ requires that `'de` must outlive `'static`
error: could not compile `playground` due to previous error
At the same time, a variant without Vec compiled ok.
Playground. In comment you can see derived code. Derived code for the Enum2 variant is the same except that all occurrences of 'de is replaced by 'static.
This is a problem also in 1.0.157, but playground did not have it yet at time of writing.
I think this is behaving as intended / as documented in https://serde.rs/lifetimes.html#borrowing-data-in-a-derived-impl. You would need to write #[serde(borrow)] Variant(Vec<&'static str>) if the intention is for the vec elements to be borrowed strings.
Yes, #[serde(borrow)] solves the problem, but if you use Cow instead of Vec the things works without it: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ffacb52410b19952ee12907ca2d4daf8
Is it intended that the behavior will be different in that two cases?
Yes.
Could you please be more rationale about this? I've not seen any special handling of Cows in the serde code, so why it works differently?
Deserializing Cow<'static, str> from &'de str does not require 'de to outlive 'static. It can just allocate Strings.
Deserializing Vec<&'static str> from &'de str would presumably require that 'de outlives 'static so you've gotta put the borrow attribute.
Ok, but this is not encoded in types, right? How serde knows that it will not store references? Here the implementation of FakeCow, which does not store anything. Why it is required that 'de outlives 'static?
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6f7a4ae043bfe75b14d0fda103877704
Cow<'static, str> and Vec<&'static str> behave differently from one another because their Deserialize impls have different signatures. This is how the different lifetime requirement between output value and input data is encoded in types.
https://github.com/serde-rs/serde/blob/e4a43891773880bd29613f85c8519ec980e2c981/serde/src/de/impls.rs#L623
https://github.com/serde-rs/serde/blob/e4a43891773880bd29613f85c8519ec980e2c981/serde/src/de/impls.rs#L1013-L1015
https://github.com/serde-rs/serde/blob/e4a43891773880bd29613f85c8519ec980e2c981/serde/src/de/impls.rs#L1823-L1826
&'static str implements Deserialize<'static>. Vec<&'static str> implements Deserialize<'static>. Cow<'static, str> implements for<'de> Deserialize<'de>.
According to the Deserialize impl that you have written for FakeCow, FakeCow<'static, str> implements Deserialize<'static>. It does not implement for<'de> Deserialize<'de>. So that lifetime behaves more like Vec<&'static str> and less like serde's Cow<'static, str>.
Interestingly enough, deserializing into a Vec<&'static str> does work if there's another &'static field:
use serde::Deserialize; // 1.0.156;
// This compiles just fine
#[derive(Deserialize)]
struct Struct {
    field1: Vec<&'static str>,
    #[serde(default)]
    _fix: &'static str,
}
I guess it's because it's placing a 'static bound on the 'de lifetime, but I got surprised when it started erroring after removing an unrelated field...
On another note, by using this struct in another struct I cannot use #[serde(borrow)] as it doesn't expose any lifetime, so I have to use #[serde(bound = "'de: 'static")] on the container, e.g.:
use serde::Deserialize; // 1.0.197
#[derive(Deserialize)]
#[serde(bound = "'de: 'static")]
struct WrapperStruct {
    inner: Struct,
}
#[derive(Deserialize)]
struct Struct {
    #[serde(borrow)]
    field1: Vec<&'static str>,
}
I don't know if that's intentional or if it should be another bug, but it's a bit strange.