From dca15a7254b478bdad1434dccb83f482357e731f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 13:28:02 -0700 Subject: [PATCH 01/13] Implement Serialize for Id --- src/id.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/id.rs b/src/id.rs index db8ab53..596bd7a 100644 --- a/src/id.rs +++ b/src/id.rs @@ -1,4 +1,5 @@ use serde::de::{Deserialize, Deserializer, Error, Unexpected, Visitor}; +use serde::ser::{Serialize, Serializer}; use std::fmt::{self, Debug, Display}; #[derive(Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] @@ -51,3 +52,12 @@ impl<'de> Deserialize<'de> for Id { deserializer.deserialize_str(IdVisitor) } } + +impl Serialize for Id { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_str(self) + } +} From 833946a05ce6068857f7961c21b0d0d66c536bd4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 13:28:22 -0700 Subject: [PATCH 02/13] Implement Serialize for Node --- src/lib.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 5971c54..8c58cc2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -405,6 +405,7 @@ extern crate serde; use crate::deserializer::NodeDeserializer; use crate::kind::AnyKind; use serde::de::{Deserialize, Deserializer, MapAccess, Visitor}; +use serde::ser::{Serialize, SerializeMap, Serializer}; use std::fmt; use std::marker::PhantomData; @@ -522,3 +523,19 @@ where deserializer.deserialize_map(visitor) } } + +impl Serialize for Node +where + T: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("id", &self.id)?; + //FIXME &self.kind; + map.serialize_entry("inner", &self.inner)?; + map.end() + } +} From 797857eeaf474e8e89bdb15f0d840ab174ae2e68 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 13:34:44 -0700 Subject: [PATCH 03/13] Implement Serialize for Kind --- src/kind.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/kind.rs b/src/kind.rs index f6dba0d..f8de3f3 100644 --- a/src/kind.rs +++ b/src/kind.rs @@ -2,6 +2,7 @@ use serde::de::{ DeserializeSeed, Deserializer, EnumAccess, Expected, IntoDeserializer, Unexpected, VariantAccess, Visitor, }; +use serde::ser::{Serialize, Serializer}; use serde::{forward_to_deserialize_any, Deserialize}; use std::borrow::Cow; use std::fmt::{self, Debug, Display}; @@ -274,6 +275,19 @@ impl<'de> Visitor<'de> for KindVisitor { } } +impl Serialize for Kind { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if let Kind::null = self { + serializer.serialize_unit() + } else { + serializer.serialize_str(self.as_str()) + } + } +} + pub struct ParseKindError { _private: (), } From 8300eb0903307b0a4d5cb05276de5e7d658fe54e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 13:38:46 -0700 Subject: [PATCH 04/13] Implement Serialize for IncludedFrom --- src/loc.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/loc.rs b/src/loc.rs index 8189afa..9b4305d 100644 --- a/src/loc.rs +++ b/src/loc.rs @@ -1,5 +1,6 @@ use crate::intern::InternVisitor; use serde::de::{Deserialize, Deserializer, Error, IgnoredAny, MapAccess, Visitor}; +use serde::ser::{Serialize, SerializeMap, Serializer}; use std::cell::{Cell, RefCell}; use std::fmt::{self, Debug}; use std::sync::Arc; @@ -464,6 +465,20 @@ impl SourceLocationField { } } +impl Serialize for IncludedFrom { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut map = serializer.serialize_map(None)?; + if let Some(included_from) = &self.included_from { + map.serialize_entry("includedFrom", included_from)?; + } + map.serialize_entry("file", &*self.file)?; + map.end() + } +} + impl Debug for SourceRange { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { let SourceRange { begin, end } = self; From 17f13194f882f96d96fd052950f06ea21f2f8d23 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 13:43:01 -0700 Subject: [PATCH 05/13] Implement Serialize for BareSourceLocation --- src/loc.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/loc.rs b/src/loc.rs index 9b4305d..fdbce17 100644 --- a/src/loc.rs +++ b/src/loc.rs @@ -465,6 +465,33 @@ impl SourceLocationField { } } +impl Serialize for BareSourceLocation { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("offset", &self.offset)?; + map.serialize_entry("file", &*self.file)?; + map.serialize_entry("line", &self.line)?; + if let Some(presumed_file) = &self.presumed_file { + map.serialize_entry("presumedFile", &**presumed_file)?; + } + if let Some(presumed_line) = &self.presumed_line { + map.serialize_entry("presumedLine", presumed_line)?; + } + map.serialize_entry("col", &self.col)?; + map.serialize_entry("tokLen", &self.tok_len)?; + if let Some(included_from) = &self.included_from { + map.serialize_entry("includedFrom", included_from)?; + } + if self.is_macro_arg_expansion { + map.serialize_entry("isMacroArgExpansion", &true)?; + } + map.end() + } +} + impl Serialize for IncludedFrom { fn serialize(&self, serializer: S) -> Result where From 2d6041c5ae1b30717be492ae53612b704e08df0e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 13:55:00 -0700 Subject: [PATCH 06/13] Implement Serialize for SourceLocation --- src/loc.rs | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/src/loc.rs b/src/loc.rs index fdbce17..0c6b108 100644 --- a/src/loc.rs +++ b/src/loc.rs @@ -465,6 +465,103 @@ impl SourceLocationField { } } +impl Serialize for SourceLocation { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + fn same_bare_source_location( + spelling_loc: &BareSourceLocation, + expansion_loc: &BareSourceLocation, + ) -> bool { + let BareSourceLocation { + offset: spelling_offset, + file: spelling_file, + line: spelling_line, + presumed_file: spelling_presumed_file, + presumed_line: spelling_presumed_line, + col: spelling_col, + tok_len: spelling_tok_len, + included_from: spelling_included_from, + is_macro_arg_expansion: spelling_is_macro_arg_expansion, + } = spelling_loc; + let BareSourceLocation { + offset: expansion_offset, + file: expansion_file, + line: expansion_line, + presumed_file: expansion_presumed_file, + presumed_line: expansion_presumed_line, + col: expansion_col, + tok_len: expansion_tok_len, + included_from: expansion_included_from, + is_macro_arg_expansion: expansion_is_macro_arg_expansion, + } = expansion_loc; + spelling_offset == expansion_offset + && spelling_file == expansion_file + && spelling_line == expansion_line + && spelling_presumed_file == expansion_presumed_file + && spelling_presumed_line == expansion_presumed_line + && spelling_col == expansion_col + && spelling_tok_len == expansion_tok_len + && spelling_included_from + .as_ref() + .zip(expansion_included_from.as_ref()) + .map_or( + false, + |(spelling_included_from, expansion_included_from)| { + same_included_from(spelling_included_from, expansion_included_from) + }, + ) + && spelling_is_macro_arg_expansion == expansion_is_macro_arg_expansion + } + + fn same_included_from( + spelling_included_from: &IncludedFrom, + expansion_included_from: &IncludedFrom, + ) -> bool { + let IncludedFrom { + included_from: spelling_included_from, + file: spelling_file, + } = spelling_included_from; + let IncludedFrom { + included_from: expansion_included_from, + file: expansion_file, + } = expansion_included_from; + spelling_included_from + .as_ref() + .zip(expansion_included_from.as_ref()) + .map_or( + false, + |(spelling_included_from, expansion_included_from)| { + same_included_from(spelling_included_from, expansion_included_from) + }, + ) + && spelling_file == expansion_file + } + + let serialize_separately = self + .spelling_loc + .as_ref() + .zip(self.expansion_loc.as_ref()) + .map_or(true, |(spelling_loc, expansion_loc)| { + !same_bare_source_location(spelling_loc, expansion_loc) + }); + + if serialize_separately { + let mut map = serializer.serialize_map(None)?; + if let Some(spelling_loc) = &self.spelling_loc { + map.serialize_entry("spellingLoc", spelling_loc)?; + } + if let Some(expansion_loc) = &self.expansion_loc { + map.serialize_entry("expansionLoc", expansion_loc)?; + } + map.end() + } else { + self.spelling_loc.serialize(serializer) + } + } +} + impl Serialize for BareSourceLocation { fn serialize(&self, serializer: S) -> Result where From 5443e5148e81ea601608137bf2f66cf3e9cf002c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 14:04:28 -0700 Subject: [PATCH 07/13] Implement Serialize for SourceRange --- src/loc.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/loc.rs b/src/loc.rs index 0c6b108..9446dd1 100644 --- a/src/loc.rs +++ b/src/loc.rs @@ -465,6 +465,18 @@ impl SourceLocationField { } } +impl Serialize for SourceRange { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("begin", &self.begin)?; + map.serialize_entry("end", &self.end)?; + map.end() + } +} + impl Serialize for SourceLocation { fn serialize(&self, serializer: S) -> Result where From 7b572d927bf9d78941724b99eb757462fa3d8198 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 14:06:57 -0700 Subject: [PATCH 08/13] Clean up nullable IncludedFrom comparisons --- src/loc.rs | 54 ++++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/src/loc.rs b/src/loc.rs index 9446dd1..96cab31 100644 --- a/src/loc.rs +++ b/src/loc.rs @@ -515,40 +515,34 @@ impl Serialize for SourceLocation { && spelling_presumed_line == expansion_presumed_line && spelling_col == expansion_col && spelling_tok_len == expansion_tok_len - && spelling_included_from - .as_ref() - .zip(expansion_included_from.as_ref()) - .map_or( - false, - |(spelling_included_from, expansion_included_from)| { - same_included_from(spelling_included_from, expansion_included_from) - }, - ) + && same_opt_included_from( + spelling_included_from.as_ref(), + expansion_included_from.as_ref(), + ) && spelling_is_macro_arg_expansion == expansion_is_macro_arg_expansion } - fn same_included_from( - spelling_included_from: &IncludedFrom, - expansion_included_from: &IncludedFrom, + fn same_opt_included_from( + spelling_included_from: Option<&IncludedFrom>, + expansion_included_from: Option<&IncludedFrom>, ) -> bool { - let IncludedFrom { - included_from: spelling_included_from, - file: spelling_file, - } = spelling_included_from; - let IncludedFrom { - included_from: expansion_included_from, - file: expansion_file, - } = expansion_included_from; - spelling_included_from - .as_ref() - .zip(expansion_included_from.as_ref()) - .map_or( - false, - |(spelling_included_from, expansion_included_from)| { - same_included_from(spelling_included_from, expansion_included_from) - }, - ) - && spelling_file == expansion_file + spelling_included_from.zip(expansion_included_from).map_or( + false, + |(spelling_included_from, expansion_included_from)| { + let IncludedFrom { + included_from: spelling_included_from, + file: spelling_file, + } = spelling_included_from; + let IncludedFrom { + included_from: expansion_included_from, + file: expansion_file, + } = expansion_included_from; + same_opt_included_from( + spelling_included_from.as_ref().map(Box::as_ref), + expansion_included_from.as_ref().map(Box::as_ref), + ) && spelling_file == expansion_file + }, + ) } let serialize_separately = self From 951450c9925d2b5f0a03c92e627b54277908978f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 14:13:30 -0700 Subject: [PATCH 09/13] Match JSONNodeDumper's deduplication logic --- src/dedup.rs | 23 +++++++++++++++++++++++ src/lib.rs | 2 ++ src/loc.rs | 23 +++++++++++++++++++++-- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/dedup.rs diff --git a/src/dedup.rs b/src/dedup.rs new file mode 100644 index 0000000..edb3a95 --- /dev/null +++ b/src/dedup.rs @@ -0,0 +1,23 @@ +use std::cell::Cell; + +thread_local! { + static REFCOUNT: Cell = Cell::new(0); +} + +pub(crate) struct Guard { + _private: (), +} + +pub(crate) fn activate() -> Guard { + REFCOUNT.with(|refcount| refcount.set(refcount.get() + 1)); + Guard { _private: () } +} + +impl Drop for Guard { + fn drop(&mut self) { + let prev = REFCOUNT.with(|refcount| refcount.replace(refcount.get() - 1)); + if prev == 1 { + crate::loc::thread_local_reset(); + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 8c58cc2..e376a4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -394,6 +394,7 @@ clippy::ptr_arg )] +mod dedup; mod deserializer; mod id; mod intern; @@ -532,6 +533,7 @@ where where S: Serializer, { + let _dedup = dedup::activate(); let mut map = serializer.serialize_map(None)?; map.serialize_entry("id", &self.id)?; //FIXME &self.kind; diff --git a/src/loc.rs b/src/loc.rs index 96cab31..7ede7d4 100644 --- a/src/loc.rs +++ b/src/loc.rs @@ -575,8 +575,27 @@ impl Serialize for BareSourceLocation { { let mut map = serializer.serialize_map(None)?; map.serialize_entry("offset", &self.offset)?; - map.serialize_entry("file", &*self.file)?; - map.serialize_entry("line", &self.line)?; + if LAST_LOC_FILENAME.with(|last_loc_filename| { + let mut last_loc_filename = last_loc_filename.borrow_mut(); + if *last_loc_filename == self.file { + false + } else { + *last_loc_filename = Arc::clone(&self.file); + true + } + }) { + map.serialize_entry("file", &*self.file)?; + map.serialize_entry("line", &self.line)?; + } else if LAST_LOC_LINE.with(|last_loc_line| { + if last_loc_line.get() == self.line { + false + } else { + last_loc_line.set(self.line); + true + } + }) { + map.serialize_entry("line", &self.line)?; + } if let Some(presumed_file) = &self.presumed_file { map.serialize_entry("presumedFile", &**presumed_file)?; } From 86ffdb3801e81a89cfe82285af522fc373669cd5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 15:30:09 -0700 Subject: [PATCH 10/13] Handle serialization of the "kind" field --- src/lib.rs | 4 +- src/serializer.rs | 292 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 src/serializer.rs diff --git a/src/lib.rs b/src/lib.rs index e376a4a..e0e0dbc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -400,11 +400,13 @@ mod id; mod intern; mod kind; mod loc; +mod serializer; extern crate serde; use crate::deserializer::NodeDeserializer; use crate::kind::AnyKind; +use crate::serializer::NodeSerializer; use serde::de::{Deserialize, Deserializer, MapAccess, Visitor}; use serde::ser::{Serialize, SerializeMap, Serializer}; use std::fmt; @@ -536,7 +538,7 @@ where let _dedup = dedup::activate(); let mut map = serializer.serialize_map(None)?; map.serialize_entry("id", &self.id)?; - //FIXME &self.kind; + T::serialize(&self.kind, NodeSerializer::new(&mut map))?; map.serialize_entry("inner", &self.inner)?; map.end() } diff --git a/src/serializer.rs b/src/serializer.rs new file mode 100644 index 0000000..51e8774 --- /dev/null +++ b/src/serializer.rs @@ -0,0 +1,292 @@ +use serde::ser::{ + Error, Impossible, Serialize, SerializeMap, SerializeStruct, SerializeStructVariant, Serializer, +}; + +pub(crate) struct NodeSerializer<'a, M> { + map: &'a mut M, +} + +impl<'a, M> NodeSerializer<'a, M> { + pub(crate) fn new(map: &'a mut M) -> Self { + NodeSerializer { map } + } +} + +impl<'a, M> Serializer for NodeSerializer<'a, M> +where + M: SerializeMap, +{ + type Ok = (); + type Error = M::Error; + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Self; + type SerializeStruct = Self; + type SerializeStructVariant = Self; + + fn serialize_bool(self, v: bool) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_i8(self, v: i8) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_i16(self, v: i16) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_i32(self, v: i32) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_i64(self, v: i64) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_u8(self, v: u8) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_u16(self, v: u16) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_u32(self, v: u32) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_u64(self, v: u64) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_f32(self, v: f32) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_f64(self, v: f64) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_char(self, v: char) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_str(self, v: &str) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_bytes(self, v: &[u8]) -> Result { + let _ = v; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_none(self) -> Result { + Ok(()) + } + + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + T::serialize(value, self) + } + + fn serialize_unit(self) -> Result { + Ok(()) + } + + fn serialize_unit_struct(self, name: &'static str) -> Result { + let _ = name; + Ok(()) + } + + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { + let _ = name; + let _ = variant_index; + self.map.serialize_entry("kind", variant) + } + + fn serialize_newtype_struct( + self, + name: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + let _ = name; + T::serialize(value, self) + } + + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + let _ = name; + let _ = variant_index; + self.map.serialize_entry("kind", variant)?; + T::serialize(value, self) + } + + fn serialize_seq(self, len: Option) -> Result { + let _ = len; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_tuple(self, len: usize) -> Result { + let _ = len; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + let _ = name; + let _ = len; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + let _ = name; + let _ = variant_index; + let _ = variant; + let _ = len; + Err(Error::custom("unsupported \"kind\"")) + } + + fn serialize_map(self, len: Option) -> Result { + let _ = len; + Ok(self) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + let _ = name; + let _ = len; + Ok(self) + } + + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + let _ = name; + let _ = variant_index; + let _ = len; + self.map.serialize_entry("kind", variant)?; + Ok(self) + } +} + +impl<'a, M> SerializeMap for NodeSerializer<'a, M> +where + M: SerializeMap, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.map.serialize_key(key) + } + + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.map.serialize_value(value) + } + + fn serialize_entry(&mut self, key: &K, value: &V) -> Result<(), Self::Error> + where + K: ?Sized + Serialize, + V: ?Sized + Serialize, + { + self.map.serialize_entry(key, value) + } + + fn end(self) -> Result<(), Self::Error> { + Ok(()) + } +} + +impl<'a, M> SerializeStruct for NodeSerializer<'a, M> +where + M: SerializeMap, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.map.serialize_entry(key, value) + } + + fn end(self) -> Result<(), Self::Error> { + Ok(()) + } +} + +impl<'a, M> SerializeStructVariant for NodeSerializer<'a, M> +where + M: SerializeMap, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.map.serialize_entry(key, value) + } + + fn end(self) -> Result<(), Self::Error> { + Ok(()) + } +} From c92b10faf7d54ddd2cf774239d9adba531738be6 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 16:24:14 -0700 Subject: [PATCH 11/13] Omit empty inner arrays --- src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index e0e0dbc..4b4cd0e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -539,7 +539,9 @@ where let mut map = serializer.serialize_map(None)?; map.serialize_entry("id", &self.id)?; T::serialize(&self.kind, NodeSerializer::new(&mut map))?; - map.serialize_entry("inner", &self.inner)?; + if !self.inner.is_empty() { + map.serialize_entry("inner", &self.inner)?; + } map.end() } } From 732ee5ba4b240ceb7b5ecfaeaa088b802312741e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 16:28:45 -0700 Subject: [PATCH 12/13] Raise minimum supported compiler to rustc 1.46 Required by the use of Option::zip. error[E0658]: use of unstable library feature 'option_zip' --> src/loc.rs:551:14 | 551 | .zip(self.expansion_loc.as_ref()) | ^^^ | = note: see issue #70086 for more information error[E0658]: use of unstable library feature 'option_zip' --> src/loc.rs:529:36 | 529 | spelling_included_from.zip(expansion_included_from).map_or( | ^^^ | = note: see issue #70086 for more information --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fcb93f6..28cab0b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: strategy: fail-fast: false matrix: - rust: [beta, stable, 1.45.0] + rust: [beta, stable, 1.46.0] steps: - uses: actions/checkout@v2 - uses: dtolnay/rust-toolchain@master From b194e2ff4b4008a783477a9bd93fd3520538f1bb Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 28 Apr 2021 16:33:15 -0700 Subject: [PATCH 13/13] Ignore blocks_in_if_conditions clippy style lint error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` --> src/loc.rs:578:55 | 578 | if LAST_LOC_FILENAME.with(|last_loc_filename| { | _______________________________________________________^ 579 | | let mut last_loc_filename = last_loc_filename.borrow_mut(); 580 | | if *last_loc_filename == self.file { 581 | | false ... | 585 | | } 586 | | }) { | |_________^ | = note: `-D clippy::blocks-in-if-conditions` implied by `-D clippy::all` = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_if_conditions error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` --> src/loc.rs:589:54 | 589 | } else if LAST_LOC_LINE.with(|last_loc_line| { | ______________________________________________________^ 590 | | if last_loc_line.get() == self.line { 591 | | false 592 | | } else { ... | 595 | | } 596 | | }) { | |_________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_if_conditions --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 4b4cd0e..63d11a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -388,6 +388,7 @@ #![doc(html_root_url = "https://docs.rs/clang-ast/0.1.2")] #![allow( + clippy::blocks_in_if_conditions, clippy::let_underscore_drop, clippy::must_use_candidate, clippy::option_if_let_else,