1
Fork 0

Auto merge of #82929 - m-ou-se:rollup-7fwrewh, r=m-ou-se

Rollup of 8 pull requests

Successful merges:

 - #81127 (Improve sift_down performance in BinaryHeap)
 - #81879 (Added #[repr(transparent)] to core::cmp::Reverse)
 - #82048 (or-patterns: disallow in `let` bindings)
 - #82731 (Bump libc dependency of std to 0.2.88.)
 - #82799 (Add regression test for #75525)
 - #82841 (Change x64 size checks to not apply to x32.)
 - #82883 (Update Cargo)
 - #82887 (Update CONTRIBUTING.md)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-03-09 09:43:55 +00:00
commit 3a5d45f68c
67 changed files with 767 additions and 425 deletions

View file

@ -1,8 +1,31 @@
# Contributing to Rust # Contributing to Rust
Thank you for your interest in contributing to Rust! Thank you for your interest in contributing to Rust! There are many ways to contribute
and we appreciate all of them.
To get started, read the [Contributing to Rust] chapter of the [rustc-dev-guide]. Documentation for contributing to Rust is located in the [Guide to Rustc Development](https://rustc-dev-guide.rust-lang.org/),
commonly known as the [rustc-dev-guide]. Despite the name, this guide documents
not just how to develop rustc (the Rust compiler), but also how to contribute to any part
of the Rust project.
To get started with contributing, please read the [Contributing to Rust] chapter of the guide.
That chapter explains how to get your development environment set up and how to get help.
## About the [rustc-dev-guide]
The [rustc-dev-guide] is meant to help document how rustc the Rust compiler works,
as well as to help new contributors get involved in rustc development. It is recommend
to read and understand the [rustc-dev-guide] before making a contribution. This guide
talks about the different bots in the Rust ecosystem, the Rust development tools,
bootstrapping, the compiler architecture, source code representation, and more.
## [Getting help](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions)
There are many ways you can get help when you're stuck. Rust has many platforms for this:
[internals], [rust-zulip], and [rust-discord]. It is recommended to ask for help on
the [rust-zulip], but any of these platforms are a great way to seek help and even
find a mentor! You can learn more about asking questions and getting help in the
[Asking Questions](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions) chapter of the [rustc-dev-guide].
## Bug reports ## Bug reports
@ -13,3 +36,6 @@ refer to [this section][contributing-bug-reports] and [open an issue][issue temp
[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/ [rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
[contributing-bug-reports]: https://rustc-dev-guide.rust-lang.org/contributing.html#bug-reports [contributing-bug-reports]: https://rustc-dev-guide.rust-lang.org/contributing.html#bug-reports
[issue template]: https://github.com/rust-lang/rust/issues/new/choose [issue template]: https://github.com/rust-lang/rust/issues/new/choose
[internals]: https://internals.rust-lang.org
[rust-discord]: http://discord.gg/rust-lang
[rust-zulip]: https://rust-lang.zulipchat.com

View file

@ -37,7 +37,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"compiler_builtins", "compiler_builtins",
"core", "core",
"rand", "rand 0.7.3",
"rand_xorshift", "rand_xorshift",
] ]
@ -325,6 +325,7 @@ dependencies = [
"openssl", "openssl",
"percent-encoding 2.1.0", "percent-encoding 2.1.0",
"pretty_env_logger", "pretty_env_logger",
"rand 0.8.3",
"rustc-workspace-hack", "rustc-workspace-hack",
"rustfix", "rustfix",
"same-file", "same-file",
@ -757,7 +758,7 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
name = "core" name = "core"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"rand", "rand 0.7.3",
] ]
[[package]] [[package]]
@ -1662,7 +1663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f" checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
dependencies = [ dependencies = [
"bitmaps", "bitmaps",
"rand_core", "rand_core 0.5.1",
"rand_xoshiro", "rand_xoshiro",
"sized-chunks", "sized-chunks",
"typenum", "typenum",
@ -1867,7 +1868,7 @@ dependencies = [
"lazy_static", "lazy_static",
"log", "log",
"parking_lot", "parking_lot",
"rand", "rand 0.7.3",
"serde", "serde",
] ]
@ -1912,9 +1913,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.85" version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
dependencies = [ dependencies = [
"rustc-std-workspace-core", "rustc-std-workspace-core",
] ]
@ -2308,7 +2309,7 @@ dependencies = [
"hex 0.4.2", "hex 0.4.2",
"libc", "libc",
"log", "log",
"rand", "rand 0.7.3",
"rustc-workspace-hack", "rustc-workspace-hack",
"rustc_version", "rustc_version",
"shell-escape", "shell-escape",
@ -2508,7 +2509,7 @@ dependencies = [
"log", "log",
"mio-named-pipes", "mio-named-pipes",
"miow 0.3.6", "miow 0.3.6",
"rand", "rand 0.7.3",
"tokio", "tokio",
"winapi 0.3.9", "winapi 0.3.9",
] ]
@ -2645,7 +2646,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [ dependencies = [
"phf_shared", "phf_shared",
"rand", "rand 0.7.3",
] ]
[[package]] [[package]]
@ -2892,12 +2893,24 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [ dependencies = [
"getrandom 0.1.14", "getrandom 0.1.14",
"libc", "libc",
"rand_chacha", "rand_chacha 0.2.2",
"rand_core", "rand_core 0.5.1",
"rand_hc", "rand_hc 0.2.0",
"rand_pcg", "rand_pcg",
] ]
[[package]]
name = "rand"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
dependencies = [
"libc",
"rand_chacha 0.3.0",
"rand_core 0.6.2",
"rand_hc 0.3.0",
]
[[package]] [[package]]
name = "rand_chacha" name = "rand_chacha"
version = "0.2.2" version = "0.2.2"
@ -2905,7 +2918,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core", "rand_core 0.5.1",
]
[[package]]
name = "rand_chacha"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
"ppv-lite86",
"rand_core 0.6.2",
] ]
[[package]] [[package]]
@ -2917,13 +2940,31 @@ dependencies = [
"getrandom 0.1.14", "getrandom 0.1.14",
] ]
[[package]]
name = "rand_core"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
dependencies = [
"getrandom 0.2.0",
]
[[package]] [[package]]
name = "rand_hc" name = "rand_hc"
version = "0.2.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [ dependencies = [
"rand_core", "rand_core 0.5.1",
]
[[package]]
name = "rand_hc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
dependencies = [
"rand_core 0.6.2",
] ]
[[package]] [[package]]
@ -2932,7 +2973,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
dependencies = [ dependencies = [
"rand_core", "rand_core 0.5.1",
] ]
[[package]] [[package]]
@ -2941,7 +2982,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8"
dependencies = [ dependencies = [
"rand_core", "rand_core 0.5.1",
] ]
[[package]] [[package]]
@ -2950,7 +2991,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004" checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
dependencies = [ dependencies = [
"rand_core", "rand_core 0.5.1",
] ]
[[package]] [[package]]
@ -3082,7 +3123,7 @@ dependencies = [
"num_cpus", "num_cpus",
"ordslice", "ordslice",
"racer", "racer",
"rand", "rand 0.7.3",
"rayon", "rayon",
"regex", "regex",
"rls-analysis", "rls-analysis",
@ -3153,7 +3194,7 @@ dependencies = [
"env_logger 0.7.1", "env_logger 0.7.1",
"futures 0.3.12", "futures 0.3.12",
"log", "log",
"rand", "rand 0.7.3",
"rls-data", "rls-data",
"rls-ipc", "rls-ipc",
"serde", "serde",
@ -3933,7 +3974,7 @@ dependencies = [
name = "rustc_incremental" name = "rustc_incremental"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"rand", "rand 0.7.3",
"rustc_ast", "rustc_ast",
"rustc_data_structures", "rustc_data_structures",
"rustc_fs_util", "rustc_fs_util",
@ -4975,7 +5016,7 @@ dependencies = [
"panic_abort", "panic_abort",
"panic_unwind", "panic_unwind",
"profiler_builtins", "profiler_builtins",
"rand", "rand 0.7.3",
"rustc-demangle", "rustc-demangle",
"unwind", "unwind",
"wasi", "wasi",
@ -5106,7 +5147,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [ dependencies = [
"cfg-if 0.1.10", "cfg-if 0.1.10",
"libc", "libc",
"rand", "rand 0.7.3",
"redox_syscall 0.1.57", "redox_syscall 0.1.57",
"remove_dir_all", "remove_dir_all",
"winapi 0.3.9", "winapi 0.3.9",

View file

@ -1073,7 +1073,7 @@ pub struct Expr {
} }
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Expr, 120); rustc_data_structures::static_assert_size!(Expr, 120);
impl Expr { impl Expr {
@ -2755,7 +2755,7 @@ pub enum ItemKind {
MacroDef(MacroDef), MacroDef(MacroDef),
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(ItemKind, 112); rustc_data_structures::static_assert_size!(ItemKind, 112);
impl ItemKind { impl ItemKind {
@ -2829,7 +2829,7 @@ pub enum AssocItemKind {
MacCall(MacCall), MacCall(MacCall),
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(AssocItemKind, 72); rustc_data_structures::static_assert_size!(AssocItemKind, 72);
impl AssocItemKind { impl AssocItemKind {
@ -2881,7 +2881,7 @@ pub enum ForeignItemKind {
MacCall(MacCall), MacCall(MacCall),
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(ForeignItemKind, 72); rustc_data_structures::static_assert_size!(ForeignItemKind, 72);
impl From<ForeignItemKind> for ItemKind { impl From<ForeignItemKind> for ItemKind {

View file

@ -244,7 +244,7 @@ pub enum TokenKind {
} }
// `TokenKind` is used a lot. Make sure it doesn't unintentionally get bigger. // `TokenKind` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(TokenKind, 16); rustc_data_structures::static_assert_size!(TokenKind, 16);
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] #[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
@ -682,7 +682,7 @@ pub enum Nonterminal {
} }
// `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger. // `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Nonterminal, 48); rustc_data_structures::static_assert_size!(Nonterminal, 48);
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)] #[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]

View file

@ -189,7 +189,7 @@ pub struct TokenStream(pub(crate) Lrc<Vec<TreeAndSpacing>>);
pub type TreeAndSpacing = (TokenTree, Spacing); pub type TreeAndSpacing = (TokenTree, Spacing);
// `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger. // `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(TokenStream, 8); rustc_data_structures::static_assert_size!(TokenStream, 8);
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable)] #[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable)]

View file

@ -52,7 +52,7 @@ pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
// (See also the comment on `DiagnosticBuilderInner`.) // (See also the comment on `DiagnosticBuilderInner`.)
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16); rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16);
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]

View file

@ -3088,7 +3088,7 @@ impl<'hir> Node<'hir> {
} }
// Some nodes are used a lot. Make sure they don't unintentionally get bigger. // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts { mod size_asserts {
rustc_data_structures::static_assert_size!(super::Block<'static>, 48); rustc_data_structures::static_assert_size!(super::Block<'static>, 48);
rustc_data_structures::static_assert_size!(super::Expr<'static>, 72); rustc_data_structures::static_assert_size!(super::Expr<'static>, 72);

View file

@ -408,7 +408,7 @@ pub enum SubregionOrigin<'tcx> {
} }
// `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger. // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(SubregionOrigin<'_>, 32); static_assert_size!(SubregionOrigin<'_>, 32);
/// Times when we replace late-bound regions with variables: /// Times when we replace late-bound regions with variables:

View file

@ -27,7 +27,7 @@
#[macro_use] #[macro_use]
extern crate rustc_macros; extern crate rustc_macros;
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
#[macro_use] #[macro_use]
extern crate rustc_data_structures; extern crate rustc_data_structures;
#[macro_use] #[macro_use]

View file

@ -56,7 +56,7 @@ pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(PredicateObligation<'_>, 32); static_assert_size!(PredicateObligation<'_>, 32);
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>; pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;

View file

@ -872,7 +872,7 @@ impl EarlyLintPass for UnusedParens {
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) { fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
if let StmtKind::Local(ref local) = s.kind { if let StmtKind::Local(ref local) = s.kind {
self.check_unused_parens_pat(cx, &local.pat, false, false); self.check_unused_parens_pat(cx, &local.pat, true, false);
} }
<Self as UnusedDelimLint>::check_stmt(self, cx, s) <Self as UnusedDelimLint>::check_stmt(self, cx, s)

View file

@ -40,7 +40,7 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg) struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(InterpErrorInfo<'_>, 8); static_assert_size!(InterpErrorInfo<'_>, 8);
/// Packages the kind of error we got from the const code interpreter /// Packages the kind of error we got from the const code interpreter
@ -444,7 +444,7 @@ impl dyn MachineStopType {
} }
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(InterpError<'_>, 72); static_assert_size!(InterpError<'_>, 72);
pub enum InterpError<'tcx> { pub enum InterpError<'tcx> {

View file

@ -44,7 +44,7 @@ pub enum ConstValue<'tcx> {
}, },
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(ConstValue<'_>, 32); static_assert_size!(ConstValue<'_>, 32);
impl<'tcx> ConstValue<'tcx> { impl<'tcx> ConstValue<'tcx> {
@ -111,7 +111,7 @@ pub enum Scalar<Tag = ()> {
Ptr(Pointer<Tag>), Ptr(Pointer<Tag>),
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(Scalar, 24); static_assert_size!(Scalar, 24);
// We want the `Debug` output to be readable as it is used by `derive(Debug)` for // We want the `Debug` output to be readable as it is used by `derive(Debug)` for
@ -509,7 +509,7 @@ pub enum ScalarMaybeUninit<Tag = ()> {
Uninit, Uninit,
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(ScalarMaybeUninit, 24); static_assert_size!(ScalarMaybeUninit, 24);
impl<Tag> From<Scalar<Tag>> for ScalarMaybeUninit<Tag> { impl<Tag> From<Scalar<Tag>> for ScalarMaybeUninit<Tag> {

View file

@ -951,7 +951,7 @@ pub struct LocalDecl<'tcx> {
} }
// `LocalDecl` is used a lot. Make sure it doesn't unintentionally get bigger. // `LocalDecl` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(LocalDecl<'_>, 56); static_assert_size!(LocalDecl<'_>, 56);
/// Extra information about a some locals that's used for diagnostics and for /// Extra information about a some locals that's used for diagnostics and for
@ -1468,7 +1468,7 @@ pub struct Statement<'tcx> {
} }
// `Statement` is used a lot. Make sure it doesn't unintentionally get bigger. // `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(Statement<'_>, 32); static_assert_size!(Statement<'_>, 32);
impl Statement<'_> { impl Statement<'_> {
@ -1755,7 +1755,7 @@ impl<V, T> ProjectionElem<V, T> {
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>; pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
// At least on 64 bit systems, `PlaceElem` should not be larger than two pointers. // At least on 64 bit systems, `PlaceElem` should not be larger than two pointers.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(PlaceElem<'_>, 24); static_assert_size!(PlaceElem<'_>, 24);
/// Alias for projections as they appear in `UserTypeProjection`, where we /// Alias for projections as they appear in `UserTypeProjection`, where we

View file

@ -17,7 +17,7 @@ pub struct PlaceTy<'tcx> {
} }
// At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers. // At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(PlaceTy<'_>, 16); static_assert_size!(PlaceTy<'_>, 16);
impl<'tcx> PlaceTy<'tcx> { impl<'tcx> PlaceTy<'tcx> {

View file

@ -340,7 +340,7 @@ impl ObligationCauseCode<'_> {
} }
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(ObligationCauseCode<'_>, 32); static_assert_size!(ObligationCauseCode<'_>, 32);
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]

View file

@ -23,7 +23,7 @@ pub struct Const<'tcx> {
pub val: ConstKind<'tcx>, pub val: ConstKind<'tcx>,
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(Const<'_>, 48); static_assert_size!(Const<'_>, 48);
impl<'tcx> Const<'tcx> { impl<'tcx> Const<'tcx> {

View file

@ -37,7 +37,7 @@ pub enum ConstKind<'tcx> {
Error(ty::DelaySpanBugEmitted), Error(ty::DelaySpanBugEmitted),
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(ConstKind<'_>, 40); static_assert_size!(ConstKind<'_>, 40);
impl<'tcx> ConstKind<'tcx> { impl<'tcx> ConstKind<'tcx> {

View file

@ -483,7 +483,7 @@ impl<'tcx> TyS<'tcx> {
} }
// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger. // `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(TyS<'_>, 32); static_assert_size!(TyS<'_>, 32);
impl<'tcx> Ord for TyS<'tcx> { impl<'tcx> Ord for TyS<'tcx> {
@ -1030,7 +1030,7 @@ crate struct PredicateInner<'tcx> {
outer_exclusive_binder: ty::DebruijnIndex, outer_exclusive_binder: ty::DebruijnIndex,
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(PredicateInner<'_>, 40); static_assert_size!(PredicateInner<'_>, 40);
#[derive(Clone, Copy, Lift)] #[derive(Clone, Copy, Lift)]

View file

@ -231,7 +231,7 @@ impl TyKind<'tcx> {
} }
// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger. // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(TyKind<'_>, 24); static_assert_size!(TyKind<'_>, 24);
/// A closure can be modeled as a struct that looks like: /// A closure can be modeled as a struct that looks like:

View file

@ -32,7 +32,7 @@ pub enum Immediate<Tag = ()> {
ScalarPair(ScalarMaybeUninit<Tag>, ScalarMaybeUninit<Tag>), ScalarPair(ScalarMaybeUninit<Tag>, ScalarMaybeUninit<Tag>),
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Immediate, 56); rustc_data_structures::static_assert_size!(Immediate, 56);
impl<Tag> From<ScalarMaybeUninit<Tag>> for Immediate<Tag> { impl<Tag> From<ScalarMaybeUninit<Tag>> for Immediate<Tag> {
@ -95,7 +95,7 @@ pub struct ImmTy<'tcx, Tag = ()> {
pub layout: TyAndLayout<'tcx>, pub layout: TyAndLayout<'tcx>,
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(ImmTy<'_>, 72); rustc_data_structures::static_assert_size!(ImmTy<'_>, 72);
impl<Tag: Copy> std::fmt::Display for ImmTy<'tcx, Tag> { impl<Tag: Copy> std::fmt::Display for ImmTy<'tcx, Tag> {
@ -162,7 +162,7 @@ pub struct OpTy<'tcx, Tag = ()> {
pub layout: TyAndLayout<'tcx>, pub layout: TyAndLayout<'tcx>,
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(OpTy<'_, ()>, 80); rustc_data_structures::static_assert_size!(OpTy<'_, ()>, 80);
impl<'tcx, Tag> std::ops::Deref for OpTy<'tcx, Tag> { impl<'tcx, Tag> std::ops::Deref for OpTy<'tcx, Tag> {

View file

@ -33,7 +33,7 @@ pub enum MemPlaceMeta<Tag = ()> {
Poison, Poison,
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(MemPlaceMeta, 24); rustc_data_structures::static_assert_size!(MemPlaceMeta, 24);
impl<Tag> MemPlaceMeta<Tag> { impl<Tag> MemPlaceMeta<Tag> {
@ -74,7 +74,7 @@ pub struct MemPlace<Tag = ()> {
pub meta: MemPlaceMeta<Tag>, pub meta: MemPlaceMeta<Tag>,
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(MemPlace, 56); rustc_data_structures::static_assert_size!(MemPlace, 56);
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
@ -87,7 +87,7 @@ pub enum Place<Tag = ()> {
Local { frame: usize, local: mir::Local }, Local { frame: usize, local: mir::Local },
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Place, 64); rustc_data_structures::static_assert_size!(Place, 64);
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@ -96,7 +96,7 @@ pub struct PlaceTy<'tcx, Tag = ()> {
pub layout: TyAndLayout<'tcx>, pub layout: TyAndLayout<'tcx>,
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(PlaceTy<'_>, 80); rustc_data_structures::static_assert_size!(PlaceTy<'_>, 80);
impl<'tcx, Tag> std::ops::Deref for PlaceTy<'tcx, Tag> { impl<'tcx, Tag> std::ops::Deref for PlaceTy<'tcx, Tag> {
@ -114,7 +114,7 @@ pub struct MPlaceTy<'tcx, Tag = ()> {
pub layout: TyAndLayout<'tcx>, pub layout: TyAndLayout<'tcx>,
} }
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(MPlaceTy<'_>, 72); rustc_data_structures::static_assert_size!(MPlaceTy<'_>, 72);
impl<'tcx, Tag> std::ops::Deref for MPlaceTy<'tcx, Tag> { impl<'tcx, Tag> std::ops::Deref for MPlaceTy<'tcx, Tag> {

View file

@ -96,7 +96,7 @@ crate enum StmtKind<'tcx> {
} }
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Expr<'_>, 168); rustc_data_structures::static_assert_size!(Expr<'_>, 168);
/// The Thir trait implementor lowers their expressions (`&'tcx H::Expr`) /// The Thir trait implementor lowers their expressions (`&'tcx H::Expr`)

View file

@ -1757,8 +1757,9 @@ impl<'a> Parser<'a> {
let (pat, ty) = if is_name_required || this.is_named_param() { let (pat, ty) = if is_name_required || this.is_named_param() {
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required); debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
let pat = this.parse_fn_param_pat()?; let (pat, colon) = this.parse_fn_param_pat_colon()?;
if let Err(mut err) = this.expect(&token::Colon) { if !colon {
let mut err = this.unexpected::<()>().unwrap_err();
return if let Some(ident) = return if let Some(ident) =
this.parameter_without_type(&mut err, pat, is_name_required, first_param) this.parameter_without_type(&mut err, pat, is_name_required, first_param)
{ {

View file

@ -31,6 +31,18 @@ pub enum RecoverComma {
No, No,
} }
/// The result of `eat_or_separator`. We want to distinguish which case we are in to avoid
/// emitting duplicate diagnostics.
#[derive(Debug, Clone, Copy)]
enum EatOrResult {
/// We recovered from a trailing vert.
TrailingVert,
/// We ate an `|` (or `||` and recovered).
AteOr,
/// We did not eat anything (i.e. the current token is not `|` or `||`).
None,
}
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
/// Parses a pattern. /// Parses a pattern.
/// ///
@ -55,9 +67,26 @@ impl<'a> Parser<'a> {
gate_or: GateOr, gate_or: GateOr,
rc: RecoverComma, rc: RecoverComma,
) -> PResult<'a, P<Pat>> { ) -> PResult<'a, P<Pat>> {
self.parse_pat_allow_top_alt_inner(expected, gate_or, rc).map(|(pat, _)| pat)
}
/// Returns the pattern and a bool indicating whether we recovered from a trailing vert (true =
/// recovered).
fn parse_pat_allow_top_alt_inner(
&mut self,
expected: Expected,
gate_or: GateOr,
rc: RecoverComma,
) -> PResult<'a, (P<Pat>, bool)> {
// Keep track of whether we recovered from a trailing vert so that we can avoid duplicated
// suggestions (which bothers rustfix).
//
// Allow a '|' before the pats (RFCs 1925, 2530, and 2535). // Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
let leading_vert_span = let (leading_vert_span, mut trailing_vert) = match self.eat_or_separator(None) {
if self.eat_or_separator(None) { Some(self.prev_token.span) } else { None }; EatOrResult::AteOr => (Some(self.prev_token.span), false),
EatOrResult::TrailingVert => (None, true),
EatOrResult::None => (None, false),
};
// Parse the first pattern (`p_0`). // Parse the first pattern (`p_0`).
let first_pat = self.parse_pat_no_top_alt(expected)?; let first_pat = self.parse_pat_no_top_alt(expected)?;
@ -77,16 +106,24 @@ impl<'a> Parser<'a> {
// If there was a leading vert, treat this as an or-pattern. This improves // If there was a leading vert, treat this as an or-pattern. This improves
// diagnostics. // diagnostics.
let span = leading_vert_span.to(self.prev_token.span); let span = leading_vert_span.to(self.prev_token.span);
return Ok(self.mk_pat(span, PatKind::Or(vec![first_pat]))); return Ok((self.mk_pat(span, PatKind::Or(vec![first_pat])), trailing_vert));
} }
return Ok(first_pat); return Ok((first_pat, trailing_vert));
} }
// Parse the patterns `p_1 | ... | p_n` where `n > 0`. // Parse the patterns `p_1 | ... | p_n` where `n > 0`.
let lo = leading_vert_span.unwrap_or(first_pat.span); let lo = leading_vert_span.unwrap_or(first_pat.span);
let mut pats = vec![first_pat]; let mut pats = vec![first_pat];
while self.eat_or_separator(Some(lo)) { loop {
match self.eat_or_separator(Some(lo)) {
EatOrResult::AteOr => {}
EatOrResult::None => break,
EatOrResult::TrailingVert => {
trailing_vert = true;
break;
}
}
let pat = self.parse_pat_no_top_alt(expected).map_err(|mut err| { let pat = self.parse_pat_no_top_alt(expected).map_err(|mut err| {
err.span_label(lo, WHILE_PARSING_OR_MSG); err.span_label(lo, WHILE_PARSING_OR_MSG);
err err
@ -101,15 +138,63 @@ impl<'a> Parser<'a> {
self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span); self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span);
} }
Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats))) Ok((self.mk_pat(or_pattern_span, PatKind::Or(pats)), trailing_vert))
} }
/// Parse the pattern for a function or function pointer parameter. /// Parse a pattern and (maybe) a `Colon` in positions where a pattern may be followed by a
pub(super) fn parse_fn_param_pat(&mut self) -> PResult<'a, P<Pat>> { /// type annotation (e.g. for `let` bindings or `fn` params).
// We actually do _not_ allow top-level or-patterns in function params, but we use ///
// `parse_pat_allow_top_alt` anyway so that we can detect when a user tries to use it. This /// Generally, this corresponds to `pat_no_top_alt` followed by an optional `Colon`. It will
// allows us to print a better error message. /// eat the `Colon` token if one is present.
// ///
/// The return value represents the parsed pattern and `true` if a `Colon` was parsed (`false`
/// otherwise).
pub(super) fn parse_pat_before_ty(
&mut self,
expected: Expected,
gate_or: GateOr,
rc: RecoverComma,
syntax_loc: &str,
) -> PResult<'a, (P<Pat>, bool)> {
// We use `parse_pat_allow_top_alt` regardless of whether we actually want top-level
// or-patterns so that we can detect when a user tries to use it. This allows us to print a
// better error message.
let (pat, trailing_vert) = self.parse_pat_allow_top_alt_inner(expected, gate_or, rc)?;
let colon = self.eat(&token::Colon);
if let PatKind::Or(pats) = &pat.kind {
let msg = format!("top-level or-patterns are not allowed in {}", syntax_loc);
let (help, fix) = if pats.len() == 1 {
// If all we have is a leading vert, then print a special message. This is the case
// if `parse_pat_allow_top_alt` returns an or-pattern with one variant.
let msg = "remove the `|`";
let fix = pprust::pat_to_string(&pat);
(msg, fix)
} else {
let msg = "wrap the pattern in parentheses";
let fix = format!("({})", pprust::pat_to_string(&pat));
(msg, fix)
};
if trailing_vert {
// We already emitted an error and suggestion to remove the trailing vert. Don't
// emit again.
self.sess.span_diagnostic.delay_span_bug(pat.span, &msg);
} else {
self.struct_span_err(pat.span, &msg)
.span_suggestion(pat.span, help, fix, Applicability::MachineApplicable)
.emit();
}
}
Ok((pat, colon))
}
/// Parse the pattern for a function or function pointer parameter, followed by a colon.
///
/// The return value represents the parsed pattern and `true` if a `Colon` was parsed (`false`
/// otherwise).
pub(super) fn parse_fn_param_pat_colon(&mut self) -> PResult<'a, (P<Pat>, bool)> {
// In order to get good UX, we first recover in the case of a leading vert for an illegal // In order to get good UX, we first recover in the case of a leading vert for an illegal
// top-level or-pat. Normally, this means recovering both `|` and `||`, but in this case, // top-level or-pat. Normally, this means recovering both `|` and `||`, but in this case,
// a leading `||` probably doesn't indicate an or-pattern attempt, so we handle that // a leading `||` probably doesn't indicate an or-pattern attempt, so we handle that
@ -128,53 +213,28 @@ impl<'a> Parser<'a> {
self.bump(); self.bump();
} }
let pat = self.parse_pat_allow_top_alt(PARAM_EXPECTED, GateOr::No, RecoverComma::No)?; self.parse_pat_before_ty(
PARAM_EXPECTED,
if let PatKind::Or(..) = &pat.kind { GateOr::No,
self.ban_illegal_fn_param_or_pat(&pat); RecoverComma::No,
} "function parameters",
)
Ok(pat)
}
/// Ban `A | B` immediately in a parameter pattern and suggest wrapping in parens.
fn ban_illegal_fn_param_or_pat(&self, pat: &Pat) {
// If all we have a leading vert, then print a special message. This is the case if
// `parse_pat_allow_top_alt` returns an or-pattern with one variant.
let (msg, fix) = match &pat.kind {
PatKind::Or(pats) if pats.len() == 1 => {
let msg = "remove the leading `|`";
let fix = pprust::pat_to_string(pat);
(msg, fix)
}
_ => {
let msg = "wrap the pattern in parentheses";
let fix = format!("({})", pprust::pat_to_string(pat));
(msg, fix)
}
};
self.struct_span_err(pat.span, "an or-pattern parameter must be wrapped in parentheses")
.span_suggestion(pat.span, msg, fix, Applicability::MachineApplicable)
.emit();
} }
/// Eat the or-pattern `|` separator. /// Eat the or-pattern `|` separator.
/// If instead a `||` token is encountered, recover and pretend we parsed `|`. /// If instead a `||` token is encountered, recover and pretend we parsed `|`.
fn eat_or_separator(&mut self, lo: Option<Span>) -> bool { fn eat_or_separator(&mut self, lo: Option<Span>) -> EatOrResult {
if self.recover_trailing_vert(lo) { if self.recover_trailing_vert(lo) {
return false; EatOrResult::TrailingVert
} } else if matches!(self.token.kind, token::OrOr) {
// Found `||`; Recover and pretend we parsed `|`.
match self.token.kind { self.ban_unexpected_or_or(lo);
token::OrOr => { self.bump();
// Found `||`; Recover and pretend we parsed `|`. EatOrResult::AteOr
self.ban_unexpected_or_or(lo); } else if self.eat(&token::BinOp(token::Or)) {
self.bump(); EatOrResult::AteOr
true } else {
} EatOrResult::None
_ => self.eat(&token::BinOp(token::Or)),
} }
} }
@ -190,14 +250,14 @@ impl<'a> Parser<'a> {
matches!( matches!(
&token.uninterpolate().kind, &token.uninterpolate().kind,
token::FatArrow // e.g. `a | => 0,`. token::FatArrow // e.g. `a | => 0,`.
| token::Ident(kw::If, false) // e.g. `a | if expr`. | token::Ident(kw::If, false) // e.g. `a | if expr`.
| token::Eq // e.g. `let a | = 0`. | token::Eq // e.g. `let a | = 0`.
| token::Semi // e.g. `let a |;`. | token::Semi // e.g. `let a |;`.
| token::Colon // e.g. `let a | :`. | token::Colon // e.g. `let a | :`.
| token::Comma // e.g. `let (a |,)`. | token::Comma // e.g. `let (a |,)`.
| token::CloseDelim(token::Bracket) // e.g. `let [a | ]`. | token::CloseDelim(token::Bracket) // e.g. `let [a | ]`.
| token::CloseDelim(token::Paren) // e.g. `let (a | )`. | token::CloseDelim(token::Paren) // e.g. `let (a | )`.
| token::CloseDelim(token::Brace) // e.g. `let A { f: a | }`. | token::CloseDelim(token::Brace) // e.g. `let A { f: a | }`.
) )
}); });
match (is_end_ahead, &self.token.kind) { match (is_end_ahead, &self.token.kind) {

View file

@ -13,7 +13,8 @@ use rustc_ast::token::{self, TokenKind};
use rustc_ast::util::classify; use rustc_ast::util::classify;
use rustc_ast::AstLike; use rustc_ast::AstLike;
use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacCallStmt, MacStmtStyle}; use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacCallStmt, MacStmtStyle};
use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID}; use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt};
use rustc_ast::{StmtKind, DUMMY_NODE_ID};
use rustc_errors::{Applicability, PResult}; use rustc_errors::{Applicability, PResult};
use rustc_span::source_map::{BytePos, Span}; use rustc_span::source_map::{BytePos, Span};
use rustc_span::symbol::{kw, sym}; use rustc_span::symbol::{kw, sym};
@ -220,9 +221,10 @@ impl<'a> Parser<'a> {
/// Parses a local variable declaration. /// Parses a local variable declaration.
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> { fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
let lo = self.prev_token.span; let lo = self.prev_token.span;
let pat = self.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::Yes)?; let (pat, colon) =
self.parse_pat_before_ty(None, GateOr::Yes, RecoverComma::Yes, "`let` bindings")?;
let (err, ty) = if self.eat(&token::Colon) { let (err, ty) = if colon {
// Save the state of the parser before parsing type normally, in case there is a `:` // Save the state of the parser before parsing type normally, in case there is a `:`
// instead of an `=` typo. // instead of an `=` typo.
let parser_snapshot_before_type = self.clone(); let parser_snapshot_before_type = self.clone();

View file

@ -23,7 +23,7 @@
#[macro_use] #[macro_use]
extern crate rustc_macros; extern crate rustc_macros;
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
#[macro_use] #[macro_use]
extern crate rustc_data_structures; extern crate rustc_data_structures;
#[macro_use] #[macro_use]

View file

@ -87,7 +87,7 @@ pub struct PendingPredicateObligation<'tcx> {
} }
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(PendingPredicateObligation<'_>, 56); static_assert_size!(PendingPredicateObligation<'_>, 56);
impl<'a, 'tcx> FulfillmentContext<'tcx> { impl<'a, 'tcx> FulfillmentContext<'tcx> {

View file

@ -566,7 +566,7 @@ impl<T: Ord> BinaryHeap<T> {
let mut child = 2 * hole.pos() + 1; let mut child = 2 * hole.pos() + 1;
// Loop invariant: child == 2 * hole.pos() + 1. // Loop invariant: child == 2 * hole.pos() + 1.
while child < end - 1 { while child <= end.saturating_sub(2) {
// compare with the greater of the two children // compare with the greater of the two children
// SAFETY: child < end - 1 < self.len() and // SAFETY: child < end - 1 < self.len() and
// child + 1 < end <= self.len(), so they're valid indexes. // child + 1 < end <= self.len(), so they're valid indexes.
@ -625,7 +625,7 @@ impl<T: Ord> BinaryHeap<T> {
let mut child = 2 * hole.pos() + 1; let mut child = 2 * hole.pos() + 1;
// Loop invariant: child == 2 * hole.pos() + 1. // Loop invariant: child == 2 * hole.pos() + 1.
while child < end - 1 { while child <= end.saturating_sub(2) {
// SAFETY: child < end - 1 < self.len() and // SAFETY: child < end - 1 < self.len() and
// child + 1 < end <= self.len(), so they're valid indexes. // child + 1 < end <= self.len(), so they're valid indexes.
// child == 2 * hole.pos() + 1 != hole.pos() and // child == 2 * hole.pos() + 1 != hole.pos() and

View file

@ -579,6 +579,7 @@ impl Ordering {
/// ``` /// ```
#[derive(PartialEq, Eq, Debug, Copy, Clone, Default, Hash)] #[derive(PartialEq, Eq, Debug, Copy, Clone, Default, Hash)]
#[stable(feature = "reverse_cmp_key", since = "1.19.0")] #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
#[repr(transparent)]
pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T); pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
#[stable(feature = "reverse_cmp_key", since = "1.19.0")] #[stable(feature = "reverse_cmp_key", since = "1.19.0")]

View file

@ -16,7 +16,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true } panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" } panic_abort = { path = "../panic_abort" }
core = { path = "../core" } core = { path = "../core" }
libc = { version = "0.2.85", default-features = false, features = ['rustc-dep-of-std'] } libc = { version = "0.2.88", default-features = false, features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.39" } compiler_builtins = { version = "0.1.39" }
profiler_builtins = { path = "../profiler_builtins", optional = true } profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" } unwind = { path = "../unwind" }

View file

@ -93,7 +93,7 @@ crate struct Item {
} }
// `Item` is used a lot. Make sure it doesn't unintentionally get bigger. // `Item` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Item, 48); rustc_data_structures::static_assert_size!(Item, 48);
impl fmt::Debug for Item { impl fmt::Debug for Item {

View file

@ -0,0 +1,27 @@
// Regression test for #75525, verifies that no bounds checks are generated.
// min-llvm-version: 12.0.0
// compile-flags: -O
#![crate_type = "lib"]
// CHECK-LABEL: @f0
// CHECK-NOT: panic
#[no_mangle]
pub fn f0(idx: usize, buf: &[u8; 10]) -> u8 {
if idx < 8 { buf[idx + 1] } else { 0 }
}
// CHECK-LABEL: @f1
// CHECK-NOT: panic
#[no_mangle]
pub fn f1(idx: usize, buf: &[u8; 10]) -> u8 {
if idx > 5 && idx < 8 { buf[idx - 1] } else { 0 }
}
// CHECK-LABEL: @f2
// CHECK-NOT: panic
#[no_mangle]
pub fn f2(idx: usize, buf: &[u8; 10]) -> u8 {
if idx > 5 && idx < 8 { buf[idx] } else { 0 }
}

View file

@ -18,10 +18,10 @@ fn main() {
let (A(a, _) | B(a), a) = (A(0, 1), 2); let (A(a, _) | B(a), a) = (A(0, 1), 2);
//~^ ERROR identifier `a` is bound more than once in the same pattern //~^ ERROR identifier `a` is bound more than once in the same pattern
let A(a, a) | B(a) = A(0, 1); let (A(a, a) | B(a)) = A(0, 1);
//~^ ERROR identifier `a` is bound more than once in the same pattern //~^ ERROR identifier `a` is bound more than once in the same pattern
let B(a) | A(a, a) = A(0, 1); let (B(a) | A(a, a)) = A(0, 1);
//~^ ERROR identifier `a` is bound more than once in the same pattern //~^ ERROR identifier `a` is bound more than once in the same pattern
match A(0, 1) { match A(0, 1) {
@ -29,17 +29,17 @@ fn main() {
//~^ ERROR identifier `a` is bound more than once in the same pattern //~^ ERROR identifier `a` is bound more than once in the same pattern
} }
let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
//~^ ERROR identifier `a` is bound more than once in the same pattern //~^ ERROR identifier `a` is bound more than once in the same pattern
//~| ERROR identifier `a` is bound more than once in the same pattern //~| ERROR identifier `a` is bound more than once in the same pattern
//~| ERROR mismatched types //~| ERROR mismatched types
let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
//~^ ERROR identifier `a` is bound more than once in the same pattern //~^ ERROR identifier `a` is bound more than once in the same pattern
//~| ERROR identifier `a` is bound more than once in the same pattern //~| ERROR identifier `a` is bound more than once in the same pattern
//~| ERROR variable `a` is not bound in all patterns //~| ERROR variable `a` is not bound in all patterns
let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); let (B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
//~^ ERROR identifier `a` is bound more than once in the same pattern //~^ ERROR identifier `a` is bound more than once in the same pattern
//~| ERROR identifier `a` is bound more than once in the same pattern //~| ERROR identifier `a` is bound more than once in the same pattern
} }

View file

@ -23,16 +23,16 @@ LL | let (A(a, _) | B(a), a) = (A(0, 1), 2);
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0416]: identifier `a` is bound more than once in the same pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/already-bound-name.rs:21:14 --> $DIR/already-bound-name.rs:21:15
| |
LL | let A(a, a) | B(a) = A(0, 1); LL | let (A(a, a) | B(a)) = A(0, 1);
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0416]: identifier `a` is bound more than once in the same pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/already-bound-name.rs:24:21 --> $DIR/already-bound-name.rs:24:22
| |
LL | let B(a) | A(a, a) = A(0, 1); LL | let (B(a) | A(a, a)) = A(0, 1);
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0416]: identifier `a` is bound more than once in the same pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/already-bound-name.rs:28:21 --> $DIR/already-bound-name.rs:28:21
@ -41,55 +41,55 @@ LL | B(a) | A(a, a) => {} // Let's ensure `match` has no funny business.
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0416]: identifier `a` is bound more than once in the same pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/already-bound-name.rs:32:36 --> $DIR/already-bound-name.rs:32:37
| |
LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); LL | let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0416]: identifier `a` is bound more than once in the same pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/already-bound-name.rs:32:46 --> $DIR/already-bound-name.rs:32:47
| |
LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); LL | let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0416]: identifier `a` is bound more than once in the same pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/already-bound-name.rs:37:36 --> $DIR/already-bound-name.rs:37:37
| |
LL | let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); LL | let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0416]: identifier `a` is bound more than once in the same pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/already-bound-name.rs:37:46 --> $DIR/already-bound-name.rs:37:47
| |
LL | let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); LL | let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0408]: variable `a` is not bound in all patterns error[E0408]: variable `a` is not bound in all patterns
--> $DIR/already-bound-name.rs:37:9 --> $DIR/already-bound-name.rs:37:10
| |
LL | let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); LL | let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
| ^^^^ pattern doesn't bind `a` - variable not in all patterns | ^^^^ pattern doesn't bind `a` - variable not in all patterns
error[E0416]: identifier `a` is bound more than once in the same pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/already-bound-name.rs:42:49 --> $DIR/already-bound-name.rs:42:50
| |
LL | let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); LL | let (B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0416]: identifier `a` is bound more than once in the same pattern error[E0416]: identifier `a` is bound more than once in the same pattern
--> $DIR/already-bound-name.rs:42:59 --> $DIR/already-bound-name.rs:42:60
| |
LL | let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); LL | let (B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
| ^ used in a pattern more than once | ^ used in a pattern more than once
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/already-bound-name.rs:32:31 --> $DIR/already-bound-name.rs:32:32
| |
LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); LL | let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
| - ^ ------- this expression has type `E<E<{integer}>>` | - ^ ------- this expression has type `E<E<{integer}>>`
| | | | | |
| | expected integer, found enum `E` | | expected integer, found enum `E`
| first introduced with type `{integer}` here | first introduced with type `{integer}` here
| |
= note: expected type `{integer}` = note: expected type `{integer}`
found type `E<{integer}>` found type `E<{integer}>`

