diff options
author | Haibo Huang <hhb@google.com> | 2021-02-09 18:09:35 -0800 |
---|---|---|
committer | Haibo Huang <hhb@google.com> | 2021-02-09 18:09:35 -0800 |
commit | 192b4227d9043733638cec58f66b31b17f4db88e (patch) | |
tree | b3129744b8f0e906d0c8a171e5299b8f897a93bf | |
parent | ec2e2eba63691e5ae47d0e5297b10cccbc19aaf8 (diff) | |
download | platform_external_rust_crates_syn-192b4227d9043733638cec58f66b31b17f4db88e.tar.gz platform_external_rust_crates_syn-192b4227d9043733638cec58f66b31b17f4db88e.tar.bz2 platform_external_rust_crates_syn-192b4227d9043733638cec58f66b31b17f4db88e.zip |
Upgrade rust/crates/syn to 1.0.60
Test: make
Change-Id: I03ed2661099efbb3dfaa244a835c520f20a2d751
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | Cargo.toml.orig | 2 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | TEST_MAPPING | 27 | ||||
-rw-r--r-- | src/attr.rs | 2 | ||||
-rw-r--r-- | src/export.rs | 2 | ||||
-rw-r--r-- | src/expr.rs | 31 | ||||
-rw-r--r-- | src/item.rs | 112 | ||||
-rw-r--r-- | src/lib.rs | 8 | ||||
-rw-r--r-- | src/macros.rs | 16 | ||||
-rw-r--r-- | src/pat.rs | 25 | ||||
-rw-r--r-- | src/path.rs | 18 | ||||
-rw-r--r-- | src/ty.rs | 45 | ||||
-rw-r--r-- | tests/common/eq.rs | 32 | ||||
-rw-r--r-- | tests/test_item.rs | 84 |
16 files changed, 343 insertions, 73 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 5f1d542c..bc8af239 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "3414ed627f05dab27d951ce4868f08e3459a3fb8" + "sha1": "5b4a2d29d6bada9ca16b79718f93baafd77db736" } } @@ -13,7 +13,7 @@ [package] edition = "2018" name = "syn" -version = "1.0.58" +version = "1.0.60" authors = ["David Tolnay <dtolnay@gmail.com>"] include = ["/benches/**", "/build.rs", "/Cargo.toml", "/LICENSE-APACHE", "/LICENSE-MIT", "/README.md", "/src/**", "/tests/**"] description = "Parser for Rust source code" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index e24f96a2..11d01b11 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "syn" -version = "1.0.58" # don't forget to update html_root_url and syn.json +version = "1.0.60" # don't forget to update html_root_url and syn.json authors = ["David Tolnay <dtolnay@gmail.com>"] license = "MIT OR Apache-2.0" description = "Parser for Rust source code" @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/syn/syn-1.0.58.crate" + value: "https://static.crates.io/crates/syn/syn-1.0.60.crate" } - version: "1.0.58" + version: "1.0.60" license_type: NOTICE last_upgrade_date { year: 2021 - month: 1 - day: 5 + month: 2 + day: 9 } } diff --git a/TEST_MAPPING b/TEST_MAPPING index 8b9d952b..bb845581 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -1,35 +1,32 @@ -// Generated by cargo2android.py for tests in Android.bp +// Generated by update_crate_tests.py for tests that depend on this crate. { "presubmit": [ { - "host": true, - "name": "pin-project-internal_host_test_src_lib" + "name": "keystore2_crypto_test_rust" }, { - "host": true, - "name": "futures-util_host_test_src_lib" + "name": "libm_device_test_src_lib" }, { - "name": "futures-util_device_test_src_lib" + "name": "serde_test_device_test_src_lib" + }, + { + "name": "libsqlite3-sys_device_test_src_lib" }, { - "host": true, - "name": "structopt-derive_host_test_src_lib" + "name": "futures-util_device_test_src_lib" }, { - "host": true, - "name": "tokio-macros_host_test_src_lib" + "name": "keystore2_test" }, { - "host": true, - "name": "libsqlite3-sys_host_test_src_lib" + "name": "unicode-bidi_device_test_src_lib" }, { - "name": "libsqlite3-sys_device_test_src_lib" + "name": "url_device_test_src_lib" }, { - "host": true, - "name": "syn-mid_host_test_src_lib" + "name": "keystore2_selinux_test" } ] } diff --git a/src/attr.rs b/src/attr.rs index 1d82190e..794a3104 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -530,7 +530,7 @@ pub mod parsing { #[cfg(feature = "full")] impl private { - pub fn attrs(outer: Vec<Attribute>, inner: Vec<Attribute>) -> Vec<Attribute> { + pub(crate) fn attrs(outer: Vec<Attribute>, inner: Vec<Attribute>) -> Vec<Attribute> { let mut attrs = outer; attrs.extend(inner); attrs diff --git a/src/export.rs b/src/export.rs index 37dc467a..601a214b 100644 --- a/src/export.rs +++ b/src/export.rs @@ -33,3 +33,5 @@ mod help { pub type Bool = bool; pub type Str = str; } + +pub struct private(pub(crate) ()); diff --git a/src/expr.rs b/src/expr.rs index 8417475c..8e054cc7 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -224,8 +224,31 @@ ast_enum_of_structs! { /// A yield expression: `yield expr`. Yield(ExprYield), + // The following is the only supported idiom for exhaustive matching of + // this enum. + // + // match expr { + // Expr::Array(e) => {...} + // Expr::Assign(e) => {...} + // ... + // Expr::Yield(e) => {...} + // + // #[cfg(test)] + // Expr::__TestExhaustive(_) => unimplemented!(), + // #[cfg(not(test))] + // _ => { /* some sane fallback */ } + // } + // + // This way we fail your tests but don't break your library when adding + // a variant. You will be notified by a test failure when a variant is + // added, so that you can add code to handle it, but your library will + // continue to compile and work for downstream users in the interim. + // + // Once `deny(reachable)` is available in rustc, Expr will be + // reimplemented as a non_exhaustive enum. + // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237 #[doc(hidden)] - __Nonexhaustive, + __TestExhaustive(crate::private), } } @@ -804,7 +827,7 @@ impl Expr { | Expr::TryBlock(ExprTryBlock { attrs, .. }) | Expr::Yield(ExprYield { attrs, .. }) => mem::replace(attrs, new), Expr::Verbatim(_) => Vec::new(), - Expr::__Nonexhaustive => unreachable!(), + Expr::__TestExhaustive(_) => unreachable!(), } } } @@ -2303,7 +2326,7 @@ pub(crate) mod parsing { Pat::Type(_) => unreachable!(), Pat::Verbatim(_) => {} Pat::Wild(pat) => pat.attrs = attrs, - Pat::__Nonexhaustive => unreachable!(), + Pat::__TestExhaustive(_) => unreachable!(), } Ok(pat) } @@ -2654,7 +2677,7 @@ pub(crate) mod parsing { } for part in float_repr.split('.') { let index = crate::parse_str(part).map_err(|err| Error::new(float.span(), err))?; - let base = mem::replace(e, Expr::__Nonexhaustive); + let base = mem::replace(e, Expr::__TestExhaustive(crate::private(()))); *e = Expr::Field(ExprField { attrs: Vec::new(), base: Box::new(base), diff --git a/src/item.rs b/src/item.rs index 883ecc79..d5c3b277 100644 --- a/src/item.rs +++ b/src/item.rs @@ -71,8 +71,31 @@ ast_enum_of_structs! { /// Tokens forming an item not interpreted by Syn. Verbatim(TokenStream), + // The following is the only supported idiom for exhaustive matching of + // this enum. + // + // match expr { + // Item::Const(e) => {...} + // Item::Enum(e) => {...} + // ... + // Item::Verbatim(e) => {...} + // + // #[cfg(test)] + // Item::__TestExhaustive(_) => unimplemented!(), + // #[cfg(not(test))] + // _ => { /* some sane fallback */ } + // } + // + // This way we fail your tests but don't break your library when adding + // a variant. You will be notified by a test failure when a variant is + // added, so that you can add code to handle it, but your library will + // continue to compile and work for downstream users in the interim. + // + // Once `deny(reachable)` is available in rustc, Item will be + // reimplemented as a non_exhaustive enum. + // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237 #[doc(hidden)] - __Nonexhaustive, + __TestExhaustive(crate::private), } } @@ -357,7 +380,7 @@ impl Item { | Item::Macro(ItemMacro { attrs, .. }) | Item::Macro2(ItemMacro2 { attrs, .. }) => mem::replace(attrs, new), Item::Verbatim(_) => Vec::new(), - Item::__Nonexhaustive => unreachable!(), + Item::__TestExhaustive(_) => unreachable!(), } } } @@ -553,8 +576,31 @@ ast_enum_of_structs! { /// Tokens in an `extern` block not interpreted by Syn. Verbatim(TokenStream), + // The following is the only supported idiom for exhaustive matching of + // this enum. + // + // match expr { + // ForeignItem::Fn(e) => {...} + // ForeignItem::Static(e) => {...} + // ... + // ForeignItem::Verbatim(e) => {...} + // + // #[cfg(test)] + // ForeignItem::__TestExhaustive(_) => unimplemented!(), + // #[cfg(not(test))] + // _ => { /* some sane fallback */ } + // } + // + // This way we fail your tests but don't break your library when adding + // a variant. You will be notified by a test failure when a variant is + // added, so that you can add code to handle it, but your library will + // continue to compile and work for downstream users in the interim. + // + // Once `deny(reachable)` is available in rustc, ForeignItem will be + // reimplemented as a non_exhaustive enum. + // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237 #[doc(hidden)] - __Nonexhaustive, + __TestExhaustive(crate::private), } } @@ -641,8 +687,31 @@ ast_enum_of_structs! { /// Tokens within the definition of a trait not interpreted by Syn. Verbatim(TokenStream), + // The following is the only supported idiom for exhaustive matching of + // this enum. + // + // match expr { + // TraitItem::Const(e) => {...} + // TraitItem::Method(e) => {...} + // ... + // TraitItem::Verbatim(e) => {...} + // + // #[cfg(test)] + // TraitItem::__TestExhaustive(_) => unimplemented!(), + // #[cfg(not(test))] + // _ => { /* some sane fallback */ } + // } + // + // This way we fail your tests but don't break your library when adding + // a variant. You will be notified by a test failure when a variant is + // added, so that you can add code to handle it, but your library will + // continue to compile and work for downstream users in the interim. + // + // Once `deny(reachable)` is available in rustc, TraitItem will be + // reimplemented as a non_exhaustive enum. + // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237 #[doc(hidden)] - __Nonexhaustive, + __TestExhaustive(crate::private), } } @@ -731,8 +800,31 @@ ast_enum_of_structs! { /// Tokens within an impl block not interpreted by Syn. Verbatim(TokenStream), + // The following is the only supported idiom for exhaustive matching of + // this enum. + // + // match expr { + // ImplItem::Const(e) => {...} + // ImplItem::Method(e) => {...} + // ... + // ImplItem::Verbatim(e) => {...} + // + // #[cfg(test)] + // ImplItem::__TestExhaustive(_) => unimplemented!(), + // #[cfg(not(test))] + // _ => { /* some sane fallback */ } + // } + // + // This way we fail your tests but don't break your library when adding + // a variant. You will be notified by a test failure when a variant is + // added, so that you can add code to handle it, but your library will + // continue to compile and work for downstream users in the interim. + // + // Once `deny(reachable)` is available in rustc, ImplItem will be + // reimplemented as a non_exhaustive enum. + // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237 #[doc(hidden)] - __Nonexhaustive, + __TestExhaustive(crate::private), } } @@ -1695,7 +1787,7 @@ pub mod parsing { ForeignItem::Type(item) => &mut item.attrs, ForeignItem::Macro(item) => &mut item.attrs, ForeignItem::Verbatim(_) => return Ok(item), - ForeignItem::__Nonexhaustive => unreachable!(), + ForeignItem::__TestExhaustive(_) => unreachable!(), }; attrs.extend(item_attrs.drain(..)); *item_attrs = attrs; @@ -2032,14 +2124,14 @@ pub mod parsing { let mut supertraits = Punctuated::new(); if colon_token.is_some() { loop { - supertraits.push_value(input.parse()?); if input.peek(Token![where]) || input.peek(token::Brace) { break; } - supertraits.push_punct(input.parse()?); + supertraits.push_value(input.parse()?); if input.peek(Token![where]) || input.peek(token::Brace) { break; } + supertraits.push_punct(input.parse()?); } } @@ -2173,7 +2265,7 @@ pub mod parsing { TraitItem::Method(item) => &mut item.attrs, TraitItem::Type(item) => &mut item.attrs, TraitItem::Macro(item) => &mut item.attrs, - TraitItem::Verbatim(_) | TraitItem::__Nonexhaustive => unreachable!(), + TraitItem::Verbatim(_) | TraitItem::__TestExhaustive(_) => unreachable!(), }; attrs.extend(item_attrs.drain(..)); *item_attrs = attrs; @@ -2504,7 +2596,7 @@ pub mod parsing { ImplItem::Type(item) => &mut item.attrs, ImplItem::Macro(item) => &mut item.attrs, ImplItem::Verbatim(_) => return Ok(item), - ImplItem::__Nonexhaustive => unreachable!(), + ImplItem::__TestExhaustive(_) => unreachable!(), }; attrs.extend(item_attrs.drain(..)); *item_attrs = attrs; @@ -250,8 +250,9 @@ //! dynamic library libproc_macro from rustc toolchain. // Syn types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/syn/1.0.58")] +#![doc(html_root_url = "https://docs.rs/syn/1.0.60")] #![cfg_attr(doc_cfg, feature(doc_cfg))] +#![allow(non_camel_case_types)] // Ignored clippy lints. #![allow( clippy::doc_markdown, @@ -813,10 +814,9 @@ mod verbatim; #[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))] mod print; -//////////////////////////////////////////////////////////////////////////////// +use crate::__private::private; -#[allow(dead_code, non_camel_case_types)] -struct private; +//////////////////////////////////////////////////////////////////////////////// // https://github.com/rust-lang/rust/issues/62830 #[cfg(feature = "parsing")] diff --git a/src/macros.rs b/src/macros.rs index e0d0b81f..5097da94 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -77,7 +77,7 @@ macro_rules! ast_enum_of_structs_impl { $pub:ident $enum:ident $name:ident { $( $(#[$variant_attr:meta])* - $variant:ident $( ($member:ident) )*, + $variant:ident $( ($($member:ident)::+) )*, )* } @@ -87,7 +87,7 @@ macro_rules! ast_enum_of_structs_impl { check_keyword_matches!(enum $enum); $($( - ast_enum_from_struct!($name::$variant, $member); + ast_enum_from_struct!($name::$variant, $($member)::+); )*)* #[cfg(feature = "printing")] @@ -95,7 +95,7 @@ macro_rules! ast_enum_of_structs_impl { $($remaining)* () tokens - $name { $($variant $($member)*,)* } + $name { $($variant $($($member)::+)*,)* } } }; } @@ -104,6 +104,9 @@ macro_rules! ast_enum_from_struct { // No From<TokenStream> for verbatim variants. ($name:ident::Verbatim, $member:ident) => {}; + // No From<TokenStream> for private variants. + ($name:ident::$variant:ident, crate::private) => {}; + ($name:ident::$variant:ident, $member:ident) => { impl From<$member> for $name { fn from(e: $member) -> $name { @@ -131,6 +134,13 @@ macro_rules! generate_to_tokens { ); }; + (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident crate::private, $($next:tt)*}) => { + generate_to_tokens!( + ($($arms)* $name::$variant(_) => unreachable!(),) + $tokens $name { $($next)* } + ); + }; + (($($arms:tt)*) $tokens:ident $name:ident {}) => { #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ::quote::ToTokens for $name { @@ -72,8 +72,31 @@ ast_enum_of_structs! { /// A pattern that matches any value: `_`. Wild(PatWild), + // The following is the only supported idiom for exhaustive matching of + // this enum. + // + // match expr { + // Pat::Box(e) => {...} + // Pat::Ident(e) => {...} + // ... + // Pat::Wild(e) => {...} + // + // #[cfg(test)] + // Pat::__TestExhaustive(_) => unimplemented!(), + // #[cfg(not(test))] + // _ => { /* some sane fallback */ } + // } + // + // This way we fail your tests but don't break your library when adding + // a variant. You will be notified by a test failure when a variant is + // added, so that you can add code to handle it, but your library will + // continue to compile and work for downstream users in the interim. + // + // Once `deny(reachable)` is available in rustc, Pat will be + // reimplemented as a non_exhaustive enum. + // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237 #[doc(hidden)] - __Nonexhaustive, + __TestExhaustive(crate::private), } } diff --git a/src/path.rs b/src/path.rs index 601891e1..3f668c9d 100644 --- a/src/path.rs +++ b/src/path.rs @@ -248,12 +248,22 @@ pub mod parsing { return Ok(GenericArgument::Const(Expr::Lit(lit))); } - #[cfg(feature = "full")] - { - if input.peek(token::Brace) { + if input.peek(token::Brace) { + #[cfg(feature = "full")] + { let block = input.call(expr::parsing::expr_block)?; return Ok(GenericArgument::Const(Expr::Block(block))); } + + #[cfg(not(feature = "full"))] + { + let begin = input.fork(); + let content; + braced!(content in input); + content.parse::<Expr>()?; + let verbatim = verbatim::between(begin, input); + return Ok(GenericArgument::Const(Expr::Verbatim(verbatim))); + } } input.parse().map(GenericArgument::Type) @@ -737,7 +747,7 @@ mod printing { } impl private { - pub fn print_path(tokens: &mut TokenStream, qself: &Option<QSelf>, path: &Path) { + pub(crate) fn print_path(tokens: &mut TokenStream, qself: &Option<QSelf>, path: &Path) { let qself = match qself { Some(qself) => qself, None => { @@ -63,8 +63,31 @@ ast_enum_of_structs! { /// Tokens in type position not interpreted by Syn. Verbatim(TokenStream), + // The following is the only supported idiom for exhaustive matching of + // this enum. + // + // match expr { + // Type::Array(e) => {...} + // Type::BareFn(e) => {...} + // ... + // Type::Verbatim(e) => {...} + // + // #[cfg(test)] + // Type::__TestExhaustive(_) => unimplemented!(), + // #[cfg(not(test))] + // _ => { /* some sane fallback */ } + // } + // + // This way we fail your tests but don't break your library when adding + // a variant. You will be notified by a test failure when a variant is + // added, so that you can add code to handle it, but your library will + // continue to compile and work for downstream users in the interim. + // + // Once `deny(reachable)` is available in rustc, Type will be + // reimplemented as a non_exhaustive enum. + // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237 #[doc(hidden)] - __Nonexhaustive, + __TestExhaustive(crate::private), } } @@ -435,9 +458,13 @@ pub mod parsing { let mut elems = Punctuated::new(); elems.push_value(first); elems.push_punct(content.parse()?); - let rest: Punctuated<Type, Token![,]> = - content.parse_terminated(Parse::parse)?; - elems.extend(rest); + while !content.is_empty() { + elems.push_value(content.parse()?); + if content.is_empty() { + break; + } + elems.push_punct(content.parse()?); + } elems }, })); @@ -770,9 +797,13 @@ pub mod parsing { let mut elems = Punctuated::new(); elems.push_value(first); elems.push_punct(content.parse()?); - let rest: Punctuated<Type, Token![,]> = - content.parse_terminated(Parse::parse)?; - elems.extend(rest); + while !content.is_empty() { + elems.push_value(content.parse()?); + if content.is_empty() { + break; + } + elems.push_punct(content.parse()?); + } elems }, }) diff --git a/tests/common/eq.rs b/tests/common/eq.rs index 8690769b..7830163d 100644 --- a/tests/common/eq.rs +++ b/tests/common/eq.rs @@ -21,7 +21,7 @@ use rustc_ast::ast::{ }; use rustc_ast::ptr::P; use rustc_ast::token::{self, CommentKind, DelimToken, Nonterminal, Token, TokenKind}; -use rustc_ast::tokenstream::{self, DelimSpan, LazyTokenStream, TokenStream, TokenTree}; +use rustc_ast::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::thin_vec::ThinVec; use rustc_span::source_map::Spanned; @@ -307,7 +307,7 @@ spanless_eq_struct!(MacCallStmt; mac style attrs tokens); spanless_eq_struct!(MacroDef; body macro_rules); spanless_eq_struct!(Mod; inner unsafety items inline); spanless_eq_struct!(MutTy; ty mutbl); -spanless_eq_struct!(ParenthesizedArgs; span inputs output); +spanless_eq_struct!(ParenthesizedArgs; span inputs inputs_span output); spanless_eq_struct!(Pat; id kind span tokens); spanless_eq_struct!(Path; span segments tokens); spanless_eq_struct!(PathSegment; ident id args); @@ -538,19 +538,24 @@ fn doc_comment<'a>( })) => {} _ => return false, } - is_escaped_literal(trees, unescaped) + match trees.next() { + Some(TokenTree::Token(token)) => { + is_escaped_literal(token, unescaped) && trees.next().is_none() + } + _ => false, + } } -fn is_escaped_literal(mut trees: tokenstream::CursorRef, unescaped: Symbol) -> bool { - match match trees.next() { - Some(TokenTree::Token(Token { +fn is_escaped_literal(token: &Token, unescaped: Symbol) -> bool { + match match token { + Token { kind: TokenKind::Literal(lit), span: _, - })) => Lit::from_lit_token(*lit, DUMMY_SP), - Some(TokenTree::Token(Token { + } => Lit::from_lit_token(*lit, DUMMY_SP), + Token { kind: TokenKind::Interpolated(nonterminal), span: _, - })) => match nonterminal.as_ref() { + } => match nonterminal.as_ref() { Nonterminal::NtExpr(expr) => match &expr.kind { ExprKind::Lit(lit) => Ok(lit.clone()), _ => return false, @@ -568,10 +573,7 @@ fn is_escaped_literal(mut trees: tokenstream::CursorRef, unescaped: Symbol) -> b }, kind: LitKind::Str(symbol, StrStyle::Cooked), span: _, - }) => { - symbol.as_str().replace('\r', "") == unescaped.as_str().replace('\r', "") - && trees.next().is_none() - } + }) => symbol.as_str().replace('\r', "") == unescaped.as_str().replace('\r', ""), _ => false, } } @@ -601,9 +603,7 @@ impl SpanlessEq for AttrKind { SpanlessEq::eq(&path, &item2.path) && match &item2.args { MacArgs::Empty | MacArgs::Delimited(..) => false, - MacArgs::Eq(_span, tokens) => { - is_escaped_literal(tokens.trees_ref(), *unescaped) - } + MacArgs::Eq(_span, token) => is_escaped_literal(token, *unescaped), } } (AttrKind::Normal(..), AttrKind::DocComment(..)) => SpanlessEq::eq(other, self), diff --git a/tests/test_item.rs b/tests/test_item.rs index c28fc87f..7695f199 100644 --- a/tests/test_item.rs +++ b/tests/test_item.rs @@ -4,7 +4,7 @@ mod macros; use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree}; use quote::quote; use std::iter::FromIterator; -use syn::Item; +use syn::{Item, ItemTrait}; #[test] fn test_macro_variable_attr() { @@ -159,3 +159,85 @@ fn test_macro_variable_impl() { } "###); } + +#[test] +fn test_supertraits() { + // Rustc parses all of the following. + + #[rustfmt::skip] + let tokens = quote!(trait Trait where {}); + snapshot!(tokens as ItemTrait, @r###" + ItemTrait { + vis: Inherited, + ident: "Trait", + generics: Generics { + where_clause: Some(WhereClause), + }, + } + "###); + + #[rustfmt::skip] + let tokens = quote!(trait Trait: where {}); + snapshot!(tokens as ItemTrait, @r###" + ItemTrait { + vis: Inherited, + ident: "Trait", + generics: Generics { + where_clause: Some(WhereClause), + }, + colon_token: Some, + } + "###); + + #[rustfmt::skip] + let tokens = quote!(trait Trait: Sized where {}); + snapshot!(tokens as ItemTrait, @r###" + ItemTrait { + vis: Inherited, + ident: "Trait", + generics: Generics { + where_clause: Some(WhereClause), + }, + colon_token: Some, + supertraits: [ + Trait(TraitBound { + modifier: None, + path: Path { + segments: [ + PathSegment { + ident: "Sized", + arguments: None, + }, + ], + }, + }), + ], + } + "###); + + #[rustfmt::skip] + let tokens = quote!(trait Trait: Sized + where {}); + snapshot!(tokens as ItemTrait, @r###" + ItemTrait { + vis: Inherited, + ident: "Trait", + generics: Generics { + where_clause: Some(WhereClause), + }, + colon_token: Some, + supertraits: [ + Trait(TraitBound { + modifier: None, + path: Path { + segments: [ + PathSegment { + ident: "Sized", + arguments: None, + }, + ], + }, + }), + ], + } + "###); +} |