aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2021-02-09 18:09:35 -0800
committerHaibo Huang <hhb@google.com>2021-02-09 18:09:35 -0800
commit192b4227d9043733638cec58f66b31b17f4db88e (patch)
treeb3129744b8f0e906d0c8a171e5299b8f897a93bf
parentec2e2eba63691e5ae47d0e5297b10cccbc19aaf8 (diff)
downloadplatform_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.json2
-rw-r--r--Cargo.toml2
-rw-r--r--Cargo.toml.orig2
-rw-r--r--METADATA8
-rw-r--r--TEST_MAPPING27
-rw-r--r--src/attr.rs2
-rw-r--r--src/export.rs2
-rw-r--r--src/expr.rs31
-rw-r--r--src/item.rs112
-rw-r--r--src/lib.rs8
-rw-r--r--src/macros.rs16
-rw-r--r--src/pat.rs25
-rw-r--r--src/path.rs18
-rw-r--r--src/ty.rs45
-rw-r--r--tests/common/eq.rs32
-rw-r--r--tests/test_item.rs84
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"
}
}
diff --git a/Cargo.toml b/Cargo.toml
index 90eccd09..feec55e9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/METADATA b/METADATA
index 6f412bb3..00d6b20f 100644
--- a/METADATA
+++ b/METADATA
@@ -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;
diff --git a/src/lib.rs b/src/lib.rs
index 5cc38500..2c201c99 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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 {
diff --git a/src/pat.rs b/src/pat.rs
index 53810769..312d3c08 100644
--- a/src/pat.rs
+++ b/src/pat.rs
@@ -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 => {
diff --git a/src/ty.rs b/src/ty.rs
index eacae3b5..b60109f9 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -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,
+ },
+ ],
+ },
+ }),
+ ],
+ }
+ "###);
+}