View file

@ -8,9 +8,9 @@
fn main() { fn main() {
// One level: // One level:
let Ok(a) | Err(a) = Ok(0); let (Ok(a) | Err(a)) = Ok(0);
let Ok(ref a) | Err(ref a) = Ok(0); let (Ok(ref a) | Err(ref a)) = Ok(0);
let Ok(ref mut a) | Err(ref mut a) = Ok(0); let (Ok(ref mut a) | Err(ref mut a)) = Ok(0);
// Two levels: // Two levels:
enum Tri<S, T, U> { enum Tri<S, T, U> {
@ -20,10 +20,10 @@ fn main() {
} }
use Tri::*; use Tri::*;
let Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b))): Result<_, Result<_, _>> = let (Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b)))): Result<_, Result<_, _>> =
Ok((V1(1), 1)); Ok((V1(1), 1));
let Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b))): Result< let (Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b)))): Result<
_, _,
Result<_, _>, Result<_, _>,
> = Ok((V1(1), 1)); > = Ok((V1(1), 1));

View file

@ -3,28 +3,28 @@
const fn foo((Ok(a) | Err(a)): Result<i32, i32>) { const fn foo((Ok(a) | Err(a)): Result<i32, i32>) {
let x = Ok(3); let x = Ok(3);
let Ok(y) | Err(y) = x; let (Ok(y) | Err(y)) = x;
} }
const X: () = { const X: () = {
let x = Ok(3); let x = Ok(3);
let Ok(y) | Err(y) = x; let (Ok(y) | Err(y)) = x;
}; };
static Y: () = { static Y: () = {
let x = Ok(3); let x = Ok(3);
let Ok(y) | Err(y) = x; let (Ok(y) | Err(y)) = x;
}; };
static mut Z: () = { static mut Z: () = {
let x = Ok(3); let x = Ok(3);
let Ok(y) | Err(y) = x; let (Ok(y) | Err(y)) = x;
}; };
fn main() { fn main() {
let _: [(); { let _: [(); {
let x = Ok(3); let x = Ok(3);
let Ok(y) | Err(y) = x; let (Ok(y) | Err(y)) = x;
2 2
}]; }];
} }

