aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2021-04-13 08:49:59 -0700
committerJoel Galenson <jgalenson@google.com>2021-04-13 08:49:59 -0700
commit2909d9d54b627c0c0689e77a0c0f5ba2e6941750 (patch)
treefb7bfe81f90eef9c0b43170900c41174fdd24601
parent5c4da13b5ef53bc3a5ec65343e0e62c7f6581a68 (diff)
downloadplatform_external_rust_crates_syn-2909d9d54b627c0c0689e77a0c0f5ba2e6941750.tar.gz
platform_external_rust_crates_syn-2909d9d54b627c0c0689e77a0c0f5ba2e6941750.tar.bz2
platform_external_rust_crates_syn-2909d9d54b627c0c0689e77a0c0f5ba2e6941750.zip
Upgrade rust/crates/syn to 1.0.69
Test: make Change-Id: I4cf57cc3c7cd58a2fda04414b95edb58590c162b
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp5
-rw-r--r--Cargo.toml4
-rw-r--r--Cargo.toml.orig4
-rw-r--r--METADATA8
-rw-r--r--TEST_MAPPING353
-rw-r--r--src/custom_keyword.rs1
-rw-r--r--src/custom_punctuation.rs1
-rw-r--r--src/error.rs2
-rw-r--r--src/expr.rs370
-rw-r--r--src/generics.rs12
-rw-r--r--src/item.rs76
-rw-r--r--src/lib.rs10
-rw-r--r--src/lifetime.rs11
-rw-r--r--src/lit.rs18
-rw-r--r--src/pat.rs6
-rw-r--r--src/path.rs116
-rw-r--r--src/punctuated.rs23
-rw-r--r--tests/common/eq.rs117
-rw-r--r--tests/repo/mod.rs4
-rw-r--r--tests/test_item.rs25
-rw-r--r--tests/test_pat.rs10
-rw-r--r--tests/test_precedence.rs13
23 files changed, 938 insertions, 253 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index bc8af239..36a487f8 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
{
"git": {
- "sha1": "5b4a2d29d6bada9ca16b79718f93baafd77db736"
+ "sha1": "c80b47159a47340d20f5774d2fe1c09bd0994a13"
}
}
diff --git a/Android.bp b/Android.bp
index 647b0364..7445c4c0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,5 @@
// This file is generated by cargo2android.py --run --dependencies --features=full,visit,visit-mut,extra-traits --features=default,full,visit,visit-mut,extra-traits --host-first-multilib.
+// Do not modify this file as changes will be overridden on upgrade.
package {
default_applicable_licenses: ["external_rust_crates_syn_license"],
@@ -66,6 +67,6 @@ rust_library_host {
}
// dependent_library ["feature_list"]
-// proc-macro2-1.0.24 "default,proc-macro"
-// quote-1.0.8 "default,proc-macro"
+// proc-macro2-1.0.26 "default,proc-macro"
+// quote-1.0.9 "default,proc-macro"
// unicode-xid-0.2.1 "default"
diff --git a/Cargo.toml b/Cargo.toml
index feec55e9..b2dbe617 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "syn"
-version = "1.0.60"
+version = "1.0.69"
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"
@@ -39,7 +39,7 @@ required-features = ["full", "parsing"]
name = "file"
required-features = ["full", "parsing"]
[dependencies.proc-macro2]
-version = "1.0.23"
+version = "1.0.26"
default-features = false
[dependencies.quote]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 11d01b11..d29b93db 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "syn"
-version = "1.0.60" # don't forget to update html_root_url and syn.json
+version = "1.0.69" # 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"
@@ -35,7 +35,7 @@ proc-macro = ["proc-macro2/proc-macro", "quote/proc-macro"]
test = ["syn-test-suite/all-features"]
[dependencies]
-proc-macro2 = { version = "1.0.23", default-features = false }
+proc-macro2 = { version = "1.0.26", default-features = false }
quote = { version = "1.0", optional = true, default-features = false }
unicode-xid = "0.2"
diff --git a/METADATA b/METADATA
index 00d6b20f..366fd603 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/syn/syn-1.0.60.crate"
+ value: "https://static.crates.io/crates/syn/syn-1.0.69.crate"
}
- version: "1.0.60"
+ version: "1.0.69"
license_type: NOTICE
last_upgrade_date {
year: 2021
- month: 2
- day: 9
+ month: 4
+ day: 13
}
}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index bb845581..5d043ff9 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -2,22 +2,361 @@
{
"presubmit": [
{
+ "name": "anyhow_device_test_src_lib"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_autotrait"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_boxed"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_chain"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_context"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_convert"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_downcast"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_ffi"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_fmt"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_macros"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_repr"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_source"
+ },
+ {
+ "name": "authfs_device_test_src_lib"
+ },
+ {
+ "name": "either_device_test_src_lib"
+ },
+ {
+ "name": "futures-util_device_test_src_lib"
+ },
+ {
"name": "keystore2_crypto_test_rust"
},
{
+ "name": "keystore2_selinux_test"
+ },
+ {
+ "name": "keystore2_test"
+ },
+ {
"name": "libm_device_test_src_lib"
},
{
+ "name": "libsqlite3-sys_device_test_src_lib"
+ },
+ {
+ "name": "serde_cbor_device_test_src_lib"
+ },
+ {
+ "name": "serde_cbor_device_test_tests_bennofs"
+ },
+ {
+ "name": "serde_cbor_device_test_tests_canonical"
+ },
+ {
+ "name": "serde_cbor_device_test_tests_de"
+ },
+ {
+ "name": "serde_cbor_device_test_tests_enum"
+ },
+ {
+ "name": "serde_cbor_device_test_tests_ser"
+ },
+ {
+ "name": "serde_cbor_device_test_tests_std_types"
+ },
+ {
+ "name": "serde_cbor_device_test_tests_tags"
+ },
+ {
+ "name": "serde_cbor_device_test_tests_value"
+ },
+ {
"name": "serde_test_device_test_src_lib"
},
{
- "name": "libsqlite3-sys_device_test_src_lib"
+ "name": "tokio-test_device_test_src_lib"
},
{
- "name": "futures-util_device_test_src_lib"
+ "name": "tokio-test_device_test_tests_block_on"
},
{
- "name": "keystore2_test"
+ "name": "tokio-test_device_test_tests_io"
+ },
+ {
+ "name": "tokio-test_device_test_tests_macros"
+ },
+ {
+ "name": "tokio_device_test_tests_async_send_sync"
+ },
+ {
+ "name": "tokio_device_test_tests_buffered"
+ },
+ {
+ "name": "tokio_device_test_tests_fs"
+ },
+ {
+ "name": "tokio_device_test_tests_fs_copy"
+ },
+ {
+ "name": "tokio_device_test_tests_fs_dir"
+ },
+ {
+ "name": "tokio_device_test_tests_fs_file"
+ },
+ {
+ "name": "tokio_device_test_tests_fs_file_mocked"
+ },
+ {
+ "name": "tokio_device_test_tests_fs_link"
+ },
+ {
+ "name": "tokio_device_test_tests_io_async_fd"
+ },
+ {
+ "name": "tokio_device_test_tests_io_async_read"
+ },
+ {
+ "name": "tokio_device_test_tests_io_chain"
+ },
+ {
+ "name": "tokio_device_test_tests_io_copy"
+ },
+ {
+ "name": "tokio_device_test_tests_io_driver"
+ },
+ {
+ "name": "tokio_device_test_tests_io_driver_drop"
+ },
+ {
+ "name": "tokio_device_test_tests_io_lines"
+ },
+ {
+ "name": "tokio_device_test_tests_io_mem_stream"
+ },
+ {
+ "name": "tokio_device_test_tests_io_read"
+ },
+ {
+ "name": "tokio_device_test_tests_io_read_buf"
+ },
+ {
+ "name": "tokio_device_test_tests_io_read_exact"
+ },
+ {
+ "name": "tokio_device_test_tests_io_read_line"
+ },
+ {
+ "name": "tokio_device_test_tests_io_read_to_end"
+ },
+ {
+ "name": "tokio_device_test_tests_io_read_to_string"
+ },
+ {
+ "name": "tokio_device_test_tests_io_read_until"
+ },
+ {
+ "name": "tokio_device_test_tests_io_split"
+ },
+ {
+ "name": "tokio_device_test_tests_io_take"
+ },
+ {
+ "name": "tokio_device_test_tests_io_write"
+ },
+ {
+ "name": "tokio_device_test_tests_io_write_all"
+ },
+ {
+ "name": "tokio_device_test_tests_io_write_buf"
+ },
+ {
+ "name": "tokio_device_test_tests_io_write_int"
+ },
+ {
+ "name": "tokio_device_test_tests_macros_join"
+ },
+ {
+ "name": "tokio_device_test_tests_macros_pin"
+ },
+ {
+ "name": "tokio_device_test_tests_macros_select"
+ },
+ {
+ "name": "tokio_device_test_tests_macros_test"
+ },
+ {
+ "name": "tokio_device_test_tests_macros_try_join"
+ },
+ {
+ "name": "tokio_device_test_tests_net_bind_resource"
+ },
+ {
+ "name": "tokio_device_test_tests_net_lookup_host"
+ },
+ {
+ "name": "tokio_device_test_tests_no_rt"
+ },
+ {
+ "name": "tokio_device_test_tests_process_issue_2174"
+ },
+ {
+ "name": "tokio_device_test_tests_process_issue_42"
+ },
+ {
+ "name": "tokio_device_test_tests_process_kill_on_drop"
+ },
+ {
+ "name": "tokio_device_test_tests_process_smoke"
+ },
+ {
+ "name": "tokio_device_test_tests_rt_basic"
+ },
+ {
+ "name": "tokio_device_test_tests_rt_common"
+ },
+ {
+ "name": "tokio_device_test_tests_rt_threaded"
+ },
+ {
+ "name": "tokio_device_test_tests_signal_ctrl_c"
+ },
+ {
+ "name": "tokio_device_test_tests_signal_drop_recv"
+ },
+ {
+ "name": "tokio_device_test_tests_signal_drop_rt"
+ },
+ {
+ "name": "tokio_device_test_tests_signal_drop_signal"
+ },
+ {
+ "name": "tokio_device_test_tests_signal_multi_rt"
+ },
+ {
+ "name": "tokio_device_test_tests_signal_no_rt"
+ },
+ {
+ "name": "tokio_device_test_tests_signal_notify_both"
+ },
+ {
+ "name": "tokio_device_test_tests_signal_twice"
+ },
+ {
+ "name": "tokio_device_test_tests_signal_usr1"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_barrier"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_broadcast"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_errors"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_mpsc"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_mutex"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_mutex_owned"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_notify"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_oneshot"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_rwlock"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_semaphore"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_semaphore_owned"
+ },
+ {
+ "name": "tokio_device_test_tests_sync_watch"
+ },
+ {
+ "name": "tokio_device_test_tests_task_abort"
+ },
+ {
+ "name": "tokio_device_test_tests_task_blocking"
+ },
+ {
+ "name": "tokio_device_test_tests_task_local"
+ },
+ {
+ "name": "tokio_device_test_tests_task_local_set"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_accept"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_connect"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_echo"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_into_split"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_into_std"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_peek"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_shutdown"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_socket"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_split"
+ },
+ {
+ "name": "tokio_device_test_tests_tcp_stream"
+ },
+ {
+ "name": "tokio_device_test_tests_test_clock"
+ },
+ {
+ "name": "tokio_device_test_tests_udp"
+ },
+ {
+ "name": "tokio_device_test_tests_uds_cred"
+ },
+ {
+ "name": "tokio_device_test_tests_uds_datagram"
+ },
+ {
+ "name": "tokio_device_test_tests_uds_split"
+ },
+ {
+ "name": "tokio_device_test_tests_uds_stream"
},
{
"name": "unicode-bidi_device_test_src_lib"
@@ -26,7 +365,13 @@
"name": "url_device_test_src_lib"
},
{
- "name": "keystore2_selinux_test"
+ "name": "url_device_test_tests_data"
+ },
+ {
+ "name": "url_device_test_tests_unit"
+ },
+ {
+ "name": "vpnprofilestore_test"
}
]
}
diff --git a/src/custom_keyword.rs b/src/custom_keyword.rs
index a21842ef..69d787e5 100644
--- a/src/custom_keyword.rs
+++ b/src/custom_keyword.rs
@@ -198,6 +198,7 @@ macro_rules! impl_clone_for_custom_keyword {
($ident:ident) => {
impl $crate::__private::Copy for $ident {}
+ #[allow(clippy::expl_impl_clone_on_copy)]
impl $crate::__private::Clone for $ident {
fn clone(&self) -> Self {
*self
diff --git a/src/custom_punctuation.rs b/src/custom_punctuation.rs
index 128185da..118a8453 100644
--- a/src/custom_punctuation.rs
+++ b/src/custom_punctuation.rs
@@ -169,6 +169,7 @@ macro_rules! impl_clone_for_custom_punctuation {
($ident:ident, $($tt:tt)+) => {
impl $crate::__private::Copy for $ident {}
+ #[allow(clippy::expl_impl_clone_on_copy)]
impl $crate::__private::Clone for $ident {
fn clone(&self) -> Self {
*self
diff --git a/src/error.rs b/src/error.rs
index 6051f3b6..780731c8 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -349,7 +349,7 @@ impl std::error::Error for Error {}
impl From<LexError> for Error {
fn from(err: LexError) -> Self {
- Error::new(Span::call_site(), format!("{:?}", err))
+ Error::new(err.span(), "lex error")
}
}
diff --git a/src/expr.rs b/src/expr.rs
index 8e054cc7..a35532d4 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -827,7 +827,11 @@ impl Expr {
| Expr::TryBlock(ExprTryBlock { attrs, .. })
| Expr::Yield(ExprYield { attrs, .. }) => mem::replace(attrs, new),
Expr::Verbatim(_) => Vec::new(),
- Expr::__TestExhaustive(_) => unreachable!(),
+
+ #[cfg(test)]
+ Expr::__TestExhaustive(_) => unimplemented!(),
+ #[cfg(not(test))]
+ _ => unreachable!(),
}
}
}
@@ -1418,7 +1422,9 @@ pub(crate) mod parsing {
Precedence::Assign
} else if input.peek(Token![..]) {
Precedence::Range
- } else if input.peek(Token![as]) || input.peek(Token![:]) && !input.peek(Token![::]) {
+ } else if input.peek(Token![as])
+ || cfg!(feature = "full") && input.peek(Token![:]) && !input.peek(Token![::])
+ {
Precedence::Cast
} else {
Precedence::Any
@@ -1488,17 +1494,9 @@ pub(crate) mod parsing {
}))
}
} else if input.peek(Token![box]) {
- Ok(Expr::Box(ExprBox {
- attrs,
- box_token: input.parse()?,
- expr: Box::new(unary_expr(input, allow_struct)?),
- }))
+ expr_box(input, attrs, allow_struct).map(Expr::Box)
} else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
- Ok(Expr::Unary(ExprUnary {
- attrs,
- op: input.parse()?,
- expr: Box::new(unary_expr(input, allow_struct)?),
- }))
+ expr_unary(input, attrs, allow_struct).map(Expr::Unary)
} else {
trailer_expr(attrs, input, allow_struct)
}
@@ -1699,9 +1697,9 @@ pub(crate) mod parsing {
} else if input.peek(Token![async])
&& (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
{
- input.call(expr_async).map(Expr::Async)
+ input.parse().map(Expr::Async)
} else if input.peek(Token![try]) && input.peek2(token::Brace) {
- input.call(expr_try_block).map(Expr::TryBlock)
+ input.parse().map(Expr::TryBlock)
} else if input.peek(Token![|])
|| input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
|| input.peek(Token![static])
@@ -1722,13 +1720,13 @@ pub(crate) mod parsing {
} else if input.peek(Token![break]) {
expr_break(input, allow_struct).map(Expr::Break)
} else if input.peek(Token![continue]) {
- input.call(expr_continue).map(Expr::Continue)
+ input.parse().map(Expr::Continue)
} else if input.peek(Token![return]) {
expr_ret(input, allow_struct).map(Expr::Return)
} else if input.peek(token::Bracket) {
array_or_repeat(input)
} else if input.peek(Token![let]) {
- input.call(expr_let).map(Expr::Let)
+ input.parse().map(Expr::Let)
} else if input.peek(Token![if]) {
input.parse().map(Expr::If)
} else if input.peek(Token![while]) {
@@ -1740,13 +1738,13 @@ pub(crate) mod parsing {
} else if input.peek(Token![match]) {
input.parse().map(Expr::Match)
} else if input.peek(Token![yield]) {
- input.call(expr_yield).map(Expr::Yield)
+ input.parse().map(Expr::Yield)
} else if input.peek(Token![unsafe]) {
- input.call(expr_unsafe).map(Expr::Unsafe)
+ input.parse().map(Expr::Unsafe)
} else if input.peek(Token![const]) {
input.call(expr_const).map(Expr::Verbatim)
} else if input.peek(token::Brace) {
- input.call(expr_block).map(Expr::Block)
+ input.parse().map(Expr::Block)
} else if input.peek(Token![..]) {
expr_range(input, allow_struct).map(Expr::Range)
} else if input.peek(Token![_]) {
@@ -1762,7 +1760,7 @@ pub(crate) mod parsing {
} else if input.peek(Token![loop]) {
Expr::Loop(input.parse()?)
} else if input.peek(token::Brace) {
- Expr::Block(input.call(expr_block)?)
+ Expr::Block(input.parse()?)
} else {
return Err(input.error("expected loop or block expression"));
};
@@ -1841,6 +1839,17 @@ pub(crate) mod parsing {
}
#[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprMacro {
+ attrs: Vec::new(),
+ mac: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
let content;
let paren_token = parenthesized!(content in input);
@@ -1927,6 +1936,48 @@ pub(crate) mod parsing {
}
#[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprArray {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ let bracket_token = bracketed!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let mut elems = Punctuated::new();
+
+ while !content.is_empty() {
+ let first: Expr = content.parse()?;
+ elems.push_value(first);
+ if content.is_empty() {
+ break;
+ }
+ let punct = content.parse()?;
+ elems.push_punct(punct);
+ }
+
+ Ok(ExprArray {
+ attrs: inner_attrs,
+ bracket_token,
+ elems,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprRepeat {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(ExprRepeat {
+ bracket_token: bracketed!(content in input),
+ attrs: content.call(Attribute::parse_inner)?,
+ expr: content.parse()?,
+ semi_token: content.parse()?,
+ len: content.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
pub(crate) fn expr_early(input: ParseStream) -> Result<Expr> {
let mut attrs = input.call(expr_attrs)?;
let mut expr = if input.peek(Token![if]) {
@@ -1940,13 +1991,13 @@ pub(crate) mod parsing {
} else if input.peek(Token![match]) {
Expr::Match(input.parse()?)
} else if input.peek(Token![try]) && input.peek2(token::Brace) {
- Expr::TryBlock(input.call(expr_try_block)?)
+ Expr::TryBlock(input.parse()?)
} else if input.peek(Token![unsafe]) {
- Expr::Unsafe(input.call(expr_unsafe)?)
+ Expr::Unsafe(input.parse()?)
} else if input.peek(Token![const]) {
Expr::Verbatim(input.call(expr_const)?)
} else if input.peek(token::Brace) {
- Expr::Block(input.call(expr_block)?)
+ Expr::Block(input.parse()?)
} else {
let allow_struct = AllowStruct(true);
let mut expr = unary_expr(input, allow_struct)?;
@@ -1992,7 +2043,14 @@ pub(crate) mod parsing {
})
}
- #[cfg(not(feature = "full"))]
+ #[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprParen {
+ fn parse(input: ParseStream) -> Result<Self> {
+ expr_paren(input)
+ }
+ }
+
fn expr_paren(input: ParseStream) -> Result<ExprParen> {
let content;
Ok(ExprParen {
@@ -2010,7 +2068,7 @@ pub(crate) mod parsing {
}
if input.peek(token::Brace) {
- let block = input.call(expr::parsing::expr_block)?;
+ let block: ExprBlock = input.parse()?;
return Ok(GenericMethodArgument::Const(Expr::Block(block)));
}
@@ -2018,14 +2076,17 @@ pub(crate) mod parsing {
}
#[cfg(feature = "full")]
- fn expr_let(input: ParseStream) -> Result<ExprLet> {
- Ok(ExprLet {
- attrs: Vec::new(),
- let_token: input.parse()?,
- pat: pat::parsing::multi_pat_with_leading_vert(input)?,
- eq_token: input.parse()?,
- expr: Box::new(input.call(Expr::parse_without_eager_brace)?),
- })
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprLet {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprLet {
+ attrs: Vec::new(),
+ let_token: input.parse()?,
+ pat: pat::parsing::multi_pat_with_leading_vert(input)?,
+ eq_token: input.parse()?,
+ expr: Box::new(input.call(Expr::parse_without_eager_brace)?),
+ })
+ }
}
#[cfg(feature = "full")]
@@ -2174,63 +2235,139 @@ pub(crate) mod parsing {
}
impl_by_parsing_expr! {
- ExprBox, Box, "expected box expression",
- ExprArray, Array, "expected slice literal expression",
ExprCall, Call, "expected function call expression",
ExprMethodCall, MethodCall, "expected method call expression",
ExprTuple, Tuple, "expected tuple expression",
ExprBinary, Binary, "expected binary operation",
- ExprUnary, Unary, "expected unary operation",
ExprCast, Cast, "expected cast expression",
ExprType, Type, "expected type ascription expression",
- ExprLet, Let, "expected let guard",
- ExprClosure, Closure, "expected closure expression",
- ExprUnsafe, Unsafe, "expected unsafe block",
- ExprBlock, Block, "expected blocked scope",
ExprAssign, Assign, "expected assignment expression",
ExprAssignOp, AssignOp, "expected compound assignment expression",
ExprField, Field, "expected struct field access",
ExprIndex, Index, "expected indexing expression",
ExprRange, Range, "expected range expression",
- ExprReference, Reference, "expected referencing operation",
- ExprBreak, Break, "expected break expression",
- ExprContinue, Continue, "expected continue expression",
- ExprReturn, Return, "expected return expression",
- ExprMacro, Macro, "expected macro invocation expression",
- ExprStruct, Struct, "expected struct literal expression",
- ExprRepeat, Repeat, "expected array literal constructed from one repeated element",
- ExprParen, Paren, "expected parenthesized expression",
ExprTry, Try, "expected try expression",
- ExprAsync, Async, "expected async block",
- ExprTryBlock, TryBlock, "expected try block",
- ExprYield, Yield, "expected yield expression",
}
#[cfg(feature = "full")]
- fn expr_try_block(input: ParseStream) -> Result<ExprTryBlock> {
- Ok(ExprTryBlock {
- attrs: Vec::new(),
- try_token: input.parse()?,
- block: input.parse()?,
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprBox {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = Vec::new();
+ let allow_struct = AllowStruct(true);
+ expr_box(input, attrs, allow_struct)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_box(
+ input: ParseStream,
+ attrs: Vec<Attribute>,
+ allow_struct: AllowStruct,
+ ) -> Result<ExprBox> {
+ Ok(ExprBox {
+ attrs,
+ box_token: input.parse()?,
+ expr: Box::new(unary_expr(input, allow_struct)?),
})
}
#[cfg(feature = "full")]
- fn expr_yield(input: ParseStream) -> Result<ExprYield> {
- Ok(ExprYield {
- attrs: Vec::new(),
- yield_token: input.parse()?,
- expr: {
- if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
- Some(input.parse()?)
- } else {
- None
- }
- },
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprUnary {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = Vec::new();
+ let allow_struct = AllowStruct(true);
+ expr_unary(input, attrs, allow_struct)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_unary(
+ input: ParseStream,
+ attrs: Vec<Attribute>,
+ allow_struct: AllowStruct,
+ ) -> Result<ExprUnary> {
+ Ok(ExprUnary {
+ attrs,
+ op: input.parse()?,
+ expr: Box::new(unary_expr(input, allow_struct)?),
})
}
#[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprClosure {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_struct = AllowStruct(true);
+ expr_closure(input, allow_struct)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprReference {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_struct = AllowStruct(true);
+ Ok(ExprReference {
+ attrs: Vec::new(),
+ and_token: input.parse()?,
+ raw: Reserved::default(),
+ mutability: input.parse()?,
+ expr: Box::new(unary_expr(input, allow_struct)?),
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprBreak {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_struct = AllowStruct(true);
+ expr_break(input, allow_struct)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprReturn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_struct = AllowStruct(true);
+ expr_ret(input, allow_struct)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprTryBlock {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprTryBlock {
+ attrs: Vec::new(),
+ try_token: input.parse()?,
+ block: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprYield {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprYield {
+ attrs: Vec::new(),
+ yield_token: input.parse()?,
+ expr: {
+ if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
+ Some(input.parse()?)
+ } else {
+ None
+ }
+ },
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
let asyncness: Option<Token![async]> = input.parse()?;
let movability: Option<Token![static]> = if asyncness.is_none() {
@@ -2287,13 +2424,16 @@ pub(crate) mod parsing {
}
#[cfg(feature = "full")]
- fn expr_async(input: ParseStream) -> Result<ExprAsync> {
- Ok(ExprAsync {
- attrs: Vec::new(),
- async_token: input.parse()?,
- capture: input.parse()?,
- block: input.parse()?,
- })
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprAsync {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprAsync {
+ attrs: Vec::new(),
+ async_token: input.parse()?,
+ capture: input.parse()?,
+ block: input.parse()?,
+ })
+ }
}
#[cfg(feature = "full")]
@@ -2326,7 +2466,11 @@ pub(crate) mod parsing {
Pat::Type(_) => unreachable!(),
Pat::Verbatim(_) => {}
Pat::Wild(pat) => pat.attrs = attrs,
- Pat::__TestExhaustive(_) => unreachable!(),
+
+ #[cfg(test)]
+ Pat::__TestExhaustive(_) => unimplemented!(),
+ #[cfg(not(test))]
+ _ => unreachable!(),
}
Ok(pat)
}
@@ -2380,12 +2524,15 @@ pub(crate) mod parsing {
}
#[cfg(feature = "full")]
- fn expr_continue(input: ParseStream) -> Result<ExprContinue> {
- Ok(ExprContinue {
- attrs: Vec::new(),
- continue_token: input.parse()?,
- label: input.parse()?,
- })
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprContinue {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprContinue {
+ attrs: Vec::new(),
+ continue_token: input.parse()?,
+ label: input.parse()?,
+ })
+ }
}
#[cfg(feature = "full")]
@@ -2461,6 +2608,16 @@ pub(crate) mod parsing {
}
#[cfg(feature = "full")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprStruct {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = Vec::new();
+ let path: Path = input.parse()?;
+ expr_struct_helper(input, attrs, path)
+ }
+ }
+
+ #[cfg(feature = "full")]
fn expr_struct_helper(
input: ParseStream,
outer_attrs: Vec<Attribute>,
@@ -2507,19 +2664,22 @@ pub(crate) mod parsing {
}
#[cfg(feature = "full")]
- fn expr_unsafe(input: ParseStream) -> Result<ExprUnsafe> {
- let unsafe_token: Token![unsafe] = input.parse()?;
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprUnsafe {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let unsafe_token: Token![unsafe] = input.parse()?;
- let content;
- let brace_token = braced!(content in input);
- let inner_attrs = content.call(Attribute::parse_inner)?;
- let stmts = content.call(Block::parse_within)?;
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
- Ok(ExprUnsafe {
- attrs: inner_attrs,
- unsafe_token,
- block: Block { brace_token, stmts },
- })
+ Ok(ExprUnsafe {
+ attrs: inner_attrs,
+ unsafe_token,
+ block: Block { brace_token, stmts },
+ })
+ }
}
#[cfg(feature = "full")]
@@ -2536,19 +2696,23 @@ pub(crate) mod parsing {
}
#[cfg(feature = "full")]
- pub fn expr_block(input: ParseStream) -> Result<ExprBlock> {
- let label: Option<Label> = input.parse()?;
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprBlock {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+ let label: Option<Label> = input.parse()?;
- let content;
- let brace_token = braced!(content in input);
- let inner_attrs = content.call(Attribute::parse_inner)?;
- let stmts = content.call(Block::parse_within)?;
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
- Ok(ExprBlock {
- attrs: inner_attrs,
- label,
- block: Block { brace_token, stmts },
- })
+ Ok(ExprBlock {
+ attrs: private::attrs(outer_attrs, inner_attrs),
+ label,
+ block: Block { brace_token, stmts },
+ })
+ }
}
#[cfg(feature = "full")]
diff --git a/src/generics.rs b/src/generics.rs
index a78af22e..de0772a7 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -598,6 +598,7 @@ ast_struct! {
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
+ use crate::ext::IdentExt;
use crate::parse::{Parse, ParseStream, Result};
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
@@ -632,6 +633,15 @@ pub mod parsing {
attrs,
..input.parse()?
}));
+ } else if input.peek(Token![_]) {
+ params.push_value(GenericParam::Type(TypeParam {
+ attrs,
+ ident: input.call(Ident::parse_any)?,
+ colon_token: None,
+ bounds: Punctuated::new(),
+ eq_token: None,
+ default: None,
+ }));
} else {
return Err(lookahead.error());
}
@@ -870,7 +880,7 @@ pub mod parsing {
eq_token: {
if input.peek(Token![=]) {
let eq_token = input.parse()?;
- default = Some(input.parse::<Expr>()?);
+ default = Some(path::parsing::const_argument(input)?);
Some(eq_token)
} else {
None
diff --git a/src/item.rs b/src/item.rs
index d5c3b277..10479ab4 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -380,7 +380,11 @@ impl Item {
| Item::Macro(ItemMacro { attrs, .. })
| Item::Macro2(ItemMacro2 { attrs, .. }) => mem::replace(attrs, new),
Item::Verbatim(_) => Vec::new(),
- Item::__TestExhaustive(_) => unreachable!(),
+
+ #[cfg(test)]
+ Item::__TestExhaustive(_) => unimplemented!(),
+ #[cfg(not(test))]
+ _ => unreachable!(),
}
}
}
@@ -982,6 +986,7 @@ pub mod parsing {
use std::iter::{self, FromIterator};
crate::custom_keyword!(existential);
+ crate::custom_keyword!(macro_rules);
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Item {
@@ -1026,24 +1031,31 @@ pub mod parsing {
let static_token = input.parse()?;
let mutability = input.parse()?;
let ident = input.parse()?;
- let colon_token = input.parse()?;
- let ty = input.parse()?;
- if input.peek(Token![;]) {
+ if input.peek(Token![=]) {
+ input.parse::<Token![=]>()?;
+ input.parse::<Expr>()?;
input.parse::<Token![;]>()?;
Ok(Item::Verbatim(verbatim::between(begin, input)))
} else {
- Ok(Item::Static(ItemStatic {
- attrs: Vec::new(),
- vis,
- static_token,
- mutability,
- ident,
- colon_token,
- ty,
- eq_token: input.parse()?,
- expr: input.parse()?,
- semi_token: input.parse()?,
- }))
+ let colon_token = input.parse()?;
+ let ty = input.parse()?;
+ if input.peek(Token![;]) {
+ input.parse::<Token![;]>()?;
+ Ok(Item::Verbatim(verbatim::between(begin, input)))
+ } else {
+ Ok(Item::Static(ItemStatic {
+ attrs: Vec::new(),
+ vis,
+ static_token,
+ mutability,
+ ident,
+ colon_token,
+ ty,
+ eq_token: input.parse()?,
+ expr: input.parse()?,
+ semi_token: input.parse()?,
+ }))
+ }
}
} else if lookahead.peek(Token![const]) {
ahead.parse::<Token![const]>()?;
@@ -1142,6 +1154,10 @@ pub mod parsing {
|| lookahead.peek(Token![::]))
{
input.parse().map(Item::Macro)
+ } else if ahead.peek(macro_rules) {
+ input.advance_to(&ahead);
+ input.parse::<ItemMacro>()?;
+ Ok(Item::Verbatim(verbatim::between(begin, input)))
} else {
Err(lookahead.error())
}?;
@@ -1164,7 +1180,6 @@ pub mod parsing {
semi_token: Token![;],
}
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for FlexibleItemType {
fn parse(input: ParseStream) -> Result<Self> {
let vis: Visibility = input.parse()?;
@@ -1176,14 +1191,14 @@ pub mod parsing {
let mut bounds = Punctuated::new();
if colon_token.is_some() {
loop {
- bounds.push_value(input.parse::<TypeParamBound>()?);
if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
break;
}
- bounds.push_punct(input.parse::<Token![+]>()?);
+ bounds.push_value(input.parse::<TypeParamBound>()?);
if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
break;
}
+ bounds.push_punct(input.parse::<Token![+]>()?);
}
}
generics.where_clause = input.parse()?;
@@ -1497,11 +1512,11 @@ pub mod parsing {
abi,
fn_token,
ident,
+ generics,
paren_token,
inputs,
- output,
variadic,
- generics,
+ output,
})
}
}
@@ -1787,7 +1802,11 @@ pub mod parsing {
ForeignItem::Type(item) => &mut item.attrs,
ForeignItem::Macro(item) => &mut item.attrs,
ForeignItem::Verbatim(_) => return Ok(item),
- ForeignItem::__TestExhaustive(_) => unreachable!(),
+
+ #[cfg(test)]
+ ForeignItem::__TestExhaustive(_) => unimplemented!(),
+ #[cfg(not(test))]
+ _ => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
@@ -2265,7 +2284,12 @@ pub mod parsing {
TraitItem::Method(item) => &mut item.attrs,
TraitItem::Type(item) => &mut item.attrs,
TraitItem::Macro(item) => &mut item.attrs,
- TraitItem::Verbatim(_) | TraitItem::__TestExhaustive(_) => unreachable!(),
+ TraitItem::Verbatim(_) => unreachable!(),
+
+ #[cfg(test)]
+ TraitItem::__TestExhaustive(_) => unimplemented!(),
+ #[cfg(not(test))]
+ _ => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
@@ -2596,7 +2620,11 @@ pub mod parsing {
ImplItem::Type(item) => &mut item.attrs,
ImplItem::Macro(item) => &mut item.attrs,
ImplItem::Verbatim(_) => return Ok(item),
- ImplItem::__TestExhaustive(_) => unreachable!(),
+
+ #[cfg(test)]
+ ImplItem::__TestExhaustive(_) => unimplemented!(),
+ #[cfg(not(test))]
+ _ => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
diff --git a/src/lib.rs b/src/lib.rs
index 2c201c99..ea0c6dde 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -250,7 +250,7 @@
//! 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.60")]
+#![doc(html_root_url = "https://docs.rs/syn/1.0.69")]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![allow(non_camel_case_types)]
// Ignored clippy lints.
@@ -259,13 +259,17 @@
clippy::eval_order_dependence,
clippy::inherent_to_string,
clippy::large_enum_variant,
+ clippy::manual_map, // https://github.com/rust-lang/rust-clippy/issues/6795
clippy::match_on_vec_items,
+ clippy::missing_panics_doc,
clippy::needless_doctest_main,
clippy::needless_pass_by_value,
clippy::never_loop,
clippy::too_many_arguments,
clippy::trivially_copy_pass_by_ref,
- clippy::unnecessary_unwrap
+ clippy::unnecessary_unwrap,
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6983
+ clippy::wrong_self_convention
)]
// Ignored clippy_pedantic lints.
#![allow(
@@ -275,6 +279,8 @@
clippy::expl_impl_clone_on_copy,
clippy::if_not_else,
clippy::match_same_arms,
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
+ clippy::match_wildcard_for_single_variants,
clippy::missing_errors_doc,
clippy::module_name_repetitions,
clippy::must_use_candidate,
diff --git a/src/lifetime.rs b/src/lifetime.rs
index 9cec5eec..28cd7e36 100644
--- a/src/lifetime.rs
+++ b/src/lifetime.rs
@@ -57,6 +57,17 @@ impl Lifetime {
ident: Ident::new(&symbol[1..], span),
}
}
+
+ pub fn span(&self) -> Span {
+ self.apostrophe
+ .join(self.ident.span())
+ .unwrap_or(self.apostrophe)
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.apostrophe = span;
+ self.ident.set_span(span);
+ }
}
impl Display for Lifetime {
diff --git a/src/lit.rs b/src/lit.rs
index d67ee884..0aa50a59 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -505,6 +505,24 @@ impl Display for LitFloat {
}
}
+impl LitBool {
+ pub fn new(value: bool, span: Span) -> Self {
+ LitBool { value, span }
+ }
+
+ pub fn value(&self) -> bool {
+ self.value
+ }
+
+ pub fn span(&self) -> Span {
+ self.span
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.span = span;
+ }
+}
+
#[cfg(feature = "extra-traits")]
mod debug_impls {
use super::*;
diff --git a/src/pat.rs b/src/pat.rs
index 312d3c08..d25843fc 100644
--- a/src/pat.rs
+++ b/src/pat.rs
@@ -523,7 +523,7 @@ pub mod parsing {
attrs,
member,
colon_token: input.parse()?,
- pat: Box::new(multi_pat(input)?),
+ pat: Box::new(multi_pat_with_leading_vert(input)?),
});
}
@@ -602,7 +602,7 @@ pub mod parsing {
let mut elems = Punctuated::new();
while !content.is_empty() {
- let value = multi_pat(&content)?;
+ let value = multi_pat_with_leading_vert(&content)?;
elems.push_value(value);
if content.is_empty() {
break;
@@ -701,7 +701,7 @@ pub mod parsing {
let mut elems = Punctuated::new();
while !content.is_empty() {
- let value = multi_pat(&content)?;
+ let value = multi_pat_with_leading_vert(&content)?;
elems.push_value(value);
if content.is_empty() {
break;
diff --git a/src/path.rs b/src/path.rs
index 3f668c9d..df1788db 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -213,8 +213,6 @@ ast_struct! {
pub mod parsing {
use super::*;
- #[cfg(feature = "full")]
- use crate::expr;
use crate::ext::IdentExt;
use crate::parse::{Parse, ParseStream, Result};
@@ -243,31 +241,76 @@ pub mod parsing {
}
}
- if input.peek(Lit) {
- let lit = input.parse()?;
- return Ok(GenericArgument::Const(Expr::Lit(lit)));
+ if input.peek(Lit) || input.peek(token::Brace) {
+ return const_argument(input).map(GenericArgument::Const);
}
- if input.peek(token::Brace) {
- #[cfg(feature = "full")]
- {
- let block = input.call(expr::parsing::expr_block)?;
- return Ok(GenericArgument::Const(Expr::Block(block)));
- }
+ #[cfg(feature = "full")]
+ let begin = input.fork();
- #[cfg(not(feature = "full"))]
- {
- let begin = input.fork();
- let content;
- braced!(content in input);
- content.parse::<Expr>()?;
+ let argument: Type = input.parse()?;
+
+ #[cfg(feature = "full")]
+ {
+ if match &argument {
+ Type::Path(argument)
+ if argument.qself.is_none()
+ && argument.path.leading_colon.is_none()
+ && argument.path.segments.len() == 1 =>
+ {
+ match argument.path.segments[0].arguments {
+ PathArguments::AngleBracketed(_) => true,
+ _ => false,
+ }
+ }
+ _ => false,
+ } && if input.peek(Token![=]) {
+ input.parse::<Token![=]>()?;
+ input.parse::<Type>()?;
+ true
+ } else if input.peek(Token![:]) {
+ input.parse::<Token![:]>()?;
+ input.call(constraint_bounds)?;
+ true
+ } else {
+ false
+ } {
let verbatim = verbatim::between(begin, input);
- return Ok(GenericArgument::Const(Expr::Verbatim(verbatim)));
+ return Ok(GenericArgument::Type(Type::Verbatim(verbatim)));
}
}
- input.parse().map(GenericArgument::Type)
+ Ok(GenericArgument::Type(argument))
+ }
+ }
+
+ pub fn const_argument(input: ParseStream) -> Result<Expr> {
+ let lookahead = input.lookahead1();
+
+ if input.peek(Lit) {
+ let lit = input.parse()?;
+ return Ok(Expr::Lit(lit));
+ }
+
+ if input.peek(token::Brace) {
+ #[cfg(feature = "full")]
+ {
+ let block: ExprBlock = input.parse()?;
+ return Ok(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(Expr::Verbatim(verbatim));
+ }
}
+
+ Err(lookahead.error())
}
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
@@ -360,26 +403,29 @@ pub mod parsing {
Ok(Constraint {
ident: input.parse()?,
colon_token: input.parse()?,
- bounds: {
- let mut bounds = Punctuated::new();
- loop {
- if input.peek(Token![,]) || input.peek(Token![>]) {
- break;
- }
- let value = input.parse()?;
- bounds.push_value(value);
- if !input.peek(Token![+]) {
- break;
- }
- let punct = input.parse()?;
- bounds.push_punct(punct);
- }
- bounds
- },
+ bounds: constraint_bounds(input)?,
})
}
}
+ #[cfg(feature = "full")]
+ fn constraint_bounds(input: ParseStream) -> Result<Punctuated<TypeParamBound, Token![+]>> {
+ let mut bounds = Punctuated::new();
+ loop {
+ if input.peek(Token![,]) || input.peek(Token![>]) {
+ break;
+ }
+ let value = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ Ok(bounds)
+ }
+
impl Path {
/// Parse a `Path` containing no path arguments on any of its segments.
///
diff --git a/src/punctuated.rs b/src/punctuated.rs
index 4d349697..f94edc29 100644
--- a/src/punctuated.rs
+++ b/src/punctuated.rs
@@ -162,7 +162,11 @@ impl<T, P> Punctuated<T, P> {
/// Panics if the sequence does not already have a trailing punctuation when
/// this method is called.
pub fn push_value(&mut self, value: T) {
- assert!(self.empty_or_trailing());
+ assert!(
+ self.empty_or_trailing(),
+ "Punctuated::push_value: cannot push value if Punctuated is missing trailing punctuation",
+ );
+
self.last = Some(Box::new(value));
}
@@ -174,7 +178,11 @@ impl<T, P> Punctuated<T, P> {
///
/// Panics if the sequence is empty or already has a trailing punctuation.
pub fn push_punct(&mut self, punctuation: P) {
- assert!(self.last.is_some());
+ assert!(
+ self.last.is_some(),
+ "Punctuated::push_punct: cannot push punctuation if Punctuated is empty or already has trailing punctuation",
+ );
+
let last = self.last.take().unwrap();
self.inner.push((*last, punctuation));
}
@@ -228,7 +236,10 @@ impl<T, P> Punctuated<T, P> {
where
P: Default,
{
- assert!(index <= self.len());
+ assert!(
+ index <= self.len(),
+ "Punctuated::insert: index out of range",
+ );
if index == self.len() {
self.push(value);
@@ -454,7 +465,11 @@ impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> {
fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
- assert!(self.empty_or_trailing());
+ assert!(
+ self.empty_or_trailing(),
+ "Punctuated::extend: Punctuated is not empty or does not have a trailing punctuation",
+ );
+
let mut nomore = false;
for pair in i {
if nomore {
diff --git a/tests/common/eq.rs b/tests/common/eq.rs
index 7830163d..944d5851 100644
--- a/tests/common/eq.rs
+++ b/tests/common/eq.rs
@@ -6,18 +6,19 @@ use rustc_ast::ast::{
AngleBracketedArg, AngleBracketedArgs, AnonConst, Arm, AssocItemKind, AssocTyConstraint,
AssocTyConstraintKind, Async, AttrId, AttrItem, AttrKind, AttrStyle, Attribute, BareFnTy,
BinOpKind, BindingMode, Block, BlockCheckMode, BorrowKind, CaptureBy, Const, Crate, CrateSugar,
- Defaultness, EnumDef, Expr, ExprKind, Extern, Field, FieldPat, FloatTy, FnDecl, FnHeader,
- FnRetTy, FnSig, ForeignItemKind, ForeignMod, GenericArg, GenericArgs, GenericBound,
- GenericParam, GenericParamKind, Generics, GlobalAsm, ImplPolarity, InlineAsm, InlineAsmOperand,
- InlineAsmOptions, InlineAsmRegOrRegClass, InlineAsmTemplatePiece, IntTy, IsAuto, Item,
- ItemKind, Label, Lifetime, Lit, LitFloatType, LitIntType, LitKind, LlvmAsmDialect,
- LlvmInlineAsm, LlvmInlineAsmOutput, Local, MacArgs, MacCall, MacCallStmt, MacDelimiter,
- MacStmtStyle, MacroDef, Mod, Movability, MutTy, Mutability, NodeId, Param, ParenthesizedArgs,
- Pat, PatKind, Path, PathSegment, PolyTraitRef, QSelf, RangeEnd, RangeLimits, RangeSyntax, Stmt,
- StmtKind, StrLit, StrStyle, StructField, StructRest, TraitBoundModifier, TraitObjectSyntax,
- TraitRef, Ty, TyKind, UintTy, UnOp, Unsafe, UnsafeSource, UseTree, UseTreeKind, Variant,
- VariantData, Visibility, VisibilityKind, WhereBoundPredicate, WhereClause, WhereEqPredicate,
- WherePredicate, WhereRegionPredicate,
+ Defaultness, EnumDef, Expr, ExprField, ExprKind, Extern, FieldDef, FloatTy, FnDecl, FnHeader,
+ FnKind, FnRetTy, FnSig, ForeignItemKind, ForeignMod, GenericArg, GenericArgs, GenericBound,
+ GenericParam, GenericParamKind, Generics, GlobalAsm, ImplKind, ImplPolarity, Inline, InlineAsm,
+ InlineAsmOperand, InlineAsmOptions, InlineAsmRegOrRegClass, InlineAsmTemplatePiece, IntTy,
+ IsAuto, Item, ItemKind, Label, Lifetime, Lit, LitFloatType, LitIntType, LitKind,
+ LlvmAsmDialect, LlvmInlineAsm, LlvmInlineAsmOutput, Local, MacArgs, MacCall, MacCallStmt,
+ MacDelimiter, MacStmtStyle, MacroDef, ModKind, Movability, MutTy, Mutability, NodeId, Param,
+ ParenthesizedArgs, Pat, PatField, PatKind, Path, PathSegment, PolyTraitRef, QSelf, RangeEnd,
+ RangeLimits, RangeSyntax, Stmt, StmtKind, StrLit, StrStyle, StructExpr, StructRest,
+ TraitBoundModifier, TraitKind, TraitObjectSyntax, TraitRef, Ty, TyAliasKind, TyKind, UintTy,
+ UnOp, Unsafe, UnsafeSource, UseTree, UseTreeKind, Variant, VariantData, Visibility,
+ VisibilityKind, WhereBoundPredicate, WhereClause, WhereEqPredicate, WherePredicate,
+ WhereRegionPredicate,
};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, CommentKind, DelimToken, Nonterminal, Token, TokenKind};
@@ -32,6 +33,12 @@ pub trait SpanlessEq {
fn eq(&self, other: &Self) -> bool;
}
+impl<T: SpanlessEq> SpanlessEq for Box<T> {
+ fn eq(&self, other: &Self) -> bool {
+ SpanlessEq::eq(&**self, &**other)
+ }
+}
+
impl<T: SpanlessEq> SpanlessEq for P<T> {
fn eq(&self, other: &Self) -> bool {
SpanlessEq::eq(&**self, &**other)
@@ -129,47 +136,47 @@ spanless_eq_partial_eq!(token::LitKind);
macro_rules! spanless_eq_struct {
{
- $($name:ident)::+ $(<$param:ident>)?;
- $([$field:ident $other:ident])*
- $(![$ignore:ident])*
+ $($name:ident)::+ $(<$param:ident>)?
+ $([$field:tt $this:ident $other:ident])*
+ $(![$ignore:tt])*;
} => {
impl $(<$param: SpanlessEq>)* SpanlessEq for $($name)::+ $(<$param>)* {
fn eq(&self, other: &Self) -> bool {
- let $($name)::+ { $($field,)* $($ignore: _,)* } = self;
+ let $($name)::+ { $($field: $this,)* $($ignore: _,)* } = self;
let $($name)::+ { $($field: $other,)* $($ignore: _,)* } = other;
- true $(&& SpanlessEq::eq($field, $other))*
+ true $(&& SpanlessEq::eq($this, $other))*
}
}
};
{
- $($name:ident)::+ $(<$param:ident>)?;
- $([$field:ident $other:ident])*
- $(![$ignore:ident])*
- $next:ident
+ $($name:ident)::+ $(<$param:ident>)?
+ $([$field:tt $this:ident $other:ident])*
+ $(![$ignore:tt])*;
+ !$next:tt
$($rest:tt)*
} => {
spanless_eq_struct! {
- $($name)::+ $(<$param>)*;
- $([$field $other])*
- [$next other]
+ $($name)::+ $(<$param>)*
+ $([$field $this $other])*
$(![$ignore])*
+ ![$next];
$($rest)*
}
};
{
- $($name:ident)::+ $(<$param:ident>)?;
- $([$field:ident $other:ident])*
- $(![$ignore:ident])*
- !$next:ident
+ $($name:ident)::+ $(<$param:ident>)?
+ $([$field:tt $this:ident $other:ident])*
+ $(![$ignore:tt])*;
+ $next:tt
$($rest:tt)*
} => {
spanless_eq_struct! {
- $($name)::+ $(<$param>)*;
- $([$field $other])*
- $(![$ignore])*
- ![$next]
+ $($name)::+ $(<$param>)*
+ $([$field $this $other])*
+ [$next this other]
+ $(![$ignore])*;
$($rest)*
}
};
@@ -282,18 +289,20 @@ spanless_eq_struct!(AttrItem; path args tokens);
spanless_eq_struct!(Attribute; kind id style span);
spanless_eq_struct!(BareFnTy; unsafety ext generic_params decl);
spanless_eq_struct!(Block; stmts id rules span tokens);
-spanless_eq_struct!(Crate; module attrs span proc_macros);
+spanless_eq_struct!(Crate; attrs items span proc_macros);
spanless_eq_struct!(EnumDef; variants);
spanless_eq_struct!(Expr; id kind span attrs !tokens);
-spanless_eq_struct!(Field; attrs id span ident expr is_shorthand is_placeholder);
-spanless_eq_struct!(FieldPat; ident pat is_shorthand attrs id span is_placeholder);
+spanless_eq_struct!(ExprField; attrs id span ident expr is_shorthand is_placeholder);
+spanless_eq_struct!(FieldDef; attrs id span vis ident ty is_placeholder);
spanless_eq_struct!(FnDecl; inputs output);
spanless_eq_struct!(FnHeader; constness asyncness unsafety ext);
+spanless_eq_struct!(FnKind; 0 1 2 3);
spanless_eq_struct!(FnSig; header decl span);
spanless_eq_struct!(ForeignMod; unsafety abi items);
spanless_eq_struct!(GenericParam; id ident attrs bounds is_placeholder kind);
spanless_eq_struct!(Generics; params where_clause span);
spanless_eq_struct!(GlobalAsm; asm);
+spanless_eq_struct!(ImplKind; unsafety polarity defaultness constness generics of_trait self_ty items);
spanless_eq_struct!(InlineAsm; template operands options line_spans);
spanless_eq_struct!(Item<K>; attrs id span vis ident kind !tokens);
spanless_eq_struct!(Label; ident);
@@ -305,20 +314,22 @@ spanless_eq_struct!(Local; pat ty init id span attrs !tokens);
spanless_eq_struct!(MacCall; path args prior_type_ascription);
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 inputs_span output);
spanless_eq_struct!(Pat; id kind span tokens);
+spanless_eq_struct!(PatField; ident pat is_shorthand attrs id span is_placeholder);
spanless_eq_struct!(Path; span segments tokens);
spanless_eq_struct!(PathSegment; ident id args);
spanless_eq_struct!(PolyTraitRef; bound_generic_params trait_ref span);
spanless_eq_struct!(QSelf; ty path_span position);
spanless_eq_struct!(Stmt; id kind span);
spanless_eq_struct!(StrLit; style symbol suffix span symbol_unescaped);
-spanless_eq_struct!(StructField; attrs id span vis ident ty is_placeholder);
+spanless_eq_struct!(StructExpr; path fields rest);
spanless_eq_struct!(Token; kind span);
+spanless_eq_struct!(TraitKind; 0 1 2 3 4);
spanless_eq_struct!(TraitRef; path ref_id);
spanless_eq_struct!(Ty; id kind span tokens);
+spanless_eq_struct!(TyAliasKind; 0 1 2 3);
spanless_eq_struct!(UseTree; prefix kind span);
spanless_eq_struct!(Variant; attrs id span !vis ident data disr_expr is_placeholder);
spanless_eq_struct!(Visibility; kind span tokens);
@@ -328,7 +339,7 @@ spanless_eq_struct!(WhereEqPredicate; id span lhs_ty rhs_ty);
spanless_eq_struct!(WhereRegionPredicate; span lifetime bounds);
spanless_eq_struct!(token::Lit; kind symbol suffix);
spanless_eq_enum!(AngleBracketedArg; Arg(0) Constraint(0));
-spanless_eq_enum!(AssocItemKind; Const(0 1 2) Fn(0 1 2 3) TyAlias(0 1 2 3) MacCall(0));
+spanless_eq_enum!(AssocItemKind; Const(0 1 2) Fn(0) TyAlias(0) MacCall(0));
spanless_eq_enum!(AssocTyConstraintKind; Equality(ty) Bound(bounds));
spanless_eq_enum!(Async; Yes(span closure_id return_impl_trait_id) No);
spanless_eq_enum!(AttrStyle; Outer Inner);
@@ -343,12 +354,13 @@ spanless_eq_enum!(Defaultness; Default(0) Final);
spanless_eq_enum!(Extern; None Implicit Explicit(0));
spanless_eq_enum!(FloatTy; F32 F64);
spanless_eq_enum!(FnRetTy; Default(0) Ty(0));
-spanless_eq_enum!(ForeignItemKind; Static(0 1 2) Fn(0 1 2 3) TyAlias(0 1 2 3) MacCall(0));
+spanless_eq_enum!(ForeignItemKind; Static(0 1 2) Fn(0) TyAlias(0) MacCall(0));
spanless_eq_enum!(GenericArg; Lifetime(0) Type(0) Const(0));
spanless_eq_enum!(GenericArgs; AngleBracketed(0) Parenthesized(0));
spanless_eq_enum!(GenericBound; Trait(0 1) Outlives(0));
spanless_eq_enum!(GenericParamKind; Lifetime Type(default) Const(ty kw_span default));
spanless_eq_enum!(ImplPolarity; Positive Negative(0));
+spanless_eq_enum!(Inline; Yes No);
spanless_eq_enum!(InlineAsmRegOrRegClass; Reg(0) RegClass(0));
spanless_eq_enum!(InlineAsmTemplatePiece; String(0) Placeholder(operand_idx modifier span));
spanless_eq_enum!(IntTy; Isize I8 I16 I32 I64 I128);
@@ -359,6 +371,7 @@ spanless_eq_enum!(LlvmAsmDialect; Att Intel);
spanless_eq_enum!(MacArgs; Empty Delimited(0 1 2) Eq(0 1));
spanless_eq_enum!(MacDelimiter; Parenthesis Bracket Brace);
spanless_eq_enum!(MacStmtStyle; Semicolon Braces NoBraces);
+spanless_eq_enum!(ModKind; Loaded(0 1 2) Unloaded);
spanless_eq_enum!(Movability; Static Movable);
spanless_eq_enum!(Mutability; Mut Not);
spanless_eq_enum!(RangeEnd; Included(0) Excluded);
@@ -383,16 +396,14 @@ spanless_eq_enum!(ExprKind; Box(0) Array(0) ConstBlock(0) Call(0 1)
Closure(0 1 2 3 4 5) Block(0 1) Async(0 1 2) Await(0) TryBlock(0)
Assign(0 1 2) AssignOp(0 1 2) Field(0 1) Index(0 1) Underscore Range(0 1 2)
Path(0 1) AddrOf(0 1 2) Break(0 1) Continue(0) Ret(0) InlineAsm(0)
- LlvmInlineAsm(0) MacCall(0) Struct(0 1 2) Repeat(0 1) Paren(0) Try(0)
- Yield(0) Err);
+ LlvmInlineAsm(0) MacCall(0) Struct(0) Repeat(0 1) Paren(0) Try(0) Yield(0)
+ Err);
spanless_eq_enum!(InlineAsmOperand; In(reg expr) Out(reg late expr)
- InOut(reg late expr) SplitInOut(reg late in_expr out_expr) Const(expr)
+ InOut(reg late expr) SplitInOut(reg late in_expr out_expr) Const(anon_const)
Sym(expr));
spanless_eq_enum!(ItemKind; ExternCrate(0) Use(0) Static(0 1 2) Const(0 1 2)
- Fn(0 1 2 3) Mod(0) ForeignMod(0) GlobalAsm(0) TyAlias(0 1 2 3) Enum(0 1)
- Struct(0 1) Union(0 1) Trait(0 1 2 3 4) TraitAlias(0 1)
- Impl(unsafety polarity defaultness constness generics of_trait self_ty items)
- MacCall(0) MacroDef(0));
+ Fn(0) Mod(0 1) ForeignMod(0) GlobalAsm(0) TyAlias(0) Enum(0 1) Struct(0 1)
+ Union(0 1) Trait(0) TraitAlias(0 1) Impl(0) MacCall(0) MacroDef(0));
spanless_eq_enum!(LitKind; Str(0 1) ByteStr(0) Byte(0) Char(0) Int(0 1)
Float(0 1) Bool(0) Err(0));
spanless_eq_enum!(PatKind; Wild Ident(0 1 2) Struct(0 1 2) TupleStruct(0 1)
@@ -467,8 +478,8 @@ impl SpanlessEq for TokenKind {
impl SpanlessEq for TokenStream {
fn eq(&self, other: &Self) -> bool {
- let mut this_trees = self.trees_ref();
- let mut other_trees = other.trees_ref();
+ let mut this_trees = self.trees();
+ let mut other_trees = other.trees();
loop {
let this = match this_trees.next() {
None => return other_trees.next().is_none(),
@@ -478,7 +489,7 @@ impl SpanlessEq for TokenStream {
None => return false,
Some(tree) => tree,
};
- if SpanlessEq::eq(this, other) {
+ if SpanlessEq::eq(&this, &other) {
continue;
}
if let (TokenTree::Token(this), TokenTree::Token(other)) = (this, other) {
@@ -505,7 +516,7 @@ impl SpanlessEq for TokenStream {
fn doc_comment<'a>(
style: AttrStyle,
unescaped: Symbol,
- trees: &mut impl Iterator<Item = &'a TokenTree>,
+ trees: &mut impl Iterator<Item = TokenTree>,
) -> bool {
if match style {
AttrStyle::Outer => false,
@@ -523,12 +534,12 @@ fn doc_comment<'a>(
Some(TokenTree::Delimited(_span, DelimToken::Bracket, stream)) => stream,
_ => return false,
};
- let mut trees = stream.trees_ref();
+ let mut trees = stream.trees();
match trees.next() {
Some(TokenTree::Token(Token {
kind: TokenKind::Ident(symbol, false),
span: _,
- })) if *symbol == sym::doc => {}
+ })) if symbol == sym::doc => {}
_ => return false,
}
match trees.next() {
@@ -540,7 +551,7 @@ fn doc_comment<'a>(
}
match trees.next() {
Some(TokenTree::Token(token)) => {
- is_escaped_literal(token, unescaped) && trees.next().is_none()
+ is_escaped_literal(&token, unescaped) && trees.next().is_none()
}
_ => false,
}
diff --git a/tests/repo/mod.rs b/tests/repo/mod.rs
index afb71273..24b620c5 100644
--- a/tests/repo/mod.rs
+++ b/tests/repo/mod.rs
@@ -8,7 +8,7 @@ use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;
-const REVISION: &str = "72da5a9d85a522b11e80d0fdd1fd95247d442604";
+const REVISION: &str = "52e3dffa50cfffdcfa145c0cc0ba48b49abc0c07";
#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
@@ -27,11 +27,11 @@ static EXCLUDE: &[&str] = &[
"src/test/rustdoc-ui/test-compile-fail3.rs",
"src/test/ui/include-single-expr-helper.rs",
"src/test/ui/include-single-expr-helper-1.rs",
- "src/test/ui/issues/auxiliary/issue-21146-inc.rs",
"src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
"src/test/ui/lint/expansion-time-include.rs",
"src/test/ui/macros/auxiliary/macro-comma-support.rs",
"src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
+ "src/test/ui/parser/auxiliary/issue-21146-inc.rs",
];
pub fn base_dir_filter(entry: &DirEntry) -> bool {
diff --git a/tests/test_item.rs b/tests/test_item.rs
index 7695f199..712c6c6f 100644
--- a/tests/test_item.rs
+++ b/tests/test_item.rs
@@ -241,3 +241,28 @@ fn test_supertraits() {
}
"###);
}
+
+#[test]
+fn test_type_empty_bounds() {
+ #[rustfmt::skip]
+ let tokens = quote! {
+ trait Foo {
+ type Bar: ;
+ }
+ };
+
+ snapshot!(tokens as ItemTrait, @r###"
+ ItemTrait {
+ vis: Inherited,
+ ident: "Foo",
+ generics: Generics,
+ items: [
+ TraitItem::Type {
+ ident: "Bar",
+ generics: Generics,
+ colon_token: Some,
+ },
+ ],
+ }
+ "###);
+}
diff --git a/tests/test_pat.rs b/tests/test_pat.rs
index 399de028..695e4736 100644
--- a/tests/test_pat.rs
+++ b/tests/test_pat.rs
@@ -31,14 +31,14 @@ fn test_leading_vert() {
syn::parse_str::<Item>("fn fun2(|| A: E) {}").unwrap_err();
syn::parse_str::<Stmt>("let | () = ();").unwrap();
- syn::parse_str::<Stmt>("let (| A): E;").unwrap_err();
+ syn::parse_str::<Stmt>("let (| A): E;").unwrap();
syn::parse_str::<Stmt>("let (|| A): (E);").unwrap_err();
- syn::parse_str::<Stmt>("let (| A,): (E,);").unwrap_err();
- syn::parse_str::<Stmt>("let [| A]: [E; 1];").unwrap_err();
+ syn::parse_str::<Stmt>("let (| A,): (E,);").unwrap();
+ syn::parse_str::<Stmt>("let [| A]: [E; 1];").unwrap();
syn::parse_str::<Stmt>("let [|| A]: [E; 1];").unwrap_err();
- syn::parse_str::<Stmt>("let TS(| A): TS;").unwrap_err();
+ syn::parse_str::<Stmt>("let TS(| A): TS;").unwrap();
syn::parse_str::<Stmt>("let TS(|| A): TS;").unwrap_err();
- syn::parse_str::<Stmt>("let NS { f: | A }: NS;").unwrap_err();
+ syn::parse_str::<Stmt>("let NS { f: | A }: NS;").unwrap();
syn::parse_str::<Stmt>("let NS { f: || A }: NS;").unwrap_err();
}
diff --git a/tests/test_precedence.rs b/tests/test_precedence.rs
index 4b4cb2fb..3eb2d348 100644
--- a/tests/test_precedence.rs
+++ b/tests/test_precedence.rs
@@ -195,19 +195,21 @@ fn librustc_parse_and_rewrite(input: &str) -> Option<P<ast::Expr>> {
/// This method operates on librustc objects.
fn librustc_brackets(mut librustc_expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
use rustc_ast::ast::{
- Block, BorrowKind, Expr, ExprKind, Field, GenericArg, Pat, Stmt, StmtKind, StructRest, Ty,
+ Block, BorrowKind, Expr, ExprField, ExprKind, GenericArg, Pat, Stmt, StmtKind, StructExpr,
+ StructRest, Ty,
};
use rustc_ast::mut_visit::{noop_visit_generic_arg, MutVisitor};
use rustc_data_structures::map_in_place::MapInPlace;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_span::DUMMY_SP;
use std::mem;
+ use std::ops::DerefMut;
struct BracketsVisitor {
failed: bool,
}
- fn flat_map_field<T: MutVisitor>(mut f: Field, vis: &mut T) -> Vec<Field> {
+ fn flat_map_field<T: MutVisitor>(mut f: ExprField, vis: &mut T) -> Vec<ExprField> {
if f.is_shorthand {
noop_visit_expr(&mut f.expr, vis);
} else {
@@ -237,11 +239,12 @@ fn librustc_brackets(mut librustc_expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
use rustc_ast::mut_visit::{noop_visit_expr, visit_thin_attrs};
match &mut e.kind {
ExprKind::AddrOf(BorrowKind::Raw, ..) => {}
- ExprKind::Struct(path, fields, expr) => {
+ ExprKind::Struct(expr) => {
+ let StructExpr { path, fields, rest } = expr.deref_mut();
vis.visit_path(path);
fields.flat_map_in_place(|field| flat_map_field(field, vis));
- if let StructRest::Base(expr) = expr {
- vis.visit_expr(expr);
+ if let StructRest::Base(rest) = rest {
+ vis.visit_expr(rest);
}
vis.visit_id(&mut e.id);
vis.visit_span(&mut e.span);