diff --git a/src/gen/clone.rs b/src/gen/clone.rs index be2b698422..f0b69629e7 100644 --- a/src/gen/clone.rs +++ b/src/gen/clone.rs @@ -920,6 +920,7 @@ impl Clone for crate::ForeignItemStatic { crate::ForeignItemStatic { attrs: self.attrs.clone(), vis: self.vis.clone(), + unsafety: self.unsafety.clone(), static_token: self.static_token.clone(), mutability: self.mutability.clone(), ident: self.ident.clone(), @@ -2133,6 +2134,16 @@ impl Clone for crate::UnOp { } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))] +impl Clone for crate::Unsafety { + fn clone(&self) -> Self { + match self { + crate::Unsafety::Safe(v0) => crate::Unsafety::Safe(v0.clone()), + crate::Unsafety::Unsafe(v0) => crate::Unsafety::Unsafe(v0.clone()), + } + } +} +#[cfg(feature = "full")] +#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))] impl Clone for crate::UseGlob { fn clone(&self) -> Self { crate::UseGlob { diff --git a/src/gen/debug.rs b/src/gen/debug.rs index bf0784d1c4..feda4ad602 100644 --- a/src/gen/debug.rs +++ b/src/gen/debug.rs @@ -1382,6 +1382,7 @@ impl crate::ForeignItemStatic { let mut formatter = formatter.debug_struct(name); formatter.field("attrs", &self.attrs); formatter.field("vis", &self.vis); + formatter.field("unsafety", &self.unsafety); formatter.field("static_token", &self.static_token); formatter.field("mutability", &self.mutability); formatter.field("ident", &self.ident); @@ -3067,6 +3068,25 @@ impl Debug for crate::UnOp { } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] +impl Debug for crate::Unsafety { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Unsafety::")?; + match self { + crate::Unsafety::Safe(v0) => { + let mut formatter = formatter.debug_tuple("Safe"); + formatter.field(v0); + formatter.finish() + } + crate::Unsafety::Unsafe(v0) => { + let mut formatter = formatter.debug_tuple("Unsafe"); + formatter.field(v0); + formatter.finish() + } + } + } +} +#[cfg(feature = "full")] +#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl Debug for crate::UseGlob { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { let mut formatter = formatter.debug_struct("UseGlob"); diff --git a/src/gen/eq.rs b/src/gen/eq.rs index 5ba15722b7..20078677d2 100644 --- a/src/gen/eq.rs +++ b/src/gen/eq.rs @@ -929,8 +929,8 @@ impl Eq for crate::ForeignItemStatic {} impl PartialEq for crate::ForeignItemStatic { fn eq(&self, other: &Self) -> bool { self.attrs == other.attrs && self.vis == other.vis - && self.mutability == other.mutability && self.ident == other.ident - && self.ty == other.ty + && self.unsafety == other.unsafety && self.mutability == other.mutability + && self.ident == other.ident && self.ty == other.ty } } #[cfg(feature = "full")] @@ -2153,6 +2153,20 @@ impl PartialEq for crate::UnOp { } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] +impl Eq for crate::Unsafety {} +#[cfg(feature = "full")] +#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] +impl PartialEq for crate::Unsafety { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (crate::Unsafety::Safe(_), crate::Unsafety::Safe(_)) => true, + (crate::Unsafety::Unsafe(_), crate::Unsafety::Unsafe(_)) => true, + _ => false, + } + } +} +#[cfg(feature = "full")] +#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl Eq for crate::UseGlob {} #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] diff --git a/src/gen/fold.rs b/src/gen/fold.rs index b71421f47a..99ec35f807 100644 --- a/src/gen/fold.rs +++ b/src/gen/fold.rs @@ -965,6 +965,11 @@ pub trait Fold { } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + fn fold_unsafety(&mut self, i: crate::Unsafety) -> crate::Unsafety { + fold_unsafety(self, i) + } + #[cfg(feature = "full")] + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] fn fold_use_glob(&mut self, i: crate::UseGlob) -> crate::UseGlob { fold_use_glob(self, i) } @@ -2148,6 +2153,7 @@ where crate::ForeignItemStatic { attrs: f.fold_attributes(node.attrs), vis: f.fold_visibility(node.vis), + unsafety: (node.unsafety).map(|it| f.fold_unsafety(it)), static_token: node.static_token, mutability: f.fold_static_mutability(node.mutability), ident: f.fold_ident(node.ident), @@ -3274,7 +3280,7 @@ where crate::Signature { constness: node.constness, asyncness: node.asyncness, - unsafety: node.unsafety, + unsafety: (node.unsafety).map(|it| f.fold_unsafety(it)), abi: (node.abi).map(|it| f.fold_abi(it)), fn_token: node.fn_token, ident: f.fold_ident(node.ident), @@ -3734,6 +3740,17 @@ where } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] +pub fn fold_unsafety(f: &mut F, node: crate::Unsafety) -> crate::Unsafety +where + F: Fold + ?Sized, +{ + match node { + crate::Unsafety::Safe(_binding_0) => crate::Unsafety::Safe(_binding_0), + crate::Unsafety::Unsafe(_binding_0) => crate::Unsafety::Unsafe(_binding_0), + } +} +#[cfg(feature = "full")] +#[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub fn fold_use_glob(f: &mut F, node: crate::UseGlob) -> crate::UseGlob where F: Fold + ?Sized, diff --git a/src/gen/hash.rs b/src/gen/hash.rs index 508af526c1..2826b7963c 100644 --- a/src/gen/hash.rs +++ b/src/gen/hash.rs @@ -1203,6 +1203,7 @@ impl Hash for crate::ForeignItemStatic { { self.attrs.hash(state); self.vis.hash(state); + self.unsafety.hash(state); self.mutability.hash(state); self.ident.hash(state); self.ty.hash(state); @@ -2711,6 +2712,23 @@ impl Hash for crate::UnOp { } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] +impl Hash for crate::Unsafety { + fn hash(&self, state: &mut H) + where + H: Hasher, + { + match self { + crate::Unsafety::Safe(_) => { + state.write_u8(0u8); + } + crate::Unsafety::Unsafe(_) => { + state.write_u8(1u8); + } + } + } +} +#[cfg(feature = "full")] +#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl Hash for crate::UseGlob { fn hash(&self, _state: &mut H) where diff --git a/src/gen/token.css b/src/gen/token.css index ed82ae1502..d1055689b5 100644 --- a/src/gen/token.css +++ b/src/gen/token.css @@ -70,6 +70,7 @@ a.struct[title="struct syn::token::RArrow"], a.struct[title="struct syn::token::Raw"], a.struct[title="struct syn::token::Ref"], a.struct[title="struct syn::token::Return"], +a.struct[title="struct syn::token::Safe"], a.struct[title="struct syn::token::SelfType"], a.struct[title="struct syn::token::SelfValue"], a.struct[title="struct syn::token::Semi"], @@ -175,6 +176,7 @@ a.struct[title="struct syn::token::RArrow"]::before, a.struct[title="struct syn::token::Raw"]::before, a.struct[title="struct syn::token::Ref"]::before, a.struct[title="struct syn::token::Return"]::before, +a.struct[title="struct syn::token::Safe"]::before, a.struct[title="struct syn::token::SelfType"]::before, a.struct[title="struct syn::token::SelfValue"]::before, a.struct[title="struct syn::token::Semi"]::before, @@ -496,6 +498,10 @@ a.struct[title="struct syn::token::Return"]::before { content: "Token![return]"; } +a.struct[title="struct syn::token::Safe"]::before { + content: "Token![safe]"; +} + a.struct[title="struct syn::token::SelfType"]::before { content: "Token![Self]"; } @@ -718,6 +724,7 @@ a.struct[title="struct syn::token::Pub"]::after, a.struct[title="struct syn::token::Raw"]::after, a.struct[title="struct syn::token::Ref"]::after, a.struct[title="struct syn::token::Return"]::after, +a.struct[title="struct syn::token::Safe"]::after, a.struct[title="struct syn::token::Static"]::after, a.struct[title="struct syn::token::Struct"]::after, a.struct[title="struct syn::token::Super"]::after, diff --git a/src/gen/visit.rs b/src/gen/visit.rs index cd258fcde1..d20c7bf47d 100644 --- a/src/gen/visit.rs +++ b/src/gen/visit.rs @@ -884,6 +884,11 @@ pub trait Visit<'ast> { } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + fn visit_unsafety(&mut self, i: &'ast crate::Unsafety) { + visit_unsafety(self, i); + } + #[cfg(feature = "full")] + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] fn visit_use_glob(&mut self, i: &'ast crate::UseGlob) { visit_use_glob(self, i); } @@ -2178,6 +2183,9 @@ where v.visit_attribute(it); } v.visit_visibility(&node.vis); + if let Some(it) = &node.unsafety { + v.visit_unsafety(it); + } skip!(node.static_token); v.visit_static_mutability(&node.mutability); v.visit_ident(&node.ident); @@ -3320,7 +3328,9 @@ where { skip!(node.constness); skip!(node.asyncness); - skip!(node.unsafety); + if let Some(it) = &node.unsafety { + v.visit_unsafety(it); + } if let Some(it) = &node.abi { v.visit_abi(it); } @@ -3783,6 +3793,21 @@ where } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] +pub fn visit_unsafety<'ast, V>(v: &mut V, node: &'ast crate::Unsafety) +where + V: Visit<'ast> + ?Sized, +{ + match node { + crate::Unsafety::Safe(_binding_0) => { + skip!(_binding_0); + } + crate::Unsafety::Unsafe(_binding_0) => { + skip!(_binding_0); + } + } +} +#[cfg(feature = "full")] +#[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub fn visit_use_glob<'ast, V>(v: &mut V, node: &'ast crate::UseGlob) where V: Visit<'ast> + ?Sized, diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs index 6588182c4f..30ab8d0522 100644 --- a/src/gen/visit_mut.rs +++ b/src/gen/visit_mut.rs @@ -894,6 +894,11 @@ pub trait VisitMut { } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + fn visit_unsafety_mut(&mut self, i: &mut crate::Unsafety) { + visit_unsafety_mut(self, i); + } + #[cfg(feature = "full")] + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] fn visit_use_glob_mut(&mut self, i: &mut crate::UseGlob) { visit_use_glob_mut(self, i); } @@ -2083,6 +2088,9 @@ where { v.visit_attributes_mut(&mut node.attrs); v.visit_visibility_mut(&mut node.vis); + if let Some(it) = &mut node.unsafety { + v.visit_unsafety_mut(it); + } skip!(node.static_token); v.visit_static_mutability_mut(&mut node.mutability); v.visit_ident_mut(&mut node.ident); @@ -3159,7 +3167,9 @@ where { skip!(node.constness); skip!(node.asyncness); - skip!(node.unsafety); + if let Some(it) = &mut node.unsafety { + v.visit_unsafety_mut(it); + } if let Some(it) = &mut node.abi { v.visit_abi_mut(it); } @@ -3607,6 +3617,21 @@ where } #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] +pub fn visit_unsafety_mut(v: &mut V, node: &mut crate::Unsafety) +where + V: VisitMut + ?Sized, +{ + match node { + crate::Unsafety::Safe(_binding_0) => { + skip!(_binding_0); + } + crate::Unsafety::Unsafe(_binding_0) => { + skip!(_binding_0); + } + } +} +#[cfg(feature = "full")] +#[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub fn visit_use_glob_mut(v: &mut V, node: &mut crate::UseGlob) where V: VisitMut + ?Sized, diff --git a/src/item.rs b/src/item.rs index d977609b16..6c13c88647 100644 --- a/src/item.rs +++ b/src/item.rs @@ -558,6 +558,7 @@ ast_struct! { pub struct ForeignItemStatic { pub attrs: Vec, pub vis: Visibility, + pub unsafety: Option, pub static_token: Token![static], pub mutability: StaticMutability, pub ident: Ident, @@ -796,7 +797,7 @@ ast_struct! { pub struct Signature { pub constness: Option, pub asyncness: Option, - pub unsafety: Option, + pub unsafety: Option, pub abi: Option, pub fn_token: Token![fn], pub ident: Ident, @@ -819,6 +820,15 @@ impl Signature { } } +ast_enum! { + /// The unsafety of an item. Can be either `safe` or `unsafe`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub enum Unsafety { + Safe(Token![safe]), + Unsafe(Token![unsafe]) + } +} + ast_enum_of_structs! { /// An argument in a function signature: the `n: usize` in `fn f(n: usize)`. #[cfg_attr(docsrs, doc(cfg(feature = "full")))] @@ -919,7 +929,7 @@ pub(crate) mod parsing { ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver, Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, - TraitItemType, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic, + TraitItemType, Unsafety, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic, }; use crate::lifetime::Lifetime; use crate::lit::LitStr; @@ -956,8 +966,7 @@ pub(crate) mod parsing { let vis: Visibility = ahead.parse()?; let lookahead = ahead.lookahead1(); - let allow_safe = false; - let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead, allow_safe) { + let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) { let vis: Visibility = input.parse()?; let sig: Signature = input.parse()?; if input.peek(Token![;]) { @@ -1494,12 +1503,11 @@ pub(crate) mod parsing { } } - fn peek_signature(input: ParseStream, allow_safe: bool) -> bool { + fn peek_signature(input: ParseStream) -> bool { let fork = input.fork(); fork.parse::>().is_ok() && fork.parse::>().is_ok() - && ((allow_safe - && token::parsing::peek_keyword(fork.cursor(), "safe") + && ((token::parsing::peek_keyword(fork.cursor(), "safe") && token::parsing::keyword(&fork, "safe").is_ok()) || fork.parse::>().is_ok()) && fork.parse::>().is_ok() @@ -1509,37 +1517,26 @@ pub(crate) mod parsing { #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] impl Parse for Signature { fn parse(input: ParseStream) -> Result { - let allow_safe = false; - parse_signature(input, allow_safe).map(Option::unwrap) - } - } - - fn parse_signature(input: ParseStream, allow_safe: bool) -> Result> { - let constness: Option = input.parse()?; - let asyncness: Option = input.parse()?; - let unsafety: Option = input.parse()?; - let safe = allow_safe - && unsafety.is_none() - && token::parsing::peek_keyword(input.cursor(), "safe"); - if safe { - token::parsing::keyword(input, "safe")?; - } - let abi: Option = input.parse()?; - let fn_token: Token![fn] = input.parse()?; - let ident: Ident = input.parse()?; - let mut generics: Generics = input.parse()?; + let constness: Option = input.parse()?; + let asyncness: Option = input.parse()?; + let unsafety: Option = if peek_unsafety(input) { + Some(input.parse()?) + } else { + None + }; + let abi: Option = input.parse()?; + let fn_token: Token![fn] = input.parse()?; + let ident: Ident = input.parse()?; + let mut generics: Generics = input.parse()?; - let content; - let paren_token = parenthesized!(content in input); - let (inputs, variadic) = parse_fn_args(&content)?; + let content; + let paren_token = parenthesized!(content in input); + let (inputs, variadic) = parse_fn_args(&content)?; - let output: ReturnType = input.parse()?; - generics.where_clause = input.parse()?; + let output: ReturnType = input.parse()?; + generics.where_clause = input.parse()?; - Ok(if safe { - None - } else { - Some(Signature { + Ok(Signature { constness, asyncness, unsafety, @@ -1552,7 +1549,31 @@ pub(crate) mod parsing { variadic, output, }) - }) + } + } + + fn peek_unsafety(input: ParseStream) -> bool { + input.peek(Token![safe]) || input.peek(Token![unsafe]) + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for Unsafety { + fn parse(input: ParseStream) -> Result { + let safety: Option = input.parse()?; + let unsafety: Option = input.parse()?; + match (safety, unsafety) { + (Some(safety), None) => Ok(Unsafety::Safe(safety)), + (None, Some(unsafety)) => Ok(Unsafety::Unsafe(unsafety)), + (None, None) => Err(Error::new( + input.span(), + "Expected either `safe` or `unsafe`", + )), + (Some(safety), Some(unsafety)) => Err(Error::new( + safety.span.join(unsafety.span).unwrap_or(safety.span), + "Expected either `safe` or `unsafe` but got both", + )), + } + } } #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] @@ -1848,11 +1869,9 @@ pub(crate) mod parsing { let vis: Visibility = ahead.parse()?; let lookahead = ahead.lookahead1(); - let allow_safe = true; - let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead, allow_safe) { + let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) { let vis: Visibility = input.parse()?; - let sig = parse_signature(input, allow_safe)?; - let has_safe = sig.is_none(); + let sig: Signature = input.parse()?; let has_body = input.peek(token::Brace); let semi_token: Option = if has_body { let content; @@ -1863,13 +1882,13 @@ pub(crate) mod parsing { } else { Some(input.parse()?) }; - if has_safe || has_body { + if has_body { Ok(ForeignItem::Verbatim(verbatim::between(&begin, input))) } else { Ok(ForeignItem::Fn(ForeignItemFn { attrs: Vec::new(), vis, - sig: sig.unwrap(), + sig, semi_token: semi_token.unwrap(), })) } @@ -1879,12 +1898,11 @@ pub(crate) mod parsing { && ahead.peek2(Token![static])) { let vis = input.parse()?; - let unsafety: Option = input.parse()?; - let safe = - unsafety.is_none() && token::parsing::peek_keyword(input.cursor(), "safe"); - if safe { - token::parsing::keyword(input, "safe")?; - } + let unsafety = if peek_unsafety(input) { + Some(input.parse()?) + } else { + None + }; let static_token = input.parse()?; let mutability = input.parse()?; let ident = input.parse()?; @@ -1896,12 +1914,13 @@ pub(crate) mod parsing { input.parse::()?; } let semi_token: Token![;] = input.parse()?; - if unsafety.is_some() || safe || has_value { + if has_value { Ok(ForeignItem::Verbatim(verbatim::between(&begin, input))) } else { Ok(ForeignItem::Static(ForeignItemStatic { attrs: Vec::new(), vis, + unsafety, static_token, mutability, ident, @@ -1960,6 +1979,7 @@ pub(crate) mod parsing { Ok(ForeignItemStatic { attrs: input.call(Attribute::parse_outer)?, vis: input.parse()?, + unsafety: if peek_unsafety(input) { Some(input.parse()?) } else { None }, static_token: input.parse()?, mutability: input.parse()?, ident: input.parse()?, @@ -2339,8 +2359,7 @@ pub(crate) mod parsing { let ahead = input.fork(); let lookahead = ahead.lookahead1(); - let allow_safe = false; - let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead, allow_safe) { + let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) { input.parse().map(TraitItem::Fn) } else if lookahead.peek(Token![const]) { let const_token: Token![const] = ahead.parse()?; @@ -2677,8 +2696,7 @@ pub(crate) mod parsing { None }; - let allow_safe = false; - let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead, allow_safe) { + let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) { let allow_omitted_body = true; if let Some(item) = parse_impl_item_fn(input, allow_omitted_body)? { Ok(ImplItem::Fn(item)) @@ -2941,8 +2959,8 @@ mod printing { ImplItemFn, ImplItemMacro, ImplItemType, ItemConst, ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver, Signature, StaticMutability, - TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, UseGlob, UseGroup, UseName, - UsePath, UseRename, Variadic, + TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, Unsafety, UseGlob, UseGroup, + UseName, UsePath, UseRename, Variadic, }; use crate::mac::MacroDelimiter; use crate::path; @@ -3381,6 +3399,9 @@ mod printing { fn to_tokens(&self, tokens: &mut TokenStream) { tokens.append_all(self.attrs.outer()); self.vis.to_tokens(tokens); + if let Some(unsafety) = &self.unsafety { + unsafety.to_tokens(tokens); + } self.static_token.to_tokens(tokens); self.mutability.to_tokens(tokens); self.ident.to_tokens(tokens); @@ -3436,6 +3457,16 @@ mod printing { } } + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for Unsafety { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Unsafety::Unsafe(t) => t.to_tokens(tokens), + Unsafety::Safe(t) => t.to_tokens(tokens), + } + } + } + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] impl ToTokens for Receiver { fn to_tokens(&self, tokens: &mut TokenStream) { diff --git a/src/lib.rs b/src/lib.rs index 28a6dd6d79..4c9c7c3e2c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -431,7 +431,7 @@ pub use crate::item::{ ItemConst, ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver, Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, - TraitItemType, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic, + TraitItemType, Unsafety, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic, }; mod lifetime; diff --git a/src/token.rs b/src/token.rs index 8d63a4111b..e11813c8fd 100644 --- a/src/token.rs +++ b/src/token.rs @@ -726,6 +726,7 @@ define_keywords! { "raw" pub struct Raw "ref" pub struct Ref "return" pub struct Return + "safe" pub struct Safe "Self" pub struct SelfType "self" pub struct SelfValue "static" pub struct Static @@ -905,6 +906,7 @@ macro_rules! Token { [raw] => { $crate::token::Raw }; [ref] => { $crate::token::Ref }; [return] => { $crate::token::Return }; + [safe] => { $crate::token::Safe }; [Self] => { $crate::token::SelfType }; [self] => { $crate::token::SelfValue }; [static] => { $crate::token::Static }; diff --git a/syn.json b/syn.json index 60f7ac42db..3a261f28de 100644 --- a/syn.json +++ b/syn.json @@ -2291,6 +2291,11 @@ "vis": { "syn": "Visibility" }, + "unsafety": { + "option": { + "syn": "Unsafety" + } + }, "static_token": { "token": "Static" }, @@ -4448,7 +4453,7 @@ }, "unsafety": { "option": { - "token": "Unsafe" + "syn": "Unsafety" } }, "abi": { @@ -5294,6 +5299,26 @@ }, "exhaustive": false }, + { + "ident": "Unsafety", + "features": { + "any": [ + "full" + ] + }, + "variants": { + "Safe": [ + { + "token": "Safe" + } + ], + "Unsafe": [ + { + "token": "Unsafe" + } + ] + } + }, { "ident": "UseGlob", "features": { @@ -5654,6 +5679,7 @@ "Raw": "raw", "Ref": "ref", "Return": "return", + "Safe": "safe", "SelfType": "Self", "SelfValue": "self", "Semi": ";", diff --git a/tests/debug/gen.rs b/tests/debug/gen.rs index c0d37b791d..8f01c17445 100644 --- a/tests/debug/gen.rs +++ b/tests/debug/gen.rs @@ -1919,6 +1919,20 @@ impl Debug for Lite { formatter.field("attrs", Lite(&_val.attrs)); } formatter.field("vis", Lite(&_val.vis)); + if let Some(val) = &_val.unsafety { + #[derive(RefCast)] + #[repr(transparent)] + struct Print(syn::Unsafety); + impl Debug for Print { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Some(")?; + Debug::fmt(Lite(&self.0), formatter)?; + formatter.write_str(")")?; + Ok(()) + } + } + formatter.field("unsafety", Print::ref_cast(val)); + } match _val.mutability { syn::StaticMutability::None => {} _ => { @@ -1992,6 +2006,20 @@ impl Debug for Lite { formatter.field("attrs", Lite(&self.value.attrs)); } formatter.field("vis", Lite(&self.value.vis)); + if let Some(val) = &self.value.unsafety { + #[derive(RefCast)] + #[repr(transparent)] + struct Print(syn::Unsafety); + impl Debug for Print { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Some(")?; + Debug::fmt(Lite(&self.0), formatter)?; + formatter.write_str(")")?; + Ok(()) + } + } + formatter.field("unsafety", Print::ref_cast(val)); + } match self.value.mutability { syn::StaticMutability::None => {} _ => { @@ -3730,8 +3758,19 @@ impl Debug for Lite { if self.value.asyncness.is_some() { formatter.field("asyncness", &Present); } - if self.value.unsafety.is_some() { - formatter.field("unsafety", &Present); + if let Some(val) = &self.value.unsafety { + #[derive(RefCast)] + #[repr(transparent)] + struct Print(syn::Unsafety); + impl Debug for Print { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Some(")?; + Debug::fmt(Lite(&self.0), formatter)?; + formatter.write_str(")")?; + Ok(()) + } + } + formatter.field("unsafety", Print::ref_cast(val)); } if let Some(val) = &self.value.abi { #[derive(RefCast)] @@ -4548,6 +4587,20 @@ impl Debug for Lite { } } } +impl Debug for Lite { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match &self.value { + syn::Unsafety::Safe(_val) => { + formatter.write_str("Unsafety::Safe")?; + Ok(()) + } + syn::Unsafety::Unsafe(_val) => { + formatter.write_str("Unsafety::Unsafe")?; + Ok(()) + } + } + } +} impl Debug for Lite { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { let mut formatter = formatter.debug_struct("UseGlob"); @@ -5097,6 +5150,11 @@ impl Debug for Lite { formatter.write_str("Token![return]") } } +impl Debug for Lite { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Token![safe]") + } +} impl Debug for Lite { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("Token![Self]")