View file

@ -5,4 +5,5 @@ fn main() {}
#[cfg(FALSE)] #[cfg(FALSE)]
fn gated_leading_vert_in_let() { fn gated_leading_vert_in_let() {
let | A; //~ ERROR or-patterns syntax is experimental let | A; //~ ERROR or-patterns syntax is experimental
//~^ ERROR top-level or-patterns are not allowed
} }

View file

@ -1,3 +1,9 @@
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/feature-gate-or_patterns-leading-let.rs:7:9
|
LL | let | A;
| ^^^ help: remove the `|`: `A`
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns-leading-let.rs:7:9 --> $DIR/feature-gate-or_patterns-leading-let.rs:7:9
| |
@ -7,6 +13,6 @@ LL | let | A;
= note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information = note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error: aborting due to previous error error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`. For more information about this error, try `rustc --explain E0658`.

View file

@ -26,7 +26,9 @@ fn or_patterns() {
// Gated: // Gated:
let | A | B; //~ ERROR or-patterns syntax is experimental let | A | B; //~ ERROR or-patterns syntax is experimental
//~^ ERROR top-level or-patterns are not allowed
let A | B; //~ ERROR or-patterns syntax is experimental let A | B; //~ ERROR or-patterns syntax is experimental
//~^ ERROR top-level or-patterns are not allowed
for | A | B in 0 {} //~ ERROR or-patterns syntax is experimental for | A | B in 0 {} //~ ERROR or-patterns syntax is experimental
for A | B in 0 {} //~ ERROR or-patterns syntax is experimental for A | B in 0 {} //~ ERROR or-patterns syntax is experimental
fn fun((A | B): _) {} //~ ERROR or-patterns syntax is experimental fn fun((A | B): _) {} //~ ERROR or-patterns syntax is experimental

View file

@ -1,3 +1,15 @@
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/feature-gate-or_patterns.rs:28:9
|
LL | let | A | B;
| ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/feature-gate-or_patterns.rs:30:9
|
LL | let A | B;
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:5:14 --> $DIR/feature-gate-or_patterns.rs:5:14
| |
@ -17,7 +29,7 @@ LL | let | A | B;
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:29:9 --> $DIR/feature-gate-or_patterns.rs:30:9
| |
LL | let A | B; LL | let A | B;
| ^^^^^ | ^^^^^
@ -26,7 +38,7 @@ LL | let A | B;
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:30:9 --> $DIR/feature-gate-or_patterns.rs:32:9
| |
LL | for | A | B in 0 {} LL | for | A | B in 0 {}
| ^^^^^^^ | ^^^^^^^
@ -35,7 +47,7 @@ LL | for | A | B in 0 {}
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:31:9 --> $DIR/feature-gate-or_patterns.rs:33:9
| |
LL | for A | B in 0 {} LL | for A | B in 0 {}
| ^^^^^ | ^^^^^
@ -44,7 +56,7 @@ LL | for A | B in 0 {}
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:32:13 --> $DIR/feature-gate-or_patterns.rs:34:13
| |
LL | fn fun((A | B): _) {} LL | fn fun((A | B): _) {}
| ^^^^^ | ^^^^^
@ -53,7 +65,7 @@ LL | fn fun((A | B): _) {}
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:33:15 --> $DIR/feature-gate-or_patterns.rs:35:15
| |
LL | let _ = |(A | B): u8| (); LL | let _ = |(A | B): u8| ();
| ^^^^^ | ^^^^^
@ -62,7 +74,7 @@ LL | let _ = |(A | B): u8| ();
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:34:10 --> $DIR/feature-gate-or_patterns.rs:36:10
| |
LL | let (A | B); LL | let (A | B);
| ^^^^^ | ^^^^^
@ -71,7 +83,7 @@ LL | let (A | B);
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:35:10 --> $DIR/feature-gate-or_patterns.rs:37:10
| |
LL | let (A | B,); LL | let (A | B,);
| ^^^^^ | ^^^^^
@ -80,7 +92,7 @@ LL | let (A | B,);
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:36:11 --> $DIR/feature-gate-or_patterns.rs:38:11
| |
LL | let A(B | C); LL | let A(B | C);
| ^^^^^ | ^^^^^
@ -89,7 +101,7 @@ LL | let A(B | C);
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:37:14 --> $DIR/feature-gate-or_patterns.rs:39:14
| |
LL | let E::V(B | C); LL | let E::V(B | C);
| ^^^^^ | ^^^^^
@ -98,7 +110,7 @@ LL | let E::V(B | C);
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:38:17 --> $DIR/feature-gate-or_patterns.rs:40:17
| |
LL | let S { f1: B | C, f2 }; LL | let S { f1: B | C, f2 };
| ^^^^^ | ^^^^^
@ -107,7 +119,7 @@ LL | let S { f1: B | C, f2 };
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:39:20 --> $DIR/feature-gate-or_patterns.rs:41:20
| |
LL | let E::V { f1: B | C, f2 }; LL | let E::V { f1: B | C, f2 };
| ^^^^^ | ^^^^^
@ -116,7 +128,7 @@ LL | let E::V { f1: B | C, f2 };
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error[E0658]: or-patterns syntax is experimental error[E0658]: or-patterns syntax is experimental
--> $DIR/feature-gate-or_patterns.rs:40:10 --> $DIR/feature-gate-or_patterns.rs:42:10
| |
LL | let [A | B]; LL | let [A | B];
| ^^^^^ | ^^^^^
@ -169,6 +181,6 @@ LL | accept_pat!([p | q]);
= note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information = note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
= help: add `#![feature(or_patterns)]` to the crate attributes to enable = help: add `#![feature(or_patterns)]` to the crate attributes to enable
error: aborting due to 19 previous errors error: aborting due to 21 previous errors
For more information about this error, try `rustc --explain E0658`. For more information about this error, try `rustc --explain E0658`.

