diff --git a/src/expr.rs b/src/expr.rs index ad8909f7a0..7d32e4d525 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -526,7 +526,7 @@ ast_struct! { pub receiver: Box, pub dot_token: Token![.], pub method: Ident, - pub turbofish: Option, + pub turbofish: Option, pub paren_token: token::Paren, pub args: Punctuated, } @@ -858,19 +858,6 @@ impl IdentFragment for Index { } } -#[cfg(feature = "full")] -ast_struct! { - /// The `::<>` explicit type parameters passed to a method call: - /// `parse::()`. - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct MethodTurbofish { - pub colon2_token: Token![::], - pub lt_token: Token![<], - pub args: Punctuated, - pub gt_token: Token![>], - } -} - #[cfg(feature = "full")] ast_struct! { /// A field-value pair in a struct literal. @@ -1473,7 +1460,7 @@ pub(crate) mod parsing { let member: Member = input.parse()?; let turbofish = if member.is_named() && input.peek(Token![::]) { - Some(input.parse::()?) + Some(AngleBracketedGenericArguments::parse_turbofish(input)?) } else { None }; @@ -1946,34 +1933,6 @@ pub(crate) mod parsing { }) } - #[cfg(feature = "full")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for MethodTurbofish { - fn parse(input: ParseStream) -> Result { - Ok(MethodTurbofish { - colon2_token: input.parse()?, - lt_token: input.parse()?, - args: { - let mut args = Punctuated::new(); - loop { - if input.peek(Token![>]) { - break; - } - let value: GenericArgument = input.parse()?; - args.push_value(value); - if input.peek(Token![>]) { - break; - } - let punct = input.parse()?; - args.push_punct(punct); - } - args - }, - gt_token: input.parse()?, - }) - } - } - #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ExprLet { @@ -2855,17 +2814,6 @@ pub(crate) mod printing { } } - #[cfg(feature = "full")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for MethodTurbofish { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.colon2_token.to_tokens(tokens); - self.lt_token.to_tokens(tokens); - self.args.to_tokens(tokens); - self.gt_token.to_tokens(tokens); - } - } - #[cfg(feature = "full")] #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for ExprTuple { diff --git a/src/gen/clone.rs b/src/gen/clone.rs index cf7f3a4191..06ab49c6c1 100644 --- a/src/gen/clone.rs +++ b/src/gen/clone.rs @@ -1418,18 +1418,6 @@ impl Clone for MetaNameValue { } } } -#[cfg(feature = "full")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))] -impl Clone for MethodTurbofish { - fn clone(&self) -> Self { - MethodTurbofish { - colon2_token: self.colon2_token.clone(), - lt_token: self.lt_token.clone(), - args: self.args.clone(), - gt_token: self.gt_token.clone(), - } - } -} #[cfg(any(feature = "derive", feature = "full"))] #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))] impl Clone for ParenthesizedGenericArguments { diff --git a/src/gen/debug.rs b/src/gen/debug.rs index da7b45e156..bde6a00fe2 100644 --- a/src/gen/debug.rs +++ b/src/gen/debug.rs @@ -1952,18 +1952,6 @@ impl Debug for MetaNameValue { formatter.finish() } } -#[cfg(feature = "full")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] -impl Debug for MethodTurbofish { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - let mut formatter = formatter.debug_struct("MethodTurbofish"); - formatter.field("colon2_token", &self.colon2_token); - formatter.field("lt_token", &self.lt_token); - formatter.field("args", &self.args); - formatter.field("gt_token", &self.gt_token); - formatter.finish() - } -} #[cfg(any(feature = "derive", feature = "full"))] #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] impl Debug for ParenthesizedGenericArguments { diff --git a/src/gen/eq.rs b/src/gen/eq.rs index 384988c269..3787ebd8ee 100644 --- a/src/gen/eq.rs +++ b/src/gen/eq.rs @@ -1341,16 +1341,6 @@ impl PartialEq for MetaNameValue { self.path == other.path && self.value == other.value } } -#[cfg(feature = "full")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] -impl Eq for MethodTurbofish {} -#[cfg(feature = "full")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] -impl PartialEq for MethodTurbofish { - fn eq(&self, other: &Self) -> bool { - self.args == other.args - } -} #[cfg(any(feature = "derive", feature = "full"))] #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] impl Eq for ParenthesizedGenericArguments {} diff --git a/src/gen/fold.rs b/src/gen/fold.rs index 953d5461e3..e013219a6f 100644 --- a/src/gen/fold.rs +++ b/src/gen/fold.rs @@ -484,10 +484,6 @@ pub trait Fold { fn fold_meta_name_value(&mut self, i: MetaNameValue) -> MetaNameValue { fold_meta_name_value(self, i) } - #[cfg(feature = "full")] - fn fold_method_turbofish(&mut self, i: MethodTurbofish) -> MethodTurbofish { - fold_method_turbofish(self, i) - } #[cfg(any(feature = "derive", feature = "full"))] fn fold_parenthesized_generic_arguments( &mut self, @@ -1407,7 +1403,8 @@ where receiver: Box::new(f.fold_expr(*node.receiver)), dot_token: Token![.](tokens_helper(f, &node.dot_token.spans)), method: f.fold_ident(node.method), - turbofish: (node.turbofish).map(|it| f.fold_method_turbofish(it)), + turbofish: (node.turbofish) + .map(|it| f.fold_angle_bracketed_generic_arguments(it)), paren_token: Paren(tokens_helper(f, &node.paren_token.span)), args: FoldHelper::lift(node.args, |it| f.fold_expr(it)), } @@ -2392,18 +2389,6 @@ where value: f.fold_expr(node.value), } } -#[cfg(feature = "full")] -pub fn fold_method_turbofish(f: &mut F, node: MethodTurbofish) -> MethodTurbofish -where - F: Fold + ?Sized, -{ - MethodTurbofish { - colon2_token: Token![::](tokens_helper(f, &node.colon2_token.spans)), - lt_token: Token![<](tokens_helper(f, &node.lt_token.spans)), - args: FoldHelper::lift(node.args, |it| f.fold_generic_argument(it)), - gt_token: Token![>](tokens_helper(f, &node.gt_token.spans)), - } -} #[cfg(any(feature = "derive", feature = "full"))] pub fn fold_parenthesized_generic_arguments( f: &mut F, diff --git a/src/gen/hash.rs b/src/gen/hash.rs index 2a4cc3b1c9..e6a08963b7 100644 --- a/src/gen/hash.rs +++ b/src/gen/hash.rs @@ -1799,16 +1799,6 @@ impl Hash for MetaNameValue { self.value.hash(state); } } -#[cfg(feature = "full")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] -impl Hash for MethodTurbofish { - fn hash(&self, state: &mut H) - where - H: Hasher, - { - self.args.hash(state); - } -} #[cfg(any(feature = "derive", feature = "full"))] #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] impl Hash for ParenthesizedGenericArguments { diff --git a/src/gen/visit.rs b/src/gen/visit.rs index 5d6fa29628..56492b09f6 100644 --- a/src/gen/visit.rs +++ b/src/gen/visit.rs @@ -486,10 +486,6 @@ pub trait Visit<'ast> { fn visit_meta_name_value(&mut self, i: &'ast MetaNameValue) { visit_meta_name_value(self, i); } - #[cfg(feature = "full")] - fn visit_method_turbofish(&mut self, i: &'ast MethodTurbofish) { - visit_method_turbofish(self, i); - } #[cfg(any(feature = "derive", feature = "full"))] fn visit_parenthesized_generic_arguments( &mut self, @@ -1537,7 +1533,7 @@ where tokens_helper(v, &node.dot_token.spans); v.visit_ident(&node.method); if let Some(it) = &node.turbofish { - v.visit_method_turbofish(it); + v.visit_angle_bracketed_generic_arguments(it); } tokens_helper(v, &node.paren_token.span); for el in Punctuated::pairs(&node.args) { @@ -2662,22 +2658,6 @@ where tokens_helper(v, &node.eq_token.spans); v.visit_expr(&node.value); } -#[cfg(feature = "full")] -pub fn visit_method_turbofish<'ast, V>(v: &mut V, node: &'ast MethodTurbofish) -where - V: Visit<'ast> + ?Sized, -{ - tokens_helper(v, &node.colon2_token.spans); - tokens_helper(v, &node.lt_token.spans); - for el in Punctuated::pairs(&node.args) { - let (it, p) = el.into_tuple(); - v.visit_generic_argument(it); - if let Some(p) = p { - tokens_helper(v, &p.spans); - } - } - tokens_helper(v, &node.gt_token.spans); -} #[cfg(any(feature = "derive", feature = "full"))] pub fn visit_parenthesized_generic_arguments<'ast, V>( v: &mut V, diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs index e9453b9924..75685f5768 100644 --- a/src/gen/visit_mut.rs +++ b/src/gen/visit_mut.rs @@ -487,10 +487,6 @@ pub trait VisitMut { fn visit_meta_name_value_mut(&mut self, i: &mut MetaNameValue) { visit_meta_name_value_mut(self, i); } - #[cfg(feature = "full")] - fn visit_method_turbofish_mut(&mut self, i: &mut MethodTurbofish) { - visit_method_turbofish_mut(self, i); - } #[cfg(any(feature = "derive", feature = "full"))] fn visit_parenthesized_generic_arguments_mut( &mut self, @@ -1538,7 +1534,7 @@ where tokens_helper(v, &mut node.dot_token.spans); v.visit_ident_mut(&mut node.method); if let Some(it) = &mut node.turbofish { - v.visit_method_turbofish_mut(it); + v.visit_angle_bracketed_generic_arguments_mut(it); } tokens_helper(v, &mut node.paren_token.span); for el in Punctuated::pairs_mut(&mut node.args) { @@ -2665,22 +2661,6 @@ where tokens_helper(v, &mut node.eq_token.spans); v.visit_expr_mut(&mut node.value); } -#[cfg(feature = "full")] -pub fn visit_method_turbofish_mut(v: &mut V, node: &mut MethodTurbofish) -where - V: VisitMut + ?Sized, -{ - tokens_helper(v, &mut node.colon2_token.spans); - tokens_helper(v, &mut node.lt_token.spans); - for el in Punctuated::pairs_mut(&mut node.args) { - let (it, p) = el.into_tuple(); - v.visit_generic_argument_mut(it); - if let Some(p) = p { - tokens_helper(v, &mut p.spans); - } - } - tokens_helper(v, &mut node.gt_token.spans); -} #[cfg(any(feature = "derive", feature = "full"))] pub fn visit_parenthesized_generic_arguments_mut( v: &mut V, diff --git a/src/lib.rs b/src/lib.rs index 617500ac22..9ca8e5207f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -345,7 +345,7 @@ pub use crate::error::{Error, Result}; #[cfg(any(feature = "full", feature = "derive"))] mod expr; #[cfg(feature = "full")] -pub use crate::expr::{Arm, FieldValue, Label, MethodTurbofish, RangeLimits}; +pub use crate::expr::{Arm, FieldValue, Label, RangeLimits}; #[cfg(any(feature = "full", feature = "derive"))] pub use crate::expr::{ Expr, ExprArray, ExprAssign, ExprAssignOp, ExprAsync, ExprAwait, ExprBinary, ExprBlock, diff --git a/src/path.rs b/src/path.rs index 369af385ca..9a53fb5b46 100644 --- a/src/path.rs +++ b/src/path.rs @@ -328,11 +328,21 @@ pub mod parsing { Err(lookahead.error()) } - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for AngleBracketedGenericArguments { - fn parse(input: ParseStream) -> Result { + impl AngleBracketedGenericArguments { + /// Parse `::<…>` with mandatory leading `::`. + /// + /// The ordinary [`Parse`] impl for `AngleBracketedGenericArguments` + /// parses optional leading `::`. + #[cfg(feature = "full")] + #[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "full"))))] + pub fn parse_turbofish(input: ParseStream) -> Result { + let colon2_token: Token![::] = input.parse()?; + Self::do_parse(Some(colon2_token), input) + } + + fn do_parse(colon2_token: Option, input: ParseStream) -> Result { Ok(AngleBracketedGenericArguments { - colon2_token: input.parse()?, + colon2_token, lt_token: input.parse()?, args: { let mut args = Punctuated::new(); @@ -340,12 +350,12 @@ pub mod parsing { if input.peek(Token![>]) { break; } - let value = input.parse()?; + let value: GenericArgument = input.parse()?; args.push_value(value); if input.peek(Token![>]) { break; } - let punct = input.parse()?; + let punct: Token![,] = input.parse()?; args.push_punct(punct); } args @@ -355,6 +365,14 @@ pub mod parsing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + impl Parse for AngleBracketedGenericArguments { + fn parse(input: ParseStream) -> Result { + let colon2_token: Option = input.parse()?; + Self::do_parse(colon2_token, input) + } + } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ParenthesizedGenericArguments { fn parse(input: ParseStream) -> Result { diff --git a/syn.json b/syn.json index d8b59577f8..fcb69a99be 100644 --- a/syn.json +++ b/syn.json @@ -1481,7 +1481,7 @@ }, "turbofish": { "option": { - "syn": "MethodTurbofish" + "syn": "AngleBracketedGenericArguments" } }, "paren_token": { @@ -3580,33 +3580,6 @@ } } }, - { - "ident": "MethodTurbofish", - "features": { - "any": [ - "full" - ] - }, - "fields": { - "colon2_token": { - "token": "Colon2" - }, - "lt_token": { - "token": "Lt" - }, - "args": { - "punctuated": { - "element": { - "syn": "GenericArgument" - }, - "punct": "Comma" - } - }, - "gt_token": { - "token": "Gt" - } - } - }, { "ident": "ParenthesizedGenericArguments", "features": { diff --git a/tests/debug/gen.rs b/tests/debug/gen.rs index ecaaf01d47..867b37bb16 100644 --- a/tests/debug/gen.rs +++ b/tests/debug/gen.rs @@ -838,7 +838,7 @@ impl Debug for Lite { if let Some(val) = &_val.turbofish { #[derive(RefCast)] #[repr(transparent)] - struct Print(syn::MethodTurbofish); + struct Print(syn::AngleBracketedGenericArguments); impl Debug for Print { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("Some")?; @@ -1622,7 +1622,7 @@ impl Debug for Lite { if let Some(val) = &_val.turbofish { #[derive(RefCast)] #[repr(transparent)] - struct Print(syn::MethodTurbofish); + struct Print(syn::AngleBracketedGenericArguments); impl Debug for Print { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("Some")?; @@ -3700,16 +3700,6 @@ impl Debug for Lite { formatter.finish() } } -impl Debug for Lite { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - let _val = &self.value; - let mut formatter = formatter.debug_struct("MethodTurbofish"); - if !_val.args.is_empty() { - formatter.field("args", Lite(&_val.args)); - } - formatter.finish() - } -} impl Debug for Lite { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { let _val = &self.value;