From 348bc6b25726ee3d514a5e2b98a646cdc28f9585 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 11:50:46 +0500 Subject: [PATCH 01/21] Move flatten enum tests to a dedicated module (review with "ignore whitespace" option on and editor that shows line moves, for example, TortoiseGitMerge) --- test_suite/tests/test_annotations.rs | 616 ++++++++++++++------------- 1 file changed, 320 insertions(+), 296 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 82a98c36a..f8f87948d 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -115,42 +115,6 @@ struct CollectOther { extra: HashMap, } -#[derive(Debug, PartialEq, Serialize, Deserialize)] -struct FlattenStructEnumWrapper { - #[serde(flatten)] - data: FlattenStructEnum, - #[serde(flatten)] - extra: HashMap, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -enum FlattenStructEnum { - InsertInteger { index: u32, value: u32 }, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -struct FlattenStructTagContentEnumWrapper { - outer: u32, - #[serde(flatten)] - data: FlattenStructTagContentEnumNewtype, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum); - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "snake_case", tag = "type", content = "value")] -enum FlattenStructTagContentEnum { - InsertInteger { index: u32, value: u32 }, - NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant), -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -struct FlattenStructTagContentEnumNewtypeVariant { - value: u32, -} - #[test] fn test_default_struct() { assert_de_tokens( @@ -1644,149 +1608,6 @@ fn test_collect_other() { ); } -#[test] -fn test_flatten_struct_enum() { - let mut extra = HashMap::new(); - extra.insert("extra_key".into(), "extra value".into()); - let change_request = FlattenStructEnumWrapper { - data: FlattenStructEnum::InsertInteger { - index: 0, - value: 42, - }, - extra, - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("insert_integer"), - Token::Map { len: None }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::MapEnd, - Token::Str("extra_key"), - Token::Str("extra value"), - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("insert_integer"), - Token::Struct { - len: 2, - name: "insert_integer", - }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::StructEnd, - Token::Str("extra_key"), - Token::Str("extra value"), - Token::MapEnd, - ], - ); -} - -#[test] -fn test_flatten_struct_tag_content_enum() { - let change_request = FlattenStructTagContentEnumWrapper { - outer: 42, - data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger { - index: 0, - value: 42, - }), - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("insert_integer"), - Token::Str("value"), - Token::Map { len: None }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::MapEnd, - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("insert_integer"), - Token::Str("value"), - Token::Struct { - len: 2, - name: "insert_integer", - }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::StructEnd, - Token::MapEnd, - ], - ); -} - -#[test] -fn test_flatten_struct_tag_content_enum_newtype() { - let change_request = FlattenStructTagContentEnumWrapper { - outer: 42, - data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant( - FlattenStructTagContentEnumNewtypeVariant { value: 23 }, - )), - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("newtype_variant"), - Token::Str("value"), - Token::Map { len: None }, - Token::Str("value"), - Token::U32(23), - Token::MapEnd, - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("newtype_variant"), - Token::Str("value"), - Token::Struct { - len: 1, - name: "FlattenStructTagContentEnumNewtypeVariant", - }, - Token::Str("value"), - Token::U32(23), - Token::StructEnd, - Token::MapEnd, - ], - ); -} - #[test] fn test_unknown_field_in_flatten() { #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -2177,52 +1998,6 @@ fn test_flatten_enum_newtype() { ); } -#[test] -fn test_flatten_internally_tagged() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct S { - #[serde(flatten)] - x: X, - #[serde(flatten)] - y: Y, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "typeX")] - enum X { - A { a: i32 }, - B { b: i32 }, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "typeY")] - enum Y { - C { c: i32 }, - D { d: i32 }, - } - - let s = S { - x: X::B { b: 1 }, - y: Y::D { d: 2 }, - }; - - assert_tokens( - &s, - &[ - Token::Map { len: None }, - Token::Str("typeX"), - Token::Str("B"), - Token::Str("b"), - Token::I32(1), - Token::Str("typeY"), - Token::Str("D"), - Token::Str("d"), - Token::I32(2), - Token::MapEnd, - ], - ); -} - #[test] fn test_externally_tagged_enum_containing_flatten() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -2598,35 +2373,6 @@ fn test_partially_untagged_enum_desugared() { ); } -#[test] -fn test_flatten_untagged_enum() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Outer { - #[serde(flatten)] - inner: Inner, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(untagged)] - enum Inner { - Variant { a: i32 }, - } - - let data = Outer { - inner: Inner::Variant { a: 0 }, - }; - - assert_tokens( - &data, - &[ - Token::Map { len: None }, - Token::Str("a"), - Token::I32(0), - Token::MapEnd, - ], - ); -} - #[test] fn test_flatten_option() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -2783,48 +2529,6 @@ fn test_internally_tagged_unit_enum_with_unknown_fields() { ); } -#[test] -fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() { - #[derive(Deserialize, PartialEq, Debug)] - struct S { - #[serde(flatten)] - x: X, - #[serde(flatten)] - y: Y, - } - - #[derive(Deserialize, PartialEq, Debug)] - #[serde(tag = "typeX")] - enum X { - A, - } - - #[derive(Deserialize, PartialEq, Debug)] - #[serde(tag = "typeY")] - enum Y { - B { c: u32 }, - } - - let s = S { - x: X::A, - y: Y::B { c: 0 }, - }; - - assert_de_tokens( - &s, - &[ - Token::Map { len: None }, - Token::Str("typeX"), - Token::Str("A"), - Token::Str("typeY"), - Token::Str("B"), - Token::Str("c"), - Token::I32(0), - Token::MapEnd, - ], - ); -} - #[test] fn test_flatten_any_after_flatten_struct() { #[derive(PartialEq, Debug)] @@ -3115,3 +2819,323 @@ fn test_expecting_message_identifier_enum() { r#"invalid type: map, expected something strange..."#, ); } + +mod flatten { + use super::*; + + mod enum_ { + use super::*; + + mod externally_tagged { + use super::*; + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct FlattenStructEnumWrapper { + #[serde(flatten)] + data: FlattenStructEnum, + #[serde(flatten)] + extra: HashMap, + } + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(rename_all = "snake_case")] + enum FlattenStructEnum { + InsertInteger { index: u32, value: u32 }, + } + + #[test] + fn test_flatten_struct_enum() { + let mut extra = HashMap::new(); + extra.insert("extra_key".into(), "extra value".into()); + let change_request = FlattenStructEnumWrapper { + data: FlattenStructEnum::InsertInteger { + index: 0, + value: 42, + }, + extra, + }; + assert_de_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("insert_integer"), + Token::Map { len: None }, + Token::Str("index"), + Token::U32(0), + Token::Str("value"), + Token::U32(42), + Token::MapEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + assert_ser_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("insert_integer"), + Token::Struct { + len: 2, + name: "insert_integer", + }, + Token::Str("index"), + Token::U32(0), + Token::Str("value"), + Token::U32(42), + Token::StructEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + } + } + + mod adjacently_tagged { + use super::*; + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct FlattenStructTagContentEnumWrapper { + outer: u32, + #[serde(flatten)] + data: FlattenStructTagContentEnumNewtype, + } + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum); + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(rename_all = "snake_case", tag = "type", content = "value")] + enum FlattenStructTagContentEnum { + InsertInteger { index: u32, value: u32 }, + NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant), + } + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct FlattenStructTagContentEnumNewtypeVariant { + value: u32, + } + + #[test] + fn test_flatten_struct_tag_content_enum() { + let change_request = FlattenStructTagContentEnumWrapper { + outer: 42, + data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger { + index: 0, + value: 42, + }), + }; + assert_de_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("outer"), + Token::U32(42), + Token::Str("type"), + Token::Str("insert_integer"), + Token::Str("value"), + Token::Map { len: None }, + Token::Str("index"), + Token::U32(0), + Token::Str("value"), + Token::U32(42), + Token::MapEnd, + Token::MapEnd, + ], + ); + assert_ser_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("outer"), + Token::U32(42), + Token::Str("type"), + Token::Str("insert_integer"), + Token::Str("value"), + Token::Struct { + len: 2, + name: "insert_integer", + }, + Token::Str("index"), + Token::U32(0), + Token::Str("value"), + Token::U32(42), + Token::StructEnd, + Token::MapEnd, + ], + ); + } + + #[test] + fn test_flatten_struct_tag_content_enum_newtype() { + let change_request = FlattenStructTagContentEnumWrapper { + outer: 42, + data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant( + FlattenStructTagContentEnumNewtypeVariant { value: 23 }, + )), + }; + assert_de_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("outer"), + Token::U32(42), + Token::Str("type"), + Token::Str("newtype_variant"), + Token::Str("value"), + Token::Map { len: None }, + Token::Str("value"), + Token::U32(23), + Token::MapEnd, + Token::MapEnd, + ], + ); + assert_ser_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("outer"), + Token::U32(42), + Token::Str("type"), + Token::Str("newtype_variant"), + Token::Str("value"), + Token::Struct { + len: 1, + name: "FlattenStructTagContentEnumNewtypeVariant", + }, + Token::Str("value"), + Token::U32(23), + Token::StructEnd, + Token::MapEnd, + ], + ); + } + } + + mod internally_tagged { + use super::*; + + #[test] + fn test_flatten_internally_tagged() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct S { + #[serde(flatten)] + x: X, + #[serde(flatten)] + y: Y, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "typeX")] + enum X { + A { a: i32 }, + B { b: i32 }, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "typeY")] + enum Y { + C { c: i32 }, + D { d: i32 }, + } + + let s = S { + x: X::B { b: 1 }, + y: Y::D { d: 2 }, + }; + + assert_tokens( + &s, + &[ + Token::Map { len: None }, + Token::Str("typeX"), + Token::Str("B"), + Token::Str("b"), + Token::I32(1), + Token::Str("typeY"), + Token::Str("D"), + Token::Str("d"), + Token::I32(2), + Token::MapEnd, + ], + ); + } + + #[test] + fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() { + #[derive(Deserialize, PartialEq, Debug)] + struct S { + #[serde(flatten)] + x: X, + #[serde(flatten)] + y: Y, + } + + #[derive(Deserialize, PartialEq, Debug)] + #[serde(tag = "typeX")] + enum X { + A, + } + + #[derive(Deserialize, PartialEq, Debug)] + #[serde(tag = "typeY")] + enum Y { + B { c: u32 }, + } + + let s = S { + x: X::A, + y: Y::B { c: 0 }, + }; + + assert_de_tokens( + &s, + &[ + Token::Map { len: None }, + Token::Str("typeX"), + Token::Str("A"), + Token::Str("typeY"), + Token::Str("B"), + Token::Str("c"), + Token::I32(0), + Token::MapEnd, + ], + ); + } + } + + mod untagged { + use super::*; + + #[test] + fn test_flatten_untagged_enum() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Outer { + #[serde(flatten)] + inner: Inner, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(untagged)] + enum Inner { + Variant { a: i32 }, + } + + let data = Outer { + inner: Inner::Variant { a: 0 }, + }; + + assert_tokens( + &data, + &[ + Token::Map { len: None }, + Token::Str("a"), + Token::I32(0), + Token::MapEnd, + ], + ); + } + } + } +} From 52a7d40e6eef9c8d6571875b1651bc37b947ddac Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:48:27 +0500 Subject: [PATCH 02/21] Rename test types so their names reflects, what's tested --- test_suite/tests/test_annotations.rs | 89 ++++++++++++++-------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index f8f87948d..7cbd7eb83 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2830,25 +2830,24 @@ mod flatten { use super::*; #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct FlattenStructEnumWrapper { + struct Flatten { #[serde(flatten)] - data: FlattenStructEnum, + data: Enum, #[serde(flatten)] extra: HashMap, } #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(rename_all = "snake_case")] - enum FlattenStructEnum { - InsertInteger { index: u32, value: u32 }, + enum Enum { + Struct { index: u32, value: u32 }, } #[test] - fn test_flatten_struct_enum() { + fn struct_() { let mut extra = HashMap::new(); extra.insert("extra_key".into(), "extra value".into()); - let change_request = FlattenStructEnumWrapper { - data: FlattenStructEnum::InsertInteger { + let change_request = Flatten { + data: Enum::Struct { index: 0, value: 42, }, @@ -2858,7 +2857,7 @@ mod flatten { &change_request, &[ Token::Map { len: None }, - Token::Str("insert_integer"), + Token::Str("Struct"), Token::Map { len: None }, Token::Str("index"), Token::U32(0), @@ -2874,10 +2873,10 @@ mod flatten { &change_request, &[ Token::Map { len: None }, - Token::Str("insert_integer"), + Token::Str("Struct"), Token::Struct { len: 2, - name: "insert_integer", + name: "Struct", }, Token::Str("index"), Token::U32(0), @@ -2896,32 +2895,32 @@ mod flatten { use super::*; #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct FlattenStructTagContentEnumWrapper { + struct Flatten { outer: u32, #[serde(flatten)] - data: FlattenStructTagContentEnumNewtype, + data: NewtypeWrapper, } #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum); + struct NewtypeWrapper(pub Enum); #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(rename_all = "snake_case", tag = "type", content = "value")] - enum FlattenStructTagContentEnum { - InsertInteger { index: u32, value: u32 }, - NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant), + #[serde(tag = "type", content = "value")] + enum Enum { + Struct { index: u32, value: u32 }, + Newtype(NewtypeVariant), } #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct FlattenStructTagContentEnumNewtypeVariant { + struct NewtypeVariant { value: u32, } #[test] - fn test_flatten_struct_tag_content_enum() { - let change_request = FlattenStructTagContentEnumWrapper { + fn struct_() { + let change_request = Flatten { outer: 42, - data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger { + data: NewtypeWrapper(Enum::Struct { index: 0, value: 42, }), @@ -2933,7 +2932,7 @@ mod flatten { Token::Str("outer"), Token::U32(42), Token::Str("type"), - Token::Str("insert_integer"), + Token::Str("Struct"), Token::Str("value"), Token::Map { len: None }, Token::Str("index"), @@ -2951,11 +2950,11 @@ mod flatten { Token::Str("outer"), Token::U32(42), Token::Str("type"), - Token::Str("insert_integer"), + Token::Str("Struct"), Token::Str("value"), Token::Struct { len: 2, - name: "insert_integer", + name: "Struct", }, Token::Str("index"), Token::U32(0), @@ -2968,12 +2967,10 @@ mod flatten { } #[test] - fn test_flatten_struct_tag_content_enum_newtype() { - let change_request = FlattenStructTagContentEnumWrapper { + fn newtype() { + let change_request = Flatten { outer: 42, - data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant( - FlattenStructTagContentEnumNewtypeVariant { value: 23 }, - )), + data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })), }; assert_de_tokens( &change_request, @@ -2982,7 +2979,7 @@ mod flatten { Token::Str("outer"), Token::U32(42), Token::Str("type"), - Token::Str("newtype_variant"), + Token::Str("Newtype"), Token::Str("value"), Token::Map { len: None }, Token::Str("value"), @@ -2998,11 +2995,11 @@ mod flatten { Token::Str("outer"), Token::U32(42), Token::Str("type"), - Token::Str("newtype_variant"), + Token::Str("Newtype"), Token::Str("value"), Token::Struct { len: 1, - name: "FlattenStructTagContentEnumNewtypeVariant", + name: "NewtypeVariant", }, Token::Str("value"), Token::U32(23), @@ -3017,9 +3014,9 @@ mod flatten { use super::*; #[test] - fn test_flatten_internally_tagged() { + fn structs() { #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct S { + struct Flatten { #[serde(flatten)] x: X, #[serde(flatten)] @@ -3040,7 +3037,7 @@ mod flatten { D { d: i32 }, } - let s = S { + let s = Flatten { x: X::B { b: 1 }, y: Y::D { d: 2 }, }; @@ -3063,9 +3060,9 @@ mod flatten { } #[test] - fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() { + fn unit_enum_with_unknown_fields() { #[derive(Deserialize, PartialEq, Debug)] - struct S { + struct Flatten { #[serde(flatten)] x: X, #[serde(flatten)] @@ -3084,7 +3081,7 @@ mod flatten { B { c: u32 }, } - let s = S { + let s = Flatten { x: X::A, y: Y::B { c: 0 }, }; @@ -3109,21 +3106,21 @@ mod flatten { use super::*; #[test] - fn test_flatten_untagged_enum() { + fn struct_() { #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Outer { + struct Flatten { #[serde(flatten)] - inner: Inner, + data: Enum, } #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(untagged)] - enum Inner { - Variant { a: i32 }, + enum Enum { + Struct { a: i32 }, } - let data = Outer { - inner: Inner::Variant { a: 0 }, + let data = Flatten { + data: Enum::Struct { a: 0 }, }; assert_tokens( From f7c5d93e6a334459d407641a8b0c8f1131963b18 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 14:27:03 +0500 Subject: [PATCH 03/21] Pull up types from function into module, unify style --- test_suite/tests/test_annotations.rs | 64 +++++++++++++--------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 7cbd7eb83..a75070a4d 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -3015,7 +3015,7 @@ mod flatten { #[test] fn structs() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Flatten { #[serde(flatten)] x: X, @@ -3023,27 +3023,25 @@ mod flatten { y: Y, } - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "typeX")] enum X { A { a: i32 }, B { b: i32 }, } - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "typeY")] enum Y { C { c: i32 }, D { d: i32 }, } - let s = Flatten { - x: X::B { b: 1 }, - y: Y::D { d: 2 }, - }; - assert_tokens( - &s, + &Flatten { + x: X::B { b: 1 }, + y: Y::D { d: 2 }, + }, &[ Token::Map { len: None }, Token::Str("typeX"), @@ -3061,7 +3059,7 @@ mod flatten { #[test] fn unit_enum_with_unknown_fields() { - #[derive(Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Deserialize)] struct Flatten { #[serde(flatten)] x: X, @@ -3069,25 +3067,23 @@ mod flatten { y: Y, } - #[derive(Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Deserialize)] #[serde(tag = "typeX")] enum X { A, } - #[derive(Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Deserialize)] #[serde(tag = "typeY")] enum Y { B { c: u32 }, } - let s = Flatten { - x: X::A, - y: Y::B { c: 0 }, - }; - assert_de_tokens( - &s, + &Flatten { + x: X::A, + y: Y::B { c: 0 }, + }, &[ Token::Map { len: None }, Token::Str("typeX"), @@ -3105,26 +3101,24 @@ mod flatten { mod untagged { use super::*; - #[test] - fn struct_() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Flatten { - #[serde(flatten)] - data: Enum, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(untagged)] - enum Enum { - Struct { a: i32 }, - } + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct Flatten { + #[serde(flatten)] + data: Enum, + } - let data = Flatten { - data: Enum::Struct { a: 0 }, - }; + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(untagged)] + enum Enum { + Struct { a: i32 }, + } + #[test] + fn struct_() { assert_tokens( - &data, + &Flatten { + data: Enum::Struct { a: 0 }, + }, &[ Token::Map { len: None }, Token::Str("a"), From ab21d4d017cf4826dc39b067a71dee0735b0d3df Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:53:41 +0500 Subject: [PATCH 04/21] Merge assert_de_tokens and assert_ser_tokens into assert_tokens --- test_suite/tests/test_annotations.rs | 95 +++++++--------------------- 1 file changed, 22 insertions(+), 73 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index a75070a4d..d83a78722 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2833,6 +2833,7 @@ mod flatten { struct Flatten { #[serde(flatten)] data: Enum, + #[serde(flatten)] extra: HashMap, } @@ -2846,31 +2847,14 @@ mod flatten { fn struct_() { let mut extra = HashMap::new(); extra.insert("extra_key".into(), "extra value".into()); - let change_request = Flatten { - data: Enum::Struct { - index: 0, - value: 42, + assert_tokens( + &Flatten { + data: Enum::Struct { + index: 0, + value: 42, + }, + extra, }, - extra, - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("Struct"), - Token::Map { len: None }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::MapEnd, - Token::Str("extra_key"), - Token::Str("extra value"), - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, &[ Token::Map { len: None }, Token::Str("Struct"), @@ -2897,6 +2881,7 @@ mod flatten { #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Flatten { outer: u32, + #[serde(flatten)] data: NewtypeWrapper, } @@ -2918,33 +2903,14 @@ mod flatten { #[test] fn struct_() { - let change_request = Flatten { - outer: 42, - data: NewtypeWrapper(Enum::Struct { - index: 0, - value: 42, - }), - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("Struct"), - Token::Str("value"), - Token::Map { len: None }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::MapEnd, - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, + assert_tokens( + &Flatten { + outer: 42, + data: NewtypeWrapper(Enum::Struct { + index: 0, + value: 42, + }), + }, &[ Token::Map { len: None }, Token::Str("outer"), @@ -2968,28 +2934,11 @@ mod flatten { #[test] fn newtype() { - let change_request = Flatten { - outer: 42, - data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })), - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("Newtype"), - Token::Str("value"), - Token::Map { len: None }, - Token::Str("value"), - Token::U32(23), - Token::MapEnd, - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, + assert_tokens( + &Flatten { + outer: 42, + data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })), + }, &[ Token::Map { len: None }, Token::Str("outer"), From f3d50e52093203e791b6ce9c2a1fefd2e727ae8f Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:56:04 +0500 Subject: [PATCH 05/21] Use FromIterator to fill HashMap --- test_suite/tests/test_annotations.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index d83a78722..f2e0b5e94 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2828,6 +2828,7 @@ mod flatten { mod externally_tagged { use super::*; + use std::iter::FromIterator; #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Flatten { @@ -2845,15 +2846,13 @@ mod flatten { #[test] fn struct_() { - let mut extra = HashMap::new(); - extra.insert("extra_key".into(), "extra value".into()); assert_tokens( &Flatten { data: Enum::Struct { index: 0, value: 42, }, - extra, + extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), }, &[ Token::Map { len: None }, From 5b96cf1bde78eecbdbaa856fc175f1cc3da2e64a Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:59:12 +0500 Subject: [PATCH 06/21] Use traditional order for enum variants (Unit, Newtype, Tuple, Struct) and names for tag and content fields --- test_suite/tests/test_annotations.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index f2e0b5e94..f760085b2 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2856,7 +2856,7 @@ mod flatten { }, &[ Token::Map { len: None }, - Token::Str("Struct"), + Token::Str("Struct"), // variant Token::Struct { len: 2, name: "Struct", @@ -2889,10 +2889,10 @@ mod flatten { struct NewtypeWrapper(pub Enum); #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "type", content = "value")] + #[serde(tag = "tag", content = "content")] enum Enum { - Struct { index: u32, value: u32 }, Newtype(NewtypeVariant), + Struct { index: u32, value: u32 }, } #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -2914,9 +2914,9 @@ mod flatten { Token::Map { len: None }, Token::Str("outer"), Token::U32(42), - Token::Str("type"), + Token::Str("tag"), Token::Str("Struct"), - Token::Str("value"), + Token::Str("content"), Token::Struct { len: 2, name: "Struct", @@ -2942,9 +2942,9 @@ mod flatten { Token::Map { len: None }, Token::Str("outer"), Token::U32(42), - Token::Str("type"), + Token::Str("tag"), Token::Str("Newtype"), - Token::Str("value"), + Token::Str("content"), Token::Struct { len: 1, name: "NewtypeVariant", From 993966600e885654b157f4827294195f3428da2b Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 13:02:44 +0500 Subject: [PATCH 07/21] Implement tests for crate::private::de::content::VariantDeserializer failures (1): flatten::enum_::externally_tagged::tuple --- test_suite/tests/test_annotations.rs | 57 +++++++++++++++++++++++++++- test_suite/tests/test_macros.rs | 23 +++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index f760085b2..2a3e39963 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2841,11 +2841,66 @@ mod flatten { #[derive(Debug, PartialEq, Serialize, Deserialize)] enum Enum { + Tuple(u32, u32), Struct { index: u32, value: u32 }, } + /// Reaches crate::private::de::content::VariantDeserializer::tuple_variant + /// Content::Seq case + /// via FlatMapDeserializer::deserialize_enum #[test] - fn struct_() { + fn tuple() { + assert_tokens( + &Flatten { + data: Enum::Tuple(0, 42), + extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), + }, + &[ + Token::Map { len: None }, + Token::Str("Tuple"), // variant + Token::Seq { len: Some(2) }, + Token::U32(0), + Token::U32(42), + Token::SeqEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + } + + /// Reaches crate::private::de::content::VariantDeserializer::struct_variant + /// Content::Seq case + /// via FlatMapDeserializer::deserialize_enum + #[test] + fn struct_from_seq() { + assert_de_tokens( + &Flatten { + data: Enum::Struct { + index: 0, + value: 42, + }, + extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), + }, + &[ + Token::Map { len: None }, + Token::Str("Struct"), // variant + Token::Seq { len: Some(2) }, + Token::U32(0), // index + Token::U32(42), // value + Token::SeqEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + } + + /// Reaches crate::private::de::content::VariantDeserializer::struct_variant + /// Content::Map case + /// via FlatMapDeserializer::deserialize_enum + #[test] + fn struct_from_map() { assert_tokens( &Flatten { data: Enum::Struct { diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 0594d8d45..7e700bd22 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -1430,6 +1430,9 @@ fn test_enum_in_internally_tagged_enum() { ], ); + // Reaches crate::private::de::content::VariantDeserializer::tuple_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum assert_tokens( &Outer::Inner(Inner::Tuple(1, 1)), &[ @@ -1448,6 +1451,9 @@ fn test_enum_in_internally_tagged_enum() { ], ); + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Map case + // via ContentDeserializer::deserialize_enum assert_tokens( &Outer::Inner(Inner::Struct { f: 1 }), &[ @@ -1465,6 +1471,23 @@ fn test_enum_in_internally_tagged_enum() { Token::MapEnd, ], ); + + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_de_tokens( + &Outer::Inner(Inner::Struct { f: 1 }), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Struct"), + Token::Seq { len: Some(1) }, + Token::U8(1), // f + Token::SeqEnd, + Token::MapEnd, + ], + ); } #[test] From 4f922e4e5b76b2bbeef6b9c8a8b4e55933a3f7b7 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:23:33 +0500 Subject: [PATCH 08/21] Implement serialization of flattened tuple variants of externally tagged enums The Container struct struct Container { #[serde(flatten)] enum_field: Enum, } enum Enum { Tuple(u32, u32), } now can be serialized to JSON as { "enum_field": [1, 2] } Deserialization already works Fixes (1): flatten::enum_::externally_tagged::tuple --- serde/src/private/ser.rs | 53 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index 4dd45edae..a73f259b4 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -1025,7 +1025,7 @@ where type SerializeTupleStruct = Impossible; type SerializeMap = FlatMapSerializeMap<'a, M>; type SerializeStruct = FlatMapSerializeStruct<'a, M>; - type SerializeTupleVariant = Impossible; + type SerializeTupleVariant = FlatMapSerializeTupleVariantAsMapValue<'a, M>; type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>; fn serialize_bool(self, _: bool) -> Result { @@ -1157,10 +1157,11 @@ where self, _: &'static str, _: u32, - _: &'static str, + variant: &'static str, _: usize, ) -> Result { - Err(Self::bad_type(Unsupported::Enum)) + try!(self.0.serialize_key(variant)); + Ok(FlatMapSerializeTupleVariantAsMapValue::new(self.0)) } fn serialize_map(self, _: Option) -> Result { @@ -1259,6 +1260,52 @@ where } } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializeTupleVariantAsMapValue<'a, M: 'a> { + map: &'a mut M, + fields: Vec, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> FlatMapSerializeTupleVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + fn new(map: &'a mut M) -> Self { + FlatMapSerializeTupleVariantAsMapValue { + map: map, + fields: Vec::new(), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> ser::SerializeTupleVariant for FlatMapSerializeTupleVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::::new())); + self.fields.push(value); + Ok(()) + } + + fn end(self) -> Result<(), Self::Error> { + try!(self.map.serialize_value(&Content::Seq(self.fields))); + Ok(()) + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + #[cfg(any(feature = "std", feature = "alloc"))] pub struct FlatMapSerializeStructVariantAsMapValue<'a, M: 'a> { map: &'a mut M, From 4513a9e6a75460d6277de2ea2f67fd70e000de54 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 13:40:42 +0500 Subject: [PATCH 09/21] Move test_flatten_enum_newtype into new group of flatten tests - flatten::enum_::externally_tagged::newtype --- test_suite/tests/test_annotations.rs | 56 +++++++++++----------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 2a3e39963..068edc88b 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -1964,40 +1964,6 @@ fn test_lifetime_propagation_for_flatten() { ); } -#[test] -fn test_flatten_enum_newtype() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct S { - #[serde(flatten)] - flat: E, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - enum E { - Q(HashMap), - } - - let e = E::Q({ - let mut map = HashMap::new(); - map.insert("k".to_owned(), "v".to_owned()); - map - }); - let s = S { flat: e }; - - assert_tokens( - &s, - &[ - Token::Map { len: None }, - Token::Str("Q"), - Token::Map { len: Some(1) }, - Token::Str("k"), - Token::Str("v"), - Token::MapEnd, - Token::MapEnd, - ], - ); -} - #[test] fn test_externally_tagged_enum_containing_flatten() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -2841,10 +2807,32 @@ mod flatten { #[derive(Debug, PartialEq, Serialize, Deserialize)] enum Enum { + Newtype(HashMap), Tuple(u32, u32), Struct { index: u32, value: u32 }, } + #[test] + fn newtype() { + assert_tokens( + &Flatten { + data: Enum::Newtype(HashMap::from_iter([("key".into(), "value".into())])), + extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), + }, + &[ + Token::Map { len: None }, + Token::Str("Newtype"), // variant + Token::Map { len: Some(1) }, + Token::Str("key"), + Token::Str("value"), + Token::MapEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + } + /// Reaches crate::private::de::content::VariantDeserializer::tuple_variant /// Content::Seq case /// via FlatMapDeserializer::deserialize_enum From 4e5e55bf1c1d2537af5622af9c904ed0d6e42b93 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 10:57:17 +0500 Subject: [PATCH 10/21] Remove custom implementations of SeqDeserializer and MapDeserializer for enums Those deserializers are used to deserialize tuple or struct variants from Content which is used by internally tagged enums and by flatten FlatMapDeserializer is reached in the following tests: flatten::enum_::externally_tagged::newtype flatten::enum_::externally_tagged::struct_from_map flatten::enum_::externally_tagged::struct_from_seq flatten::enum_::externally_tagged::tuple ContentDeserializer is reached in the following tests: test_enum_in_internally_tagged_enum test_internally_tagged_struct_variant_containing_unit_variant --- serde/src/private/de.rs | 176 +++++----------------------------------- 1 file changed, 19 insertions(+), 157 deletions(-) diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 3c0a187ac..06b024895 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -207,6 +207,7 @@ mod content { use __private::size_hint; use actually_private; + use de::value::{MapDeserializer, SeqDeserializer}; use de::{ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny, MapAccess, SeqAccess, Unexpected, Visitor, @@ -299,6 +300,17 @@ mod content { } } + impl<'de, E> de::IntoDeserializer<'de, E> for Content<'de> + where + E: de::Error, + { + type Deserializer = ContentDeserializer<'de, E>; + + fn into_deserializer(self) -> Self::Deserializer { + ContentDeserializer::new(self) + } + } + struct ContentVisitor<'de> { value: PhantomData>, } @@ -1074,7 +1086,7 @@ mod content { E: de::Error, { let seq = content.into_iter().map(ContentDeserializer::new); - let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let mut seq_visitor = SeqDeserializer::new(seq); let value = try!(visitor.visit_seq(&mut seq_visitor)); try!(seq_visitor.end()); Ok(value) @@ -1091,7 +1103,7 @@ mod content { let map = content .into_iter() .map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v))); - let mut map_visitor = de::value::MapDeserializer::new(map); + let mut map_visitor = MapDeserializer::new(map); let value = try!(visitor.visit_map(&mut map_visitor)); try!(map_visitor.end()); Ok(value) @@ -1569,7 +1581,7 @@ mod content { { match self.value { Some(Content::Seq(v)) => { - de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor) } Some(other) => Err(de::Error::invalid_type( other.unexpected(), @@ -1592,10 +1604,10 @@ mod content { { match self.value { Some(Content::Map(v)) => { - de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(MapDeserializer::new(v.into_iter()), visitor) } Some(Content::Seq(v)) => { - de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor) } Some(other) => Err(de::Error::invalid_type( other.unexpected(), @@ -1609,156 +1621,6 @@ mod content { } } - struct SeqDeserializer<'de, E> - where - E: de::Error, - { - iter: > as IntoIterator>::IntoIter, - err: PhantomData, - } - - impl<'de, E> SeqDeserializer<'de, E> - where - E: de::Error, - { - fn new(vec: Vec>) -> Self { - SeqDeserializer { - iter: vec.into_iter(), - err: PhantomData, - } - } - } - - impl<'de, E> de::Deserializer<'de> for SeqDeserializer<'de, E> - where - E: de::Error, - { - type Error = E; - - #[inline] - fn deserialize_any(mut self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let len = self.iter.len(); - if len == 0 { - visitor.visit_unit() - } else { - let ret = try!(visitor.visit_seq(&mut self)); - let remaining = self.iter.len(); - if remaining == 0 { - Ok(ret) - } else { - Err(de::Error::invalid_length(len, &"fewer elements in array")) - } - } - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any - } - } - - impl<'de, E> de::SeqAccess<'de> for SeqDeserializer<'de, E> - where - E: de::Error, - { - type Error = E; - - fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> - where - T: de::DeserializeSeed<'de>, - { - match self.iter.next() { - Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some), - None => Ok(None), - } - } - - fn size_hint(&self) -> Option { - size_hint::from_bounds(&self.iter) - } - } - - struct MapDeserializer<'de, E> - where - E: de::Error, - { - iter: , Content<'de>)> as IntoIterator>::IntoIter, - value: Option>, - err: PhantomData, - } - - impl<'de, E> MapDeserializer<'de, E> - where - E: de::Error, - { - fn new(map: Vec<(Content<'de>, Content<'de>)>) -> Self { - MapDeserializer { - iter: map.into_iter(), - value: None, - err: PhantomData, - } - } - } - - impl<'de, E> de::MapAccess<'de> for MapDeserializer<'de, E> - where - E: de::Error, - { - type Error = E; - - fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> - where - T: de::DeserializeSeed<'de>, - { - match self.iter.next() { - Some((key, value)) => { - self.value = Some(value); - seed.deserialize(ContentDeserializer::new(key)).map(Some) - } - None => Ok(None), - } - } - - fn next_value_seed(&mut self, seed: T) -> Result - where - T: de::DeserializeSeed<'de>, - { - match self.value.take() { - Some(value) => seed.deserialize(ContentDeserializer::new(value)), - None => Err(de::Error::custom("value is missing")), - } - } - - fn size_hint(&self) -> Option { - size_hint::from_bounds(&self.iter) - } - } - - impl<'de, E> de::Deserializer<'de> for MapDeserializer<'de, E> - where - E: de::Error, - { - type Error = E; - - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - visitor.visit_map(self) - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any - } - } - /// Not public API. pub struct ContentRefDeserializer<'a, 'de: 'a, E> { content: &'a Content<'de>, @@ -1820,7 +1682,7 @@ mod content { E: de::Error, { let seq = content.iter().map(ContentRefDeserializer::new); - let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let mut seq_visitor = SeqDeserializer::new(seq); let value = try!(visitor.visit_seq(&mut seq_visitor)); try!(seq_visitor.end()); Ok(value) @@ -1840,7 +1702,7 @@ mod content { ContentRefDeserializer::new(v), ) }); - let mut map_visitor = de::value::MapDeserializer::new(map); + let mut map_visitor = MapDeserializer::new(map); let value = try!(visitor.visit_map(&mut map_visitor)); try!(map_visitor.end()); Ok(value) From 91ec1c290f73777a49d200c880a3e87d86067a94 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 27 Jul 2023 19:02:09 -0700 Subject: [PATCH 11/21] Enforce question mark not used in serde crate yet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Question mark regresses compile time by 6.5–7.5%. --- serde/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 5473f822a..10461f46e 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -149,6 +149,8 @@ must_use_candidate, ) )] +// Restrictions +#![cfg_attr(feature = "cargo-clippy", deny(question_mark_used))] // Rustc lints. #![deny(missing_docs, unused_imports)] From db8f06467bf92b272a3c4890935401f75a22ae0d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 27 Jul 2023 19:05:47 -0700 Subject: [PATCH 12/21] Eliminate workaround for pre-1.17 rustc in serde_derive The oldest compiler supported by serde_derive by this point is 1.56. --- serde_derive/src/try.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/serde_derive/src/try.rs b/serde_derive/src/try.rs index d15d503e5..54967ebf5 100644 --- a/serde_derive/src/try.rs +++ b/serde_derive/src/try.rs @@ -1,4 +1,4 @@ -use proc_macro2::{Punct, Spacing, TokenStream}; +use proc_macro2::TokenStream; use quote::quote; // None of our generated code requires the `From::from` error conversion @@ -6,14 +6,11 @@ use quote::quote; // we see a significant improvement in type checking and borrow checking time of // the generated code and a slight improvement in binary size. pub fn replacement() -> TokenStream { - // Cannot pass `$expr` to `quote!` prior to Rust 1.17.0 so interpolate it. - let dollar = Punct::new('$', Spacing::Alone); - quote! { #[allow(unused_macros)] macro_rules! try { - (#dollar __expr:expr) => { - match #dollar __expr { + ($__expr:expr) => { + match $__expr { _serde::__private::Ok(__val) => __val, _serde::__private::Err(__err) => { return _serde::__private::Err(__err); From 6f1f38d0467fdf4659d3579e7dfc861ad336f1fc Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 27 Jul 2023 19:11:15 -0700 Subject: [PATCH 13/21] Replace 'try!' with '?' in serde_derive --- .../serde_derive/src/lib_from_source.rs | 1 - serde_derive/src/de.rs | 82 ++++++++-------- serde_derive/src/dummy.rs | 4 - serde_derive/src/lib.rs | 1 - serde_derive/src/ser.rs | 98 +++++++++---------- serde_derive/src/try.rs | 22 ----- 6 files changed, 90 insertions(+), 118 deletions(-) delete mode 100644 serde_derive/src/try.rs diff --git a/precompiled/serde_derive/src/lib_from_source.rs b/precompiled/serde_derive/src/lib_from_source.rs index 2427a574a..8783c0585 100644 --- a/precompiled/serde_derive/src/lib_from_source.rs +++ b/precompiled/serde_derive/src/lib_from_source.rs @@ -14,7 +14,6 @@ mod internals; mod pretend; mod ser; mod this; -mod try; use proc_macro::TokenStream; use syn::{parse_macro_input, DeriveInput}; diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 305a14d91..1434680b8 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -710,14 +710,14 @@ fn deserialize_seq( let span = field.original.span(); let func = quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>); - quote!(try!(#func(&mut __seq))) + quote!(#func(&mut __seq)?) } Some(path) => { let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); quote!({ #wrapper _serde::__private::Option::map( - try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)), + _serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)?, |__wrap| __wrap.value) }) } @@ -824,8 +824,8 @@ fn deserialize_seq_in_place( let write = match field.attrs.deserialize_with() { None => { quote! { - if let _serde::__private::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq, - _serde::__private::de::InPlaceSeed(&mut self.place.#member))) + if let _serde::__private::None = _serde::de::SeqAccess::next_element_seed(&mut __seq, + _serde::__private::de::InPlaceSeed(&mut self.place.#member))? { #value_if_none } @@ -835,7 +835,7 @@ fn deserialize_seq_in_place( let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); quote!({ #wrapper - match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) { + match _serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)? { _serde::__private::Some(__wrap) => { self.place.#member = __wrap.value; } @@ -887,12 +887,12 @@ fn deserialize_newtype_struct( let span = field.original.span(); let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize); quote! { - try!(#func(__e)) + #func(__e)? } } Some(path) => { quote! { - try!(#path(__e)) + #path(__e)? } } }; @@ -1364,7 +1364,7 @@ fn deserialize_externally_tagged_enum( } } else { quote! { - match try!(_serde::de::EnumAccess::variant(__data)) { + match _serde::de::EnumAccess::variant(__data)? { #(#variant_arms)* } } @@ -1444,9 +1444,9 @@ fn deserialize_internally_tagged_enum( #variants_stmt - let (__tag, __content) = try!(_serde::Deserializer::deserialize_any( + let (__tag, __content) = _serde::Deserializer::deserialize_any( __deserializer, - _serde::__private::de::TaggedContentVisitor::<__Field>::new(#tag, #expecting))); + _serde::__private::de::TaggedContentVisitor::<__Field>::new(#tag, #expecting))?; let __deserializer = _serde::__private::de::ContentDeserializer::<__D::Error>::new(__content); match __tag { @@ -1554,7 +1554,7 @@ fn deserialize_adjacently_tagged_enum( // Advance the map by one key, returning early in case of error. let next_key = quote! { - try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)) + _serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)? }; // When allowing unknown fields, we want to transparently step through keys @@ -1567,7 +1567,7 @@ fn deserialize_adjacently_tagged_enum( while let _serde::__private::Some(__k) = #next_key { match __k { _serde::__private::de::TagContentOtherField::Other => { - let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); + let _ = _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?; continue; }, _serde::__private::de::TagContentOtherField::Tag => { @@ -1602,14 +1602,14 @@ fn deserialize_adjacently_tagged_enum( let finish_content_then_tag = if variant_arms.is_empty() { quote! { - match try!(_serde::de::MapAccess::next_value::<__Field>(&mut __map)) {} + match _serde::de::MapAccess::next_value::<__Field>(&mut __map)? {} } } else { quote! { - let __ret = try!(match try!(_serde::de::MapAccess::next_value(&mut __map)) { + let __ret = match _serde::de::MapAccess::next_value(&mut __map)? { // Deserialize the buffered content now that we know the variant. #(#variant_arms)* - }); + }?; // Visit remaining keys, looking for duplicates. #visit_remaining_keys } @@ -1662,7 +1662,7 @@ fn deserialize_adjacently_tagged_enum( // First key is the tag. _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { // Parse the tag. - let __field = try!(_serde::de::MapAccess::next_value(&mut __map)); + let __field = _serde::de::MapAccess::next_value(&mut __map)?; // Visit the second key. match #next_relevant_key { // Second key is a duplicate of the tag. @@ -1671,12 +1671,12 @@ fn deserialize_adjacently_tagged_enum( } // Second key is the content. _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { - let __ret = try!(_serde::de::MapAccess::next_value_seed(&mut __map, + let __ret = _serde::de::MapAccess::next_value_seed(&mut __map, __Seed { field: __field, marker: _serde::__private::PhantomData, lifetime: _serde::__private::PhantomData, - })); + })?; // Visit remaining keys, looking for duplicates. #visit_remaining_keys } @@ -1687,7 +1687,7 @@ fn deserialize_adjacently_tagged_enum( // First key is the content. _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { // Buffer up the content. - let __content = try!(_serde::de::MapAccess::next_value::<_serde::__private::de::Content>(&mut __map)); + let __content = _serde::de::MapAccess::next_value::<_serde::__private::de::Content>(&mut __map)?; // Visit the second key. match #next_relevant_key { // Second key is the tag. @@ -1717,17 +1717,17 @@ fn deserialize_adjacently_tagged_enum( __A: _serde::de::SeqAccess<#delife>, { // Visit the first element - the tag. - match try!(_serde::de::SeqAccess::next_element(&mut __seq)) { + match _serde::de::SeqAccess::next_element(&mut __seq)? { _serde::__private::Some(__field) => { // Visit the second element - the content. - match try!(_serde::de::SeqAccess::next_element_seed( + match _serde::de::SeqAccess::next_element_seed( &mut __seq, __Seed { field: __field, marker: _serde::__private::PhantomData, lifetime: _serde::__private::PhantomData, }, - )) { + )? { _serde::__private::Some(__ret) => _serde::__private::Ok(__ret), // There is no second element. _serde::__private::None => { @@ -1797,7 +1797,7 @@ fn deserialize_untagged_enum_after( let fallthrough_msg = cattrs.expecting().unwrap_or(&fallthrough_msg); quote_block! { - let __content = try!(<_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer)); + let __content = <_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer)?; let __deserializer = _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content); #( @@ -1830,7 +1830,7 @@ fn deserialize_externally_tagged_variant( Style::Unit => { let this_value = ¶ms.this_value; quote_block! { - try!(_serde::de::VariantAccess::unit_variant(__variant)); + _serde::de::VariantAccess::unit_variant(__variant)?; _serde::__private::Ok(#this_value::#variant_ident) } } @@ -1879,7 +1879,7 @@ fn deserialize_internally_tagged_variant( quote!((#default)) }); quote_block! { - try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::__private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); + _serde::Deserializer::deserialize_any(#deserializer, _serde::__private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))?; _serde::__private::Ok(#this_value::#variant_ident #default) } } @@ -1965,7 +1965,7 @@ fn deserialize_externally_tagged_newtype_variant( if field.attrs.skip_deserializing() { let default = Expr(expr_is_missing(field, cattrs)); return quote_block! { - try!(_serde::de::VariantAccess::unit_variant(__variant)); + _serde::de::VariantAccess::unit_variant(__variant)?; _serde::__private::Ok(#this_value::#variant_ident(#default)) }; } @@ -2540,7 +2540,7 @@ fn deserialize_map( let func = quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>); quote! { - try!(#func(&mut __map)) + #func(&mut __map)? } } Some(path) => { @@ -2572,14 +2572,14 @@ fn deserialize_map( __Field::__other(__name) => { __collect.push(_serde::__private::Some(( __name, - try!(_serde::de::MapAccess::next_value(&mut __map))))); + _serde::de::MapAccess::next_value(&mut __map)?))); } }) } else if cattrs.deny_unknown_fields() { None } else { Some(quote! { - _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); } + _ => { let _ = _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?; } }) }; @@ -2587,14 +2587,14 @@ fn deserialize_map( let match_keys = if cattrs.deny_unknown_fields() && all_skipped { quote! { // FIXME: Once feature(exhaustive_patterns) is stable: - // let _serde::__private::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map)); + // let _serde::__private::None::<__Field> = _serde::de::MapAccess::next_key(&mut __map)?; _serde::__private::Option::map( - try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)), + _serde::de::MapAccess::next_key::<__Field>(&mut __map)?, |__impossible| match __impossible {}); } } else { quote! { - while let _serde::__private::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) { + while let _serde::__private::Some(__key) = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { match __key { #(#value_arms)* #ignored_arm @@ -2630,10 +2630,10 @@ fn deserialize_map( Some(path) => quote!(#path), }; quote! { - let #name: #field_ty = try!(#func( + let #name: #field_ty = #func( _serde::__private::de::FlatMapDeserializer( &mut __collect, - _serde::__private::PhantomData))); + _serde::__private::PhantomData))?; } }); @@ -2780,7 +2780,7 @@ fn deserialize_map_in_place( let visit = match field.attrs.deserialize_with() { None => { quote! { - try!(_serde::de::MapAccess::next_value_seed(&mut __map, _serde::__private::de::InPlaceSeed(&mut self.place.#member))) + _serde::de::MapAccess::next_value_seed(&mut __map, _serde::__private::de::InPlaceSeed(&mut self.place.#member))? } } Some(path) => { @@ -2812,7 +2812,7 @@ fn deserialize_map_in_place( None } else { Some(quote! { - _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); } + _ => { let _ = _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?; } }) }; @@ -2821,14 +2821,14 @@ fn deserialize_map_in_place( let match_keys = if cattrs.deny_unknown_fields() && all_skipped { quote! { // FIXME: Once feature(exhaustive_patterns) is stable: - // let _serde::__private::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map)); + // let _serde::__private::None::<__Field> = _serde::de::MapAccess::next_key(&mut __map)?; _serde::__private::Option::map( - try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)), + _serde::de::MapAccess::next_key::<__Field>(&mut __map)?, |__impossible| match __impossible {}); } } else { quote! { - while let _serde::__private::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) { + while let _serde::__private::Some(__key) = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { match __key { #(#value_arms_from)* #ignored_arm @@ -2925,7 +2925,7 @@ fn wrap_deserialize_with( __D: _serde::Deserializer<#delife>, { _serde::__private::Ok(__DeserializeWith { - value: try!(#deserialize_with(__deserializer)), + value: #deserialize_with(__deserializer)?, phantom: _serde::__private::PhantomData, lifetime: _serde::__private::PhantomData, }) @@ -3035,7 +3035,7 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment { let span = field.original.span(); let func = quote_spanned!(span=> _serde::__private::de::missing_field); quote_expr! { - try!(#func(#name)) + #func(#name)? } } Some(_) => { diff --git a/serde_derive/src/dummy.rs b/serde_derive/src/dummy.rs index 646da540d..095f950f3 100644 --- a/serde_derive/src/dummy.rs +++ b/serde_derive/src/dummy.rs @@ -1,10 +1,7 @@ -use crate::try; use proc_macro2::TokenStream; use quote::quote; pub fn wrap_in_const(serde_path: Option<&syn::Path>, code: TokenStream) -> TokenStream { - let try_replacement = try::replacement(); - let use_serde = match serde_path { Some(path) => quote! { use #path as _serde; @@ -20,7 +17,6 @@ pub fn wrap_in_const(serde_path: Option<&syn::Path>, code: TokenStream) -> Token #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] const _: () = { #use_serde - #try_replacement #code }; } diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index d966d8355..a7d32bb13 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -90,7 +90,6 @@ mod dummy; mod pretend; mod ser; mod this; -mod try; #[cfg(precompiled)] macro_rules! parse_macro_input { diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 951573ca4..1792d3fec 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -282,7 +282,7 @@ fn serialize_tuple_struct( .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); quote_block! { - let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len)); + let #let_mut __serde_state = _serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len)?; #(#serialize_stmts)* _serde::ser::SerializeTupleStruct::end(__serde_state) } @@ -304,7 +304,7 @@ fn serialize_struct_tag_field(cattrs: &attr::Container, struct_trait: &StructTra let type_name = cattrs.name().serialize_name(); let func = struct_trait.serialize_field(Span::call_site()); quote! { - try!(#func(&mut __serde_state, #tag, #type_name)); + #func(&mut __serde_state, #tag, #type_name)?; } } _ => quote! {}, @@ -345,7 +345,7 @@ fn serialize_struct_as_struct( ); quote_block! { - let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len)); + let #let_mut __serde_state = _serde::Serializer::serialize_struct(__serializer, #type_name, #len)?; #tag_field #(#serialize_fields)* _serde::ser::SerializeStruct::end(__serde_state) @@ -389,7 +389,7 @@ fn serialize_struct_as_map( }; quote_block! { - let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(__serializer, #len)); + let #let_mut __serde_state = _serde::Serializer::serialize_map(__serializer, #len)?; #tag_field #(#serialize_fields)* _serde::ser::SerializeMap::end(__serde_state) @@ -593,10 +593,10 @@ fn serialize_internally_tagged_variant( match effective_style(variant) { Style::Unit => { quote_block! { - let mut __struct = try!(_serde::Serializer::serialize_struct( - __serializer, #type_name, 1)); - try!(_serde::ser::SerializeStruct::serialize_field( - &mut __struct, #tag, #variant_name)); + let mut __struct = _serde::Serializer::serialize_struct( + __serializer, #type_name, 1)?; + _serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)?; _serde::ser::SerializeStruct::end(__struct) } } @@ -650,10 +650,10 @@ fn serialize_adjacently_tagged_variant( match effective_style(variant) { Style::Unit => { return quote_block! { - let mut __struct = try!(_serde::Serializer::serialize_struct( - __serializer, #type_name, 1)); - try!(_serde::ser::SerializeStruct::serialize_field( - &mut __struct, #tag, #variant_name)); + let mut __struct = _serde::Serializer::serialize_struct( + __serializer, #type_name, 1)?; + _serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)?; _serde::ser::SerializeStruct::end(__struct) }; } @@ -667,12 +667,12 @@ fn serialize_adjacently_tagged_variant( let span = field.original.span(); let func = quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field); return quote_block! { - let mut __struct = try!(_serde::Serializer::serialize_struct( - __serializer, #type_name, 2)); - try!(_serde::ser::SerializeStruct::serialize_field( - &mut __struct, #tag, #variant_name)); - try!(#func( - &mut __struct, #content, #field_expr)); + let mut __struct = _serde::Serializer::serialize_struct( + __serializer, #type_name, 2)?; + _serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)?; + #func( + &mut __struct, #content, #field_expr)?; _serde::ser::SerializeStruct::end(__struct) }; } @@ -732,15 +732,15 @@ fn serialize_adjacently_tagged_variant( } } - let mut __struct = try!(_serde::Serializer::serialize_struct( - __serializer, #type_name, 2)); - try!(_serde::ser::SerializeStruct::serialize_field( - &mut __struct, #tag, #variant_name)); - try!(_serde::ser::SerializeStruct::serialize_field( + let mut __struct = _serde::Serializer::serialize_struct( + __serializer, #type_name, 2)?; + _serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)?; + _serde::ser::SerializeStruct::serialize_field( &mut __struct, #content, &__AdjacentlyTagged { data: (#(#fields_ident,)*), phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, - })); + })?; _serde::ser::SerializeStruct::end(__struct) } } @@ -830,21 +830,21 @@ fn serialize_tuple_variant( variant_name, } => { quote_block! { - let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_variant( + let #let_mut __serde_state = _serde::Serializer::serialize_tuple_variant( __serializer, #type_name, #variant_index, #variant_name, - #len)); + #len)?; #(#serialize_stmts)* _serde::ser::SerializeTupleVariant::end(__serde_state) } } TupleVariant::Untagged => { quote_block! { - let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple( + let #let_mut __serde_state = _serde::Serializer::serialize_tuple( __serializer, - #len)); + #len)?; #(#serialize_stmts)* _serde::ser::SerializeTuple::end(__serde_state) } @@ -907,40 +907,40 @@ fn serialize_struct_variant( variant_name, } => { quote_block! { - let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct_variant( + let #let_mut __serde_state = _serde::Serializer::serialize_struct_variant( __serializer, #name, #variant_index, #variant_name, #len, - )); + )?; #(#serialize_fields)* _serde::ser::SerializeStructVariant::end(__serde_state) } } StructVariant::InternallyTagged { tag, variant_name } => { quote_block! { - let mut __serde_state = try!(_serde::Serializer::serialize_struct( + let mut __serde_state = _serde::Serializer::serialize_struct( __serializer, #name, #len + 1, - )); - try!(_serde::ser::SerializeStruct::serialize_field( + )?; + _serde::ser::SerializeStruct::serialize_field( &mut __serde_state, #tag, #variant_name, - )); + )?; #(#serialize_fields)* _serde::ser::SerializeStruct::end(__serde_state) } } StructVariant::Untagged => { quote_block! { - let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct( + let #let_mut __serde_state = _serde::Serializer::serialize_struct( __serializer, #name, #len, - )); + )?; #(#serialize_fields)* _serde::ser::SerializeStruct::end(__serde_state) } @@ -990,9 +990,9 @@ fn serialize_struct_variant_with_flatten( __S: _serde::Serializer, { let (#(#members,)*) = self.data; - let #let_mut __serde_state = try!(_serde::Serializer::serialize_map( + let #let_mut __serde_state = _serde::Serializer::serialize_map( __serializer, - _serde::__private::None)); + _serde::__private::None)?; #(#serialize_fields)* _serde::ser::SerializeMap::end(__serde_state) } @@ -1011,23 +1011,23 @@ fn serialize_struct_variant_with_flatten( } StructVariant::InternallyTagged { tag, variant_name } => { quote_block! { - let #let_mut __serde_state = try!(_serde::Serializer::serialize_map( + let #let_mut __serde_state = _serde::Serializer::serialize_map( __serializer, - _serde::__private::None)); - try!(_serde::ser::SerializeMap::serialize_entry( + _serde::__private::None)?; + _serde::ser::SerializeMap::serialize_entry( &mut __serde_state, #tag, #variant_name, - )); + )?; #(#serialize_fields)* _serde::ser::SerializeMap::end(__serde_state) } } StructVariant::Untagged => { quote_block! { - let #let_mut __serde_state = try!(_serde::Serializer::serialize_map( + let #let_mut __serde_state = _serde::Serializer::serialize_map( __serializer, - _serde::__private::None)); + _serde::__private::None)?; #(#serialize_fields)* _serde::ser::SerializeMap::end(__serde_state) } @@ -1072,7 +1072,7 @@ fn serialize_tuple_struct_visitor( let span = field.original.span(); let func = tuple_trait.serialize_element(span); let ser = quote! { - try!(#func(&mut __serde_state, #field_expr)); + #func(&mut __serde_state, #field_expr)?; }; match skip { @@ -1116,12 +1116,12 @@ fn serialize_struct_visitor( let ser = if field.attrs.flatten() { let func = quote_spanned!(span=> _serde::Serialize::serialize); quote! { - try!(#func(&#field_expr, _serde::__private::ser::FlatMapSerializer(&mut __serde_state))); + #func(&#field_expr, _serde::__private::ser::FlatMapSerializer(&mut __serde_state))?; } } else { let func = struct_trait.serialize_field(span); quote! { - try!(#func(&mut __serde_state, #key_expr, #field_expr)); + #func(&mut __serde_state, #key_expr, #field_expr)?; } }; @@ -1133,7 +1133,7 @@ fn serialize_struct_visitor( if !#skip { #ser } else { - try!(#skip_func(&mut __serde_state, #key_expr)); + #skip_func(&mut __serde_state, #key_expr)?; } } } else { @@ -1233,7 +1233,7 @@ fn wrap_serialize_with( // Serialization of an empty struct results in code like: // -// let mut __serde_state = try!(serializer.serialize_struct("S", 0)); +// let mut __serde_state = serializer.serialize_struct("S", 0)?; // _serde::ser::SerializeStruct::end(__serde_state) // // where we want to omit the `mut` to avoid a warning. diff --git a/serde_derive/src/try.rs b/serde_derive/src/try.rs deleted file mode 100644 index 54967ebf5..000000000 --- a/serde_derive/src/try.rs +++ /dev/null @@ -1,22 +0,0 @@ -use proc_macro2::TokenStream; -use quote::quote; - -// None of our generated code requires the `From::from` error conversion -// performed by the standard library's `try!` macro. With this simplified macro -// we see a significant improvement in type checking and borrow checking time of -// the generated code and a slight improvement in binary size. -pub fn replacement() -> TokenStream { - quote! { - #[allow(unused_macros)] - macro_rules! try { - ($__expr:expr) => { - match $__expr { - _serde::__private::Ok(__val) => __val, - _serde::__private::Err(__err) => { - return _serde::__private::Err(__err); - } - } - } - } - } -} From 92d686f9a536d4b3d3ede61e65d2f883a7bc4ed4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 28 Jul 2023 15:58:57 -0700 Subject: [PATCH 14/21] Fix serde::de::StdError in no-std unstable build --- serde/src/de/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index a04ecf77d..b53206bdf 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -126,10 +126,13 @@ mod utf8; pub use self::ignored_any::IgnoredAny; +#[cfg(all(feature = "unstable", not(feature = "std")))] +#[doc(no_inline)] +pub use core::error::Error as StdError; #[cfg(feature = "std")] #[doc(no_inline)] pub use std::error::Error as StdError; -#[cfg(not(feature = "std"))] +#[cfg(not(any(feature = "std", feature = "unstable")))] #[doc(no_inline)] pub use std_error::Error as StdError; From ff5442cd9ea48fd3913700bb3ddb7f1a72c9b2c3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 28 Jul 2023 16:00:07 -0700 Subject: [PATCH 15/21] Add no-std unstable build in CI --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6652aad73..d67039ce3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,6 +62,7 @@ jobs: - run: cd serde && cargo build --no-default-features - run: cd serde && cargo build --no-default-features --features alloc - run: cd serde && cargo build --no-default-features --features rc,alloc + - run: cd serde && cargo build --no-default-features --features unstable - run: cd serde && cargo test --features derive,rc,unstable - run: cd test_suite/no_std && cargo build if: matrix.os != 'windows' From 861b0dfea27c50c4b70524c3495567590c0fd307 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 28 Jul 2023 16:06:49 -0700 Subject: [PATCH 16/21] Consistently list StdError under 'Re-exports' heading of rustdoc --- serde/src/ser/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index e1f38444d..1aaa7570f 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -116,7 +116,7 @@ mod impossible; pub use self::impossible::Impossible; #[cfg(all(feature = "unstable", not(feature = "std")))] -#[doc(inline)] +#[doc(no_inline)] pub use core::error::Error as StdError; #[cfg(feature = "std")] #[doc(no_inline)] From 3616860203962c0644d286023a604d514c328f60 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 28 Jul 2023 16:09:22 -0700 Subject: [PATCH 17/21] Delete broken symlink from precompiled derive sources --- precompiled/serde_derive/src/try.rs | 1 - 1 file changed, 1 deletion(-) delete mode 120000 precompiled/serde_derive/src/try.rs diff --git a/precompiled/serde_derive/src/try.rs b/precompiled/serde_derive/src/try.rs deleted file mode 120000 index bdcbf563e..000000000 --- a/precompiled/serde_derive/src/try.rs +++ /dev/null @@ -1 +0,0 @@ -../../../serde_derive/src/try.rs \ No newline at end of file From 48aa054f5395d2570f51b9d0c85e486f1b3b46ef Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 28 Jul 2023 16:07:40 -0700 Subject: [PATCH 18/21] Release 1.0.178 --- precompiled/bin/Cargo.toml | 2 +- precompiled/serde_derive/Cargo.toml | 2 +- precompiled/serde_derive/src/lib.rs | 2 +- serde/Cargo.toml | 4 ++-- serde/src/lib.rs | 2 +- serde_derive/Cargo.toml | 2 +- serde_derive/src/lib.rs | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/precompiled/bin/Cargo.toml b/precompiled/bin/Cargo.toml index d2797be93..4bbe6d430 100644 --- a/precompiled/bin/Cargo.toml +++ b/precompiled/bin/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_derive" -version = "1.0.177" +version = "1.0.178" authors = ["David Tolnay "] publish = false diff --git a/precompiled/serde_derive/Cargo.toml b/precompiled/serde_derive/Cargo.toml index 70687716b..a58bc28e6 100644 --- a/precompiled/serde_derive/Cargo.toml +++ b/precompiled/serde_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_derive" -version = "1.0.177" +version = "1.0.178" authors = ["David Tolnay "] categories = ["no-std", "no-std::no-alloc"] description = "Implementation of #[derive(Serialize, Deserialize)]" diff --git a/precompiled/serde_derive/src/lib.rs b/precompiled/serde_derive/src/lib.rs index 7023d2d94..f1c46e836 100644 --- a/precompiled/serde_derive/src/lib.rs +++ b/precompiled/serde_derive/src/lib.rs @@ -13,7 +13,7 @@ //! //! [https://serde.rs/derive.html]: https://serde.rs/derive.html -#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.177")] +#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.178")] #[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))] include!("lib_from_source.rs"); diff --git a/serde/Cargo.toml b/serde/Cargo.toml index d5898c313..32f5a3a6f 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde" -version = "1.0.177" # remember to update html_root_url and serde_derive dependency +version = "1.0.178" # remember to update html_root_url and serde_derive dependency authors = ["Erick Tryzelaar ", "David Tolnay "] build = "build.rs" categories = ["encoding", "no-std", "no-std::no-alloc"] @@ -14,7 +14,7 @@ repository = "https://github.com/serde-rs/serde" rust-version = "1.19" [dependencies] -serde_derive = { version = "=1.0.177", optional = true, path = "../serde_derive" } +serde_derive = { version = "=1.0.178", optional = true, path = "../serde_derive" } [dev-dependencies] serde_derive = { version = "1", path = "../serde_derive" } diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 10461f46e..cc9151258 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -93,7 +93,7 @@ //////////////////////////////////////////////////////////////////////////////// // Serde types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/serde/1.0.177")] +#![doc(html_root_url = "https://docs.rs/serde/1.0.178")] // Support using Serde without the standard library! #![cfg_attr(not(feature = "std"), no_std)] // Unstable functionality only if the user asks for it. For tracking and diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 1dc99a730..d0ffa43b6 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_derive" -version = "1.0.177" # remember to update html_root_url +version = "1.0.178" # remember to update html_root_url authors = ["Erick Tryzelaar ", "David Tolnay "] categories = ["no-std", "no-std::no-alloc"] description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index a7d32bb13..e9752c934 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -13,7 +13,7 @@ //! //! [https://serde.rs/derive.html]: https://serde.rs/derive.html -#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.177")] +#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.178")] // Ignored clippy lints #![allow( // clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054 From 02c34e490b6886ee65c2032939239e25540af7c2 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 30 Jul 2023 16:07:17 -0700 Subject: [PATCH 19/21] Resolve redundant_field_names clippy lint from PR 2448 warning: redundant field names in struct initialization --> serde/src/private/ser.rs:1278:13 | 1278 | map: map, | ^^^^^^^^ help: replace it with: `map` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names = note: `-W clippy::redundant-field-names` implied by `-W clippy::all` --- serde/src/private/ser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index a73f259b4..122598947 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -1275,7 +1275,7 @@ where { fn new(map: &'a mut M) -> Self { FlatMapSerializeTupleVariantAsMapValue { - map: map, + map, fields: Vec::new(), } } From e7df53701c6e71dce4a8a376a84838134ea73a65 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 30 Jul 2023 16:15:23 -0700 Subject: [PATCH 20/21] Resolve doc_markdown clippy lint from PR 2448 warning: item in documentation is missing backticks --> test_suite/tests/test_annotations.rs:2870:25 | 2870 | /// Reaches crate::private::de::content::VariantDeserializer::tuple_variant | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown = note: `-W clippy::doc-markdown` implied by `-W clippy::pedantic` help: try | 2870 | /// Reaches `crate::private::de::content::VariantDeserializer::tuple_variant` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: item in documentation is missing backticks --> test_suite/tests/test_annotations.rs:2871:17 | 2871 | /// Content::Seq case | ^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown help: try | 2871 | /// `Content::Seq` case | ~~~~~~~~~~~~~~ warning: item in documentation is missing backticks --> test_suite/tests/test_annotations.rs:2872:21 | 2872 | /// via FlatMapDeserializer::deserialize_enum | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown help: try | 2872 | /// via `FlatMapDeserializer::deserialize_enum` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: item in documentation is missing backticks --> test_suite/tests/test_annotations.rs:2894:25 | 2894 | /// Reaches crate::private::de::content::VariantDeserializer::struct_variant | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown help: try | 2894 | /// Reaches `crate::private::de::content::VariantDeserializer::struct_variant` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: item in documentation is missing backticks --> test_suite/tests/test_annotations.rs:2895:17 | 2895 | /// Content::Seq case | ^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown help: try | 2895 | /// `Content::Seq` case | ~~~~~~~~~~~~~~ warning: item in documentation is missing backticks --> test_suite/tests/test_annotations.rs:2896:21 | 2896 | /// via FlatMapDeserializer::deserialize_enum | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown help: try | 2896 | /// via `FlatMapDeserializer::deserialize_enum` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: item in documentation is missing backticks --> test_suite/tests/test_annotations.rs:2921:25 | 2921 | /// Reaches crate::private::de::content::VariantDeserializer::struct_variant | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown help: try | 2921 | /// Reaches `crate::private::de::content::VariantDeserializer::struct_variant` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: item in documentation is missing backticks --> test_suite/tests/test_annotations.rs:2922:17 | 2922 | /// Content::Map case | ^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown help: try | 2922 | /// `Content::Map` case | ~~~~~~~~~~~~~~ warning: item in documentation is missing backticks --> test_suite/tests/test_annotations.rs:2923:21 | 2923 | /// via FlatMapDeserializer::deserialize_enum | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown help: try | 2923 | /// via `FlatMapDeserializer::deserialize_enum` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- test_suite/tests/test_annotations.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index d8e4a6345..9d301c4cf 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2867,9 +2867,9 @@ mod flatten { ); } - /// Reaches crate::private::de::content::VariantDeserializer::tuple_variant - /// Content::Seq case - /// via FlatMapDeserializer::deserialize_enum + // Reaches crate::private::de::content::VariantDeserializer::tuple_variant + // Content::Seq case + // via FlatMapDeserializer::deserialize_enum #[test] fn tuple() { assert_tokens( @@ -2891,9 +2891,9 @@ mod flatten { ); } - /// Reaches crate::private::de::content::VariantDeserializer::struct_variant - /// Content::Seq case - /// via FlatMapDeserializer::deserialize_enum + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Seq case + // via FlatMapDeserializer::deserialize_enum #[test] fn struct_from_seq() { assert_de_tokens( @@ -2918,9 +2918,9 @@ mod flatten { ); } - /// Reaches crate::private::de::content::VariantDeserializer::struct_variant - /// Content::Map case - /// via FlatMapDeserializer::deserialize_enum + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Map case + // via FlatMapDeserializer::deserialize_enum #[test] fn struct_from_map() { assert_tokens( From c2b16bfbb0a5b662aa97c9a8a5d5bf7d958b85b8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 30 Jul 2023 17:20:10 -0700 Subject: [PATCH 21/21] Release 1.0.179 --- precompiled/bin/Cargo.toml | 2 +- precompiled/serde_derive/Cargo.toml | 2 +- precompiled/serde_derive/src/lib.rs | 2 +- serde/Cargo.toml | 4 ++-- serde/src/lib.rs | 2 +- serde_derive/Cargo.toml | 2 +- serde_derive/src/lib.rs | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/precompiled/bin/Cargo.toml b/precompiled/bin/Cargo.toml index 4bbe6d430..4bd097ef3 100644 --- a/precompiled/bin/Cargo.toml +++ b/precompiled/bin/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_derive" -version = "1.0.178" +version = "1.0.179" authors = ["David Tolnay "] publish = false diff --git a/precompiled/serde_derive/Cargo.toml b/precompiled/serde_derive/Cargo.toml index a58bc28e6..b019e43ee 100644 --- a/precompiled/serde_derive/Cargo.toml +++ b/precompiled/serde_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_derive" -version = "1.0.178" +version = "1.0.179" authors = ["David Tolnay "] categories = ["no-std", "no-std::no-alloc"] description = "Implementation of #[derive(Serialize, Deserialize)]" diff --git a/precompiled/serde_derive/src/lib.rs b/precompiled/serde_derive/src/lib.rs index f1c46e836..32f3418a3 100644 --- a/precompiled/serde_derive/src/lib.rs +++ b/precompiled/serde_derive/src/lib.rs @@ -13,7 +13,7 @@ //! //! [https://serde.rs/derive.html]: https://serde.rs/derive.html -#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.178")] +#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.179")] #[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))] include!("lib_from_source.rs"); diff --git a/serde/Cargo.toml b/serde/Cargo.toml index 32f5a3a6f..b9959cf02 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde" -version = "1.0.178" # remember to update html_root_url and serde_derive dependency +version = "1.0.179" # remember to update html_root_url and serde_derive dependency authors = ["Erick Tryzelaar ", "David Tolnay "] build = "build.rs" categories = ["encoding", "no-std", "no-std::no-alloc"] @@ -14,7 +14,7 @@ repository = "https://github.com/serde-rs/serde" rust-version = "1.19" [dependencies] -serde_derive = { version = "=1.0.178", optional = true, path = "../serde_derive" } +serde_derive = { version = "=1.0.179", optional = true, path = "../serde_derive" } [dev-dependencies] serde_derive = { version = "1", path = "../serde_derive" } diff --git a/serde/src/lib.rs b/serde/src/lib.rs index cc9151258..30c5e4d60 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -93,7 +93,7 @@ //////////////////////////////////////////////////////////////////////////////// // Serde types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/serde/1.0.178")] +#![doc(html_root_url = "https://docs.rs/serde/1.0.179")] // Support using Serde without the standard library! #![cfg_attr(not(feature = "std"), no_std)] // Unstable functionality only if the user asks for it. For tracking and diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index d0ffa43b6..e77c68733 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_derive" -version = "1.0.178" # remember to update html_root_url +version = "1.0.179" # remember to update html_root_url authors = ["Erick Tryzelaar ", "David Tolnay "] categories = ["no-std", "no-std::no-alloc"] description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index e9752c934..6d596d157 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -13,7 +13,7 @@ //! //! [https://serde.rs/derive.html]: https://serde.rs/derive.html -#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.178")] +#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.179")] // Ignored clippy lints #![allow( // clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054