View file

@ -11,4 +11,4 @@ enum E { A, B }
use E::*; use E::*;
#[cfg(FALSE)] #[cfg(FALSE)]
fn fun1((A | B): E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses fn fun1((A | B): E) {} //~ ERROR top-level or-patterns are not allowed

View file

@ -11,4 +11,4 @@ enum E { A, B }
use E::*; use E::*;
#[cfg(FALSE)] #[cfg(FALSE)]
fn fun1(A | B: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses fn fun1(A | B: E) {} //~ ERROR top-level or-patterns are not allowed

View file

@ -1,4 +1,4 @@
error: an or-pattern parameter must be wrapped in parentheses error: top-level or-patterns are not allowed in function parameters
--> $DIR/fn-param-wrap-parens.rs:14:9 --> $DIR/fn-param-wrap-parens.rs:14:9
| |
LL | fn fun1(A | B: E) {} LL | fn fun1(A | B: E) {}

View file

@ -4,23 +4,23 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
fn main() { fn main() {
// One level: // One level:
let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0); let (Ok(a) | Err(ref a)): Result<&u8, u8> = Ok(&0);
//~^ ERROR variable `a` is bound inconsistently //~^ ERROR variable `a` is bound inconsistently
let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0); let (Ok(ref mut a) | Err(a)): Result<u8, &mut u8> = Ok(0);
//~^ ERROR variable `a` is bound inconsistently //~^ ERROR variable `a` is bound inconsistently
let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0);
//~^ ERROR variable `a` is bound inconsistently //~^ ERROR variable `a` is bound inconsistently
//~| ERROR mismatched types //~| ERROR mismatched types
let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
//~^ ERROR variable `a` is bound inconsistently //~^ ERROR variable `a` is bound inconsistently
//~| ERROR variable `b` is bound inconsistently //~| ERROR variable `b` is bound inconsistently
//~| ERROR mismatched types //~| ERROR mismatched types
// Two levels: // Two levels:
let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0); let (Ok(Ok(a) | Err(a)) | Err(ref a)) = Err(0);
//~^ ERROR variable `a` is bound inconsistently //~^ ERROR variable `a` is bound inconsistently
// Three levels: // Three levels:
let Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a) = Err(&1); let (Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a)) = Err(&1);
//~^ ERROR variable `a` is bound inconsistently //~^ ERROR variable `a` is bound inconsistently
} }

