From 2308ad864dddf044714d213767fe4b8af18c2cb6 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Fri, 4 Dec 2020 14:23:32 -0800 Subject: [PATCH] Support parsing 'unsafe extern "C++"' This was added in Rust 1.48 by https://github.com/rust-lang/rust/pull/75857 --- src/gen/clone.rs | 1 + src/gen/debug.rs | 1 + src/gen/eq.rs | 2 +- src/gen/fold.rs | 1 + src/gen/hash.rs | 1 + src/item.rs | 4 ++++ tests/debug/gen.rs | 12 ++++++++++++ 7 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/gen/clone.rs b/src/gen/clone.rs index 37670f2227..2cf9f76810 100644 --- a/src/gen/clone.rs +++ b/src/gen/clone.rs @@ -1121,6 +1121,7 @@ impl Clone for ItemForeignMod { fn clone(&self) -> Self { ItemForeignMod { attrs: self.attrs.clone(), + unsafety: self.unsafety.clone(), abi: self.abi.clone(), brace_token: self.brace_token.clone(), items: self.items.clone(), diff --git a/src/gen/debug.rs b/src/gen/debug.rs index 3efa2788fe..b495054386 100644 --- a/src/gen/debug.rs +++ b/src/gen/debug.rs @@ -1599,6 +1599,7 @@ impl Debug for ItemForeignMod { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { let mut formatter = formatter.debug_struct("ItemForeignMod"); formatter.field("attrs", &self.attrs); + formatter.field("unsafety", &self.unsafety); formatter.field("abi", &self.abi); formatter.field("brace_token", &self.brace_token); formatter.field("items", &self.items); diff --git a/src/gen/eq.rs b/src/gen/eq.rs index e6e85323e1..df50bc8a08 100644 --- a/src/gen/eq.rs +++ b/src/gen/eq.rs @@ -1128,7 +1128,7 @@ impl Eq for ItemForeignMod {} #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] impl PartialEq for ItemForeignMod { fn eq(&self, other: &Self) -> bool { - self.attrs == other.attrs && self.abi == other.abi && self.items == other.items + self.attrs == other.attrs && self.unsafety == other.unsafety && self.abi == other.abi && self.items == other.items } } #[cfg(feature = "full")] diff --git a/src/gen/fold.rs b/src/gen/fold.rs index d9dd32a420..d2d8e8e354 100644 --- a/src/gen/fold.rs +++ b/src/gen/fold.rs @@ -1955,6 +1955,7 @@ where { ItemForeignMod { attrs: FoldHelper::lift(node.attrs, |it| f.fold_attribute(it)), + unsafety: (node.unsafety).map(|it| Token![unsafe](tokens_helper(f, &it.span))), abi: f.fold_abi(node.abi), brace_token: Brace(tokens_helper(f, &node.brace_token.span)), items: FoldHelper::lift(node.items, |it| f.fold_foreign_item(it)), diff --git a/src/gen/hash.rs b/src/gen/hash.rs index 7247174a78..881d47061a 100644 --- a/src/gen/hash.rs +++ b/src/gen/hash.rs @@ -1482,6 +1482,7 @@ impl Hash for ItemForeignMod { H: Hasher, { self.attrs.hash(state); + self.unsafety.hash(state); self.abi.hash(state); self.items.hash(state); } diff --git a/src/item.rs b/src/item.rs index 4041c53950..5c65dd3ce2 100644 --- a/src/item.rs +++ b/src/item.rs @@ -150,6 +150,7 @@ ast_struct! { #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemForeignMod { pub attrs: Vec, + pub unsafety: Option, pub abi: Abi, pub brace_token: token::Brace, pub items: Vec, @@ -1620,6 +1621,7 @@ pub mod parsing { impl Parse for ItemForeignMod { fn parse(input: ParseStream) -> Result { let outer_attrs = input.call(Attribute::parse_outer)?; + let unsafety = input.parse()?; let abi: Abi = input.parse()?; let content; @@ -1632,6 +1634,7 @@ pub mod parsing { Ok(ItemForeignMod { attrs: private::attrs(outer_attrs, inner_attrs), + unsafety, abi, brace_token, items, @@ -2775,6 +2778,7 @@ mod printing { impl ToTokens for ItemForeignMod { fn to_tokens(&self, tokens: &mut TokenStream) { tokens.append_all(self.attrs.outer()); + self.unsafety.to_tokens(tokens); self.abi.to_tokens(tokens); self.brace_token.surround(tokens, |tokens| { tokens.append_all(self.attrs.inner()); diff --git a/tests/debug/gen.rs b/tests/debug/gen.rs index 85a1a39079..3864d2dd8e 100644 --- a/tests/debug/gen.rs +++ b/tests/debug/gen.rs @@ -3027,6 +3027,18 @@ impl Debug for Lite { if !_val.attrs.is_empty() { formatter.field("attrs", Lite(&_val.attrs)); } + if let Some(val) = &_val.unsafety { + #[derive(RefCast)] + #[repr(transparent)] + struct Print(syn::token::Unsafe); + impl Debug for Print { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Some")?; + Ok(()) + } + } + formatter.field("unsafety", Print::ref_cast(val)); + } formatter.field("abi", Lite(&_val.abi)); if !_val.items.is_empty() { formatter.field("items", Lite(&_val.items));