View file

@ -1,74 +1,74 @@
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|` error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
--> $DIR/inconsistent-modes.rs:7:25 --> $DIR/inconsistent-modes.rs:7:26
| |
LL | let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0); LL | let (Ok(a) | Err(ref a)): Result<&u8, u8> = Ok(&0);
| - ^ bound in different ways | - ^ bound in different ways
| | | |
| first binding | first binding
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|` error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
--> $DIR/inconsistent-modes.rs:9:29 --> $DIR/inconsistent-modes.rs:9:30
| |
LL | let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0); LL | let (Ok(ref mut a) | Err(a)): Result<u8, &mut u8> = Ok(0);
| - ^ bound in different ways | - ^ bound in different ways
| | | |
| first binding | first binding
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|` error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
--> $DIR/inconsistent-modes.rs:11:33 --> $DIR/inconsistent-modes.rs:11:34
| |
LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); LL | let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0);
| - first binding ^ bound in different ways | - first binding ^ bound in different ways
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|` error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
--> $DIR/inconsistent-modes.rs:14:39 --> $DIR/inconsistent-modes.rs:14:40
| |
LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); LL | let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
| - first binding ^ bound in different ways | - first binding ^ bound in different ways
error[E0409]: variable `b` is bound inconsistently across alternatives separated by `|` error[E0409]: variable `b` is bound inconsistently across alternatives separated by `|`
--> $DIR/inconsistent-modes.rs:14:46 --> $DIR/inconsistent-modes.rs:14:47
| |
LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); LL | let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
| - first binding ^ bound in different ways | - first binding ^ bound in different ways
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|` error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
--> $DIR/inconsistent-modes.rs:20:38 --> $DIR/inconsistent-modes.rs:20:39
| |
LL | let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0); LL | let (Ok(Ok(a) | Err(a)) | Err(ref a)) = Err(0);
| - ^ bound in different ways | - ^ bound in different ways
| | | |
| first binding | first binding
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|` error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
--> $DIR/inconsistent-modes.rs:24:33 --> $DIR/inconsistent-modes.rs:24:34
| |
LL | let Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a) = Err(&1); LL | let (Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a)) = Err(&1);
| - ^ bound in different ways | - ^ bound in different ways
| | | |
| first binding | first binding
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/inconsistent-modes.rs:11:25 --> $DIR/inconsistent-modes.rs:11:26
| |
LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); LL | let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0);
| ----- ^^^^^^^^^ -------------------- expected due to this | ----- ^^^^^^^^^ -------------------- expected due to this
| | | | | |
| | types differ in mutability | | types differ in mutability
| first introduced with type `&&u8` here | first introduced with type `&&u8` here
| |
= note: expected type `&&u8` = note: expected type `&&u8`
found type `&mut &mut u8` found type `&mut &mut u8`
= note: a binding must have the same type in all alternatives = note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/inconsistent-modes.rs:14:31 --> $DIR/inconsistent-modes.rs:14:32
| |
LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); LL | let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
| ----- ^^^^^^^^^ ----------- this expression has type `Result<({integer}, &{integer}), (_, _)>` | ----- ^^^^^^^^^ ----------- this expression has type `Result<({integer}, &{integer}), (_, _)>`
| | | | | |
| | types differ in mutability | | types differ in mutability
| first introduced with type `&{integer}` here | first introduced with type `&{integer}` here
| |
= note: expected type `&{integer}` = note: expected type `&{integer}`
found type `&mut _` found type `&mut _`

View file

@ -1,7 +1,7 @@
#![feature(or_patterns)] #![feature(or_patterns)]
fn main() { fn main() {
let 0 | (1 | 2) = 0; //~ ERROR refutable pattern in local binding let (0 | (1 | 2)) = 0; //~ ERROR refutable pattern in local binding
match 0 { match 0 {
//~^ ERROR non-exhaustive patterns //~^ ERROR non-exhaustive patterns
0 | (1 | 2) => {} 0 | (1 | 2) => {}

View file

@ -1,16 +1,16 @@
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
--> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:4:9 --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:4:10
| |
LL | let 0 | (1 | 2) = 0; LL | let (0 | (1 | 2)) = 0;
| ^^^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered | ^^^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
| |
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32` = note: the matched value is of type `i32`
help: you might want to use `if let` to ignore the variant that isn't matched help: you might want to use `if let` to ignore the variant that isn't matched
| |
LL | if let 0 | (1 | 2) = 0 { /* */ } LL | if let (0 | (1 | 2)) = 0 { /* */ }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0004]: non-exhaustive patterns: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered error[E0004]: non-exhaustive patterns: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
--> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:5:11 --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:5:11

View file

@ -3,7 +3,7 @@
#![feature(or_patterns)] #![feature(or_patterns)]
fn main() { fn main() {
let 0 | (1 | _) = 0; let (0 | (1 | _)) = 0;
if let 0 | (1 | 2) = 0 {} if let 0 | (1 | 2) = 0 {}
if let x @ 0 | x @ (1 | 2) = 0 {} if let x @ 0 | x @ (1 | 2) = 0 {}
} }

View file

@ -3,7 +3,7 @@
// run-pass // run-pass
fn or_pat_let(x: Result<u32, u32>) -> u32 { fn or_pat_let(x: Result<u32, u32>) -> u32 {
let Ok(y) | Err(y) = x; let (Ok(y) | Err(y)) = x;
y y
} }

View file

@ -8,7 +8,7 @@ async fn a((x | s): String) {}
//~| ERROR variable `s` is not bound in all patterns //~| ERROR variable `s` is not bound in all patterns
async fn b() { async fn b() {
let x | s = String::new(); let (x | s) = String::new();
//~^ ERROR variable `x` is not bound in all patterns //~^ ERROR variable `x` is not bound in all patterns
//~| ERROR variable `s` is not bound in all patterns //~| ERROR variable `s` is not bound in all patterns
} }

View file

@ -15,20 +15,20 @@ LL | async fn a((x | s): String) {}
| variable not in all patterns | variable not in all patterns
error[E0408]: variable `s` is not bound in all patterns error[E0408]: variable `s` is not bound in all patterns
--> $DIR/mismatched-bindings-async-fn.rs:11:9 --> $DIR/mismatched-bindings-async-fn.rs:11:10
| |
LL | let x | s = String::new(); LL | let (x | s) = String::new();
| ^ - variable not in all patterns | ^ - variable not in all patterns
| | | |
| pattern doesn't bind `s` | pattern doesn't bind `s`
error[E0408]: variable `x` is not bound in all patterns error[E0408]: variable `x` is not bound in all patterns
--> $DIR/mismatched-bindings-async-fn.rs:11:13 --> $DIR/mismatched-bindings-async-fn.rs:11:14
| |
LL | let x | s = String::new(); LL | let (x | s) = String::new();
| - ^ pattern doesn't bind `x` | - ^ pattern doesn't bind `x`
| | | |
| variable not in all patterns | variable not in all patterns
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -17,7 +17,7 @@ fn check_handling_of_paths() {
} }
use bar::foo::{alpha, charlie}; use bar::foo::{alpha, charlie};
let alpha | beta | charlie = alpha; //~ ERROR variable `beta` is not bound in all patterns let (alpha | beta | charlie) = alpha; //~ ERROR variable `beta` is not bound in all patterns
match Some(alpha) { match Some(alpha) {
Some(alpha | beta) => {} //~ ERROR variable `beta` is not bound in all patterns Some(alpha | beta) => {} //~ ERROR variable `beta` is not bound in all patterns
} }
@ -31,19 +31,19 @@ fn check_misc_nesting() {
// One level: // One level:
const X: E<u8> = B(0); const X: E<u8> = B(0);
let A(a, _) | _ = X; //~ ERROR variable `a` is not bound in all patterns let (A(a, _) | _) = X; //~ ERROR variable `a` is not bound in all patterns
let _ | B(a) = X; //~ ERROR variable `a` is not bound in all patterns let (_ | B(a)) = X; //~ ERROR variable `a` is not bound in all patterns
let A(..) | B(a) = X; //~ ERROR variable `a` is not bound in all patterns let (A(..) | B(a)) = X; //~ ERROR variable `a` is not bound in all patterns
let A(a, _) | B(_) = X; //~ ERROR variable `a` is not bound in all patterns let (A(a, _) | B(_)) = X; //~ ERROR variable `a` is not bound in all patterns
let A(_, a) | B(_) = X; //~ ERROR variable `a` is not bound in all patterns let (A(_, a) | B(_)) = X; //~ ERROR variable `a` is not bound in all patterns
let A(a, b) | B(a) = X; //~ ERROR variable `b` is not bound in all patterns let (A(a, b) | B(a)) = X; //~ ERROR variable `b` is not bound in all patterns
// Two levels: // Two levels:
const Y: E<E<u8>> = B(B(0)); const Y: E<E<u8>> = B(B(0));
let A(A(..) | B(_), _) | B(a) = Y; //~ ERROR variable `a` is not bound in all patterns let (A(A(..) | B(_), _) | B(a)) = Y; //~ ERROR variable `a` is not bound in all patterns
let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y; let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
//~^ ERROR variable `a` is not bound in all patterns //~^ ERROR variable `a` is not bound in all patterns
let A(A(a, b) | B(c), d) | B(e) = Y; let (A(A(a, b) | B(c), d) | B(e)) = Y;
//~^ ERROR variable `a` is not bound in all patterns //~^ ERROR variable `a` is not bound in all patterns
//~| ERROR variable `a` is not bound in all patterns //~| ERROR variable `a` is not bound in all patterns
//~| ERROR variable `b` is not bound in all patterns //~| ERROR variable `b` is not bound in all patterns

View file

@ -1,11 +1,11 @@
error[E0408]: variable `beta` is not bound in all patterns error[E0408]: variable `beta` is not bound in all patterns
--> $DIR/missing-bindings.rs:20:9 --> $DIR/missing-bindings.rs:20:10
| |
LL | let alpha | beta | charlie = alpha; LL | let (alpha | beta | charlie) = alpha;
| ^^^^^ ---- ^^^^^^^ pattern doesn't bind `beta` | ^^^^^ ---- ^^^^^^^ pattern doesn't bind `beta`
| | | | | |
| | variable not in all patterns | | variable not in all patterns
| pattern doesn't bind `beta` | pattern doesn't bind `beta`
error[E0408]: variable `beta` is not bound in all patterns error[E0408]: variable `beta` is not bound in all patterns
--> $DIR/missing-bindings.rs:22:14 --> $DIR/missing-bindings.rs:22:14
@ -16,132 +16,132 @@ LL | Some(alpha | beta) => {}
| pattern doesn't bind `beta` | pattern doesn't bind `beta`
error[E0408]: variable `a` is not bound in all patterns error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:34:19 --> $DIR/missing-bindings.rs:34:20
| |
LL | let A(a, _) | _ = X; LL | let (A(a, _) | _) = X;
| - ^ pattern doesn't bind `a` | - ^ pattern doesn't bind `a`
| | | |
| variable not in all patterns | variable not in all patterns
error[E0408]: variable `a` is not bound in all patterns error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:35:9 --> $DIR/missing-bindings.rs:35:10
| |
LL | let _ | B(a) = X; LL | let (_ | B(a)) = X;
| ^ - variable not in all patterns | ^ - variable not in all patterns
| | | |
| pattern doesn't bind `a` | pattern doesn't bind `a`
error[E0408]: variable `a` is not bound in all patterns error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:36:9 --> $DIR/missing-bindings.rs:36:10
| |
LL | let A(..) | B(a) = X; LL | let (A(..) | B(a)) = X;
| ^^^^^ - variable not in all patterns | ^^^^^ - variable not in all patterns
| | | |
| pattern doesn't bind `a` | pattern doesn't bind `a`
error[E0408]: variable `a` is not bound in all patterns error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:37:19 --> $DIR/missing-bindings.rs:37:20
| |
LL | let A(a, _) | B(_) = X; LL | let (A(a, _) | B(_)) = X;
| - ^^^^ pattern doesn't bind `a` | - ^^^^ pattern doesn't bind `a`
| | | |
| variable not in all patterns | variable not in all patterns
error[E0408]: variable `a` is not bound in all patterns error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:38:19 --> $DIR/missing-bindings.rs:38:20
| |
LL | let A(_, a) | B(_) = X; LL | let (A(_, a) | B(_)) = X;
| - ^^^^ pattern doesn't bind `a` | - ^^^^ pattern doesn't bind `a`
| |
| variable not in all patterns
error[E0408]: variable `b` is not bound in all patterns
--> $DIR/missing-bindings.rs:39:20
|
LL | let (A(a, b) | B(a)) = X;
| - ^^^^ pattern doesn't bind `b`
| |
| variable not in all patterns
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:43:10
|
LL | let (A(A(..) | B(_), _) | B(a)) = Y;
| ^^^^^^^^^^^^^^^^^^ - variable not in all patterns
| |
| pattern doesn't bind `a`
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:44:12
|
LL | let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
| ^^^^^ - variable not in all patterns
| |
| pattern doesn't bind `a`
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:22
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| - ^^^^ pattern doesn't bind `a`
| | | |
| variable not in all patterns | variable not in all patterns
error[E0408]: variable `b` is not bound in all patterns error[E0408]: variable `b` is not bound in all patterns
--> $DIR/missing-bindings.rs:39:19 --> $DIR/missing-bindings.rs:46:22
| |
LL | let A(a, b) | B(a) = X; LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| - ^^^^ pattern doesn't bind `b` | - ^^^^ pattern doesn't bind `b`
| |
| variable not in all patterns
error[E0408]: variable `c` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:12
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| ^^^^^^^ - variable not in all patterns
| |
| pattern doesn't bind `c`
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:33
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| - ^^^^ pattern doesn't bind `a`
| | | |
| variable not in all patterns | variable not in all patterns
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:43:9
|
LL | let A(A(..) | B(_), _) | B(a) = Y;
| ^^^^^^^^^^^^^^^^^^ - variable not in all patterns
| |
| pattern doesn't bind `a`
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:44:11
|
LL | let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
| ^^^^^ - variable not in all patterns
| |
| pattern doesn't bind `a`
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:21
|
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
| - ^^^^ pattern doesn't bind `a`
| |
| variable not in all patterns
error[E0408]: variable `b` is not bound in all patterns error[E0408]: variable `b` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:21 --> $DIR/missing-bindings.rs:46:33
| |
LL | let A(A(a, b) | B(c), d) | B(e) = Y; LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| - ^^^^ pattern doesn't bind `b` | - ^^^^ pattern doesn't bind `b`
| | | |
| variable not in all patterns | variable not in all patterns
error[E0408]: variable `c` is not bound in all patterns error[E0408]: variable `c` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:11 --> $DIR/missing-bindings.rs:46:33
| |
LL | let A(A(a, b) | B(c), d) | B(e) = Y; LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| ^^^^^^^ - variable not in all patterns | - ^^^^ pattern doesn't bind `c`
| | | |
| pattern doesn't bind `c` | variable not in all patterns
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:32
|
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
| - ^^^^ pattern doesn't bind `a`
| |
| variable not in all patterns
error[E0408]: variable `b` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:32
|
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
| - ^^^^ pattern doesn't bind `b`
| |
| variable not in all patterns
error[E0408]: variable `c` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:32
|
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
| - ^^^^ pattern doesn't bind `c`
| |
| variable not in all patterns
error[E0408]: variable `d` is not bound in all patterns error[E0408]: variable `d` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:32 --> $DIR/missing-bindings.rs:46:33
| |
LL | let A(A(a, b) | B(c), d) | B(e) = Y; LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| - ^^^^ pattern doesn't bind `d` | - ^^^^ pattern doesn't bind `d`
| | | |
| variable not in all patterns | variable not in all patterns
error[E0408]: variable `e` is not bound in all patterns error[E0408]: variable `e` is not bound in all patterns
--> $DIR/missing-bindings.rs:46:9 --> $DIR/missing-bindings.rs:46:10
| |
LL | let A(A(a, b) | B(c), d) | B(e) = Y; LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns | ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns
| | | |
| pattern doesn't bind `e` | pattern doesn't bind `e`
error[E0408]: variable `a` is not bound in all patterns error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:62:29 --> $DIR/missing-bindings.rs:62:29

View file

@ -0,0 +1,46 @@
// This test tests the precedence of `|` (or-patterns) undelimited nested patterns. In particular,
// we want to reserve the syntactic space of a pattern followed by a type annotation for possible
// future type ascription, so we need to make sure that any time a pattern is followed by type
// annotation (for now), the pattern is not a top-level or-pattern. However, there are also a few
// types of patterns that allow undelimited subpatterns that could cause the same ambiguity.
// Currently, those should be impossible due to precedence rule. This test enforces that.
#![feature(or_patterns)]
enum E {
A,
B,
}
fn foo() {
use E::*;
// ok
let b @ (A | B): E = A;
let b @ A | B: E = A; //~ERROR `b` is not bound in all patterns
//~^ ERROR top-level or-patterns are not allowed
}
enum F {
A(usize),
B(usize),
}
fn bar() {
use F::*;
// ok
let (A(x) | B(x)): F = A(3);
let &A(_) | B(_): F = A(3); //~ERROR mismatched types
//~^ ERROR top-level or-patterns are not allowed
let &&A(_) | B(_): F = A(3); //~ERROR mismatched types
//~^ ERROR top-level or-patterns are not allowed
let &mut A(_) | B(_): F = A(3); //~ERROR mismatched types
//~^ ERROR top-level or-patterns are not allowed
let &&mut A(_) | B(_): F = A(3); //~ERROR mismatched types
//~^ ERROR top-level or-patterns are not allowed
}
fn main() {}

View file

@ -0,0 +1,86 @@
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:21:9
|
LL | let b @ A | B: E = A;
| ^^^^^^^^^ help: wrap the pattern in parentheses: `(b @ A | B)`
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:36:9
|
LL | let &A(_) | B(_): F = A(3);
| ^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&A(_) | B(_))`
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:38:9
|
LL | let &&A(_) | B(_): F = A(3);
| ^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&&A(_) | B(_))`
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:40:9
|
LL | let &mut A(_) | B(_): F = A(3);
| ^^^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&mut A(_) | B(_))`
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:42:9
|
LL | let &&mut A(_) | B(_): F = A(3);
| ^^^^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&&mut A(_) | B(_))`
error[E0408]: variable `b` is not bound in all patterns
--> $DIR/nested-undelimited-precedence.rs:21:17
|
LL | let b @ A | B: E = A;
| - ^ pattern doesn't bind `b`
| |
| variable not in all patterns
error[E0308]: mismatched types
--> $DIR/nested-undelimited-precedence.rs:36:9
|
LL | let &A(_) | B(_): F = A(3);
| ^^^^^ - expected due to this
| |
| expected enum `F`, found reference
|
= note: expected enum `F`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/nested-undelimited-precedence.rs:38:9
|
LL | let &&A(_) | B(_): F = A(3);
| ^^^^^^ - expected due to this
| |
| expected enum `F`, found reference
|
= note: expected enum `F`
found reference `&_`
error[E0308]: mismatched types
--> $DIR/nested-undelimited-precedence.rs:40:9
|
LL | let &mut A(_) | B(_): F = A(3);
| ^^^^^^^^^ - expected due to this
| |
| expected enum `F`, found `&mut _`
|
= note: expected enum `F`
found mutable reference `&mut _`
error[E0308]: mismatched types
--> $DIR/nested-undelimited-precedence.rs:42:9
|
LL | let &&mut A(_) | B(_): F = A(3);
| ^^^^^^^^^^ - expected due to this
| |
| expected enum `F`, found reference
|
= note: expected enum `F`
found reference `&_`
error: aborting due to 10 previous errors
Some errors have detailed explanations: E0308, E0408.
For more information about an error, try `rustc --explain E0308`.

View file

@ -52,10 +52,10 @@ fn main() {
= Some((0u8, Some((1u16, 2u32)))) = Some((0u8, Some((1u16, 2u32))))
{} {}
let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2); let (Blah::A(_, x, y) | Blah::B(x, y)) = Blah::A(1, 1, 2);
//~^ ERROR mismatched types //~^ ERROR mismatched types
let (x, y) | (y, x) = (0u8, 1u16); let ((x, y) | (y, x)) = (0u8, 1u16);
//~^ ERROR mismatched types //~^ ERROR mismatched types
//~| ERROR mismatched types //~| ERROR mismatched types

View file

@ -187,35 +187,35 @@ LL | = Some((0u8, Some((1u16, 2u32))))
= note: a binding must have the same type in all alternatives = note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:55:39 --> $DIR/or-patterns-binding-type-mismatch.rs:55:40
| |
LL | let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2); LL | let (Blah::A(_, x, y) | Blah::B(x, y)) = Blah::A(1, 1, 2);
| - ^ ---------------- this expression has type `Blah` | - ^ ---------------- this expression has type `Blah`
| | | | | |
| | expected `usize`, found `isize` | | expected `usize`, found `isize`
| first introduced with type `usize` here | first introduced with type `usize` here
| |
= note: a binding must have the same type in all alternatives = note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:58:19 --> $DIR/or-patterns-binding-type-mismatch.rs:58:20
| |
LL | let (x, y) | (y, x) = (0u8, 1u16); LL | let ((x, y) | (y, x)) = (0u8, 1u16);
| - ^ ----------- this expression has type `(u8, u16)` | - ^ ----------- this expression has type `(u8, u16)`
| | | | | |
| | expected `u16`, found `u8` | | expected `u16`, found `u8`
| first introduced with type `u16` here | first introduced with type `u16` here
| |
= note: a binding must have the same type in all alternatives = note: a binding must have the same type in all alternatives
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/or-patterns-binding-type-mismatch.rs:58:22 --> $DIR/or-patterns-binding-type-mismatch.rs:58:23
| |
LL | let (x, y) | (y, x) = (0u8, 1u16); LL | let ((x, y) | (y, x)) = (0u8, 1u16);
| - ^ ----------- this expression has type `(u8, u16)` | - ^ ----------- this expression has type `(u8, u16)`
| | | | | |
| | expected `u8`, found `u16` | | expected `u8`, found `u16`
| first introduced with type `u8` here | first introduced with type `u8` here
| |
= note: a binding must have the same type in all alternatives = note: a binding must have the same type in all alternatives

View file

@ -37,11 +37,11 @@ fn main() {
if let &(Ok(x) | Err(x)) = res { if let &(Ok(x) | Err(x)) = res {
drop::<u8>(x); drop::<u8>(x);
} }
let Ok(mut x) | &Err(mut x) = res; let (Ok(mut x) | &Err(mut x)) = res;
drop::<u8>(x); drop::<u8>(x);
let &(Ok(x) | Err(x)) = res; let &(Ok(x) | Err(x)) = res;
drop::<u8>(x); drop::<u8>(x);
let Ok(x) | Err(x) = res; let (Ok(x) | Err(x)) = res;
drop::<&u8>(x); drop::<&u8>(x);
for Ok(mut x) | &Err(mut x) in std::iter::once(res) { for Ok(mut x) | &Err(mut x) in std::iter::once(res) {
drop::<u8>(x); drop::<u8>(x);
@ -119,9 +119,9 @@ fn main() {
} }
let tri = &Tri::A(&Ok(0)); let tri = &Tri::A(&Ok(0));
let Tri::A(Ok(mut x) | Err(mut x)) let (Tri::A(Ok(mut x) | Err(mut x))
| Tri::B(&Ok(mut x) | Err(mut x)) | Tri::B(&Ok(mut x) | Err(mut x))
| &Tri::C(Ok(mut x) | Err(mut x)) = tri; | &Tri::C(Ok(mut x) | Err(mut x))) = tri;
drop::<u8>(x); drop::<u8>(x);
match tri { match tri {

View file

@ -14,8 +14,19 @@ fn no_top_level_or_patterns() {
// -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`. // -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`.
// ...and for now neither do we allow or-patterns at the top level of functions. // ...and for now neither do we allow or-patterns at the top level of functions.
fn fun1(A | B: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses fn fun1(A | B: E) {}
//~^ ERROR top-level or-patterns are not allowed
fn fun2(| A | B: E) {} fn fun2(| A | B: E) {}
//~^ ERROR an or-pattern parameter must be wrapped in parentheses //~^ ERROR top-level or-patterns are not allowed
// We don't allow top-level or-patterns before type annotation in let-statements because we
// want to reserve this syntactic space for possible future type ascription.
let A | B: E = A;
//~^ ERROR top-level or-patterns are not allowed
let | A | B: E = A;
//~^ ERROR top-level or-patterns are not allowed
let (A | B): E = A; // ok -- wrapped in parens
} }

View file

@ -1,15 +1,27 @@
error: an or-pattern parameter must be wrapped in parentheses error: top-level or-patterns are not allowed in function parameters
--> $DIR/or-patterns-syntactic-fail.rs:17:13 --> $DIR/or-patterns-syntactic-fail.rs:17:13
| |
LL | fn fun1(A | B: E) {} LL | fn fun1(A | B: E) {}
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)` | ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
error: an or-pattern parameter must be wrapped in parentheses error: top-level or-patterns are not allowed in function parameters
--> $DIR/or-patterns-syntactic-fail.rs:19:13 --> $DIR/or-patterns-syntactic-fail.rs:20:13
| |
LL | fn fun2(| A | B: E) {} LL | fn fun2(| A | B: E) {}
| ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)` | ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/or-patterns-syntactic-fail.rs:25:9
|
LL | let A | B: E = A;
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/or-patterns-syntactic-fail.rs:28:9
|
LL | let | A | B: E = A;
| ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
error[E0369]: no implementation for `E | ()` error[E0369]: no implementation for `E | ()`
--> $DIR/or-patterns-syntactic-fail.rs:13:22 --> $DIR/or-patterns-syntactic-fail.rs:13:22
| |
@ -20,6 +32,6 @@ LL | let _ = |A | B: E| ();
| |
= note: an implementation of `std::ops::BitOr` might be missing for `E` = note: an implementation of `std::ops::BitOr` might be missing for `E`
error: aborting due to 3 previous errors error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0369`. For more information about this error, try `rustc --explain E0369`.

View file

@ -23,11 +23,11 @@ accept_pat!([p | q]);
#[cfg(FALSE)] #[cfg(FALSE)]
fn or_patterns() { fn or_patterns() {
// Top level of `let`: // Top level of `let`:
let | A | B; let (| A | B);
let A | B; let (A | B);
let A | B: u8; let (A | B): u8;
let A | B = 0; let (A | B) = 0;
let A | B: u8 = 0; let (A | B): u8 = 0;
// Top level of `for`: // Top level of `for`:
for | A | B in 0 {} for | A | B in 0 {}
@ -69,10 +69,10 @@ fn or_patterns() {
let [A | B, .. | ..]; let [A | B, .. | ..];
// These bind as `(prefix p) | q` as opposed to `prefix (p | q)`: // These bind as `(prefix p) | q` as opposed to `prefix (p | q)`:
let box 0 | 1; // Unstable; we *can* the precedence if we want. let (box 0 | 1); // Unstable; we *can* change the precedence if we want.
let &0 | 1; let (&0 | 1);
let &mut 0 | 1; let (&mut 0 | 1);
let x @ 0 | 1; let (x @ 0 | 1);
let ref x @ 0 | 1; let (ref x @ 0 | 1);
let ref mut x @ 0 | 1; let (ref mut x @ 0 | 1);
} }

View file

@ -9,7 +9,7 @@ fn main() {}
#[cfg(FALSE)] #[cfg(FALSE)]
fn leading() { fn leading() {
fn fun1( A: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses fn fun1( A: E) {} //~ ERROR top-level or-patterns are not allowed
fn fun2( A: E) {} //~ ERROR unexpected `||` before function parameter fn fun2( A: E) {} //~ ERROR unexpected `||` before function parameter
let ( | A): E; let ( | A): E;
let ( | A): (E); //~ ERROR unexpected token `||` in pattern let ( | A): (E); //~ ERROR unexpected token `||` in pattern
@ -40,6 +40,9 @@ fn trailing() {
//~^ ERROR a trailing `|` is not allowed in an or-pattern //~^ ERROR a trailing `|` is not allowed in an or-pattern
} }
// These test trailing-vert in `let` bindings, but they also test that we don't emit a
// duplicate suggestion that would confuse rustfix.
let a : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern let a : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
let a = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern let a = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
let a ; //~ ERROR a trailing `|` is not allowed in an or-pattern let a ; //~ ERROR a trailing `|` is not allowed in an or-pattern

View file

@ -9,7 +9,7 @@ fn main() {}
#[cfg(FALSE)] #[cfg(FALSE)]
fn leading() { fn leading() {
fn fun1( | A: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses fn fun1( | A: E) {} //~ ERROR top-level or-patterns are not allowed
fn fun2( || A: E) {} //~ ERROR unexpected `||` before function parameter fn fun2( || A: E) {} //~ ERROR unexpected `||` before function parameter
let ( | A): E; let ( | A): E;
let ( || A): (E); //~ ERROR unexpected token `||` in pattern let ( || A): (E); //~ ERROR unexpected token `||` in pattern
@ -40,6 +40,9 @@ fn trailing() {
//~^ ERROR a trailing `|` is not allowed in an or-pattern //~^ ERROR a trailing `|` is not allowed in an or-pattern
} }
// These test trailing-vert in `let` bindings, but they also test that we don't emit a
// duplicate suggestion that would confuse rustfix.
let a | : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern let a | : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
let a | = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern let a | = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
let a | ; //~ ERROR a trailing `|` is not allowed in an or-pattern let a | ; //~ ERROR a trailing `|` is not allowed in an or-pattern

View file

@ -1,8 +1,8 @@
error: an or-pattern parameter must be wrapped in parentheses error: top-level or-patterns are not allowed in function parameters
--> $DIR/remove-leading-vert.rs:12:14 --> $DIR/remove-leading-vert.rs:12:14
| |
LL | fn fun1( | A: E) {} LL | fn fun1( | A: E) {}
| ^^^ help: remove the leading `|`: `A` | ^^^ help: remove the `|`: `A`
error: unexpected `||` before function parameter error: unexpected `||` before function parameter
--> $DIR/remove-leading-vert.rs:13:14 --> $DIR/remove-leading-vert.rs:13:14
@ -135,7 +135,7 @@ LL | | A | B | => {}
| while parsing this or-pattern starting here | while parsing this or-pattern starting here
error: a trailing `|` is not allowed in an or-pattern error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:43:11 --> $DIR/remove-leading-vert.rs:46:11
| |
LL | let a | : u8 = 0; LL | let a | : u8 = 0;
| - ^ help: remove the `|` | - ^ help: remove the `|`
@ -143,7 +143,7 @@ LL | let a | : u8 = 0;
| while parsing this or-pattern starting here | while parsing this or-pattern starting here
error: a trailing `|` is not allowed in an or-pattern error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:44:11 --> $DIR/remove-leading-vert.rs:47:11
| |
LL | let a | = 0; LL | let a | = 0;
| - ^ help: remove the `|` | - ^ help: remove the `|`
@ -151,7 +151,7 @@ LL | let a | = 0;
| while parsing this or-pattern starting here | while parsing this or-pattern starting here
error: a trailing `|` is not allowed in an or-pattern error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:45:11 --> $DIR/remove-leading-vert.rs:48:11
| |
LL | let a | ; LL | let a | ;
| - ^ help: remove the `|` | - ^ help: remove the `|`

@ -1 +1 @@
Subproject commit c68432f1e5cbbc09833699a951b1b5b059651dff Subproject commit 970bc67c3775781b9708c8a36893576b9459c64a

View file

@ -885,7 +885,9 @@ struct MinifyingSugg<'a>(Sugg<'a>);
impl<'a> MinifyingSugg<'a> { impl<'a> MinifyingSugg<'a> {
fn as_str(&self) -> &str { fn as_str(&self) -> &str {
let Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s) = &self.0; let s = match &self.0 {
Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s) => s,
};
s.as_ref() s.as_ref()
} }