mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
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:
commit
3a5d45f68c
@ -1,8 +1,31 @@
|
||||
# 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
|
||||
|
||||
@ -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/
|
||||
[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
|
||||
[internals]: https://internals.rust-lang.org
|
||||
[rust-discord]: http://discord.gg/rust-lang
|
||||
[rust-zulip]: https://rust-lang.zulipchat.com
|
||||
|
85
Cargo.lock
85
Cargo.lock
@ -37,7 +37,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
@ -325,6 +325,7 @@ dependencies = [
|
||||
"openssl",
|
||||
"percent-encoding 2.1.0",
|
||||
"pretty_env_logger",
|
||||
"rand 0.8.3",
|
||||
"rustc-workspace-hack",
|
||||
"rustfix",
|
||||
"same-file",
|
||||
@ -757,7 +758,7 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
name = "core"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1662,7 +1663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
|
||||
dependencies = [
|
||||
"bitmaps",
|
||||
"rand_core",
|
||||
"rand_core 0.5.1",
|
||||
"rand_xoshiro",
|
||||
"sized-chunks",
|
||||
"typenum",
|
||||
@ -1867,7 +1868,7 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -1912,9 +1913,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.85"
|
||||
version = "0.2.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3"
|
||||
checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
@ -2308,7 +2309,7 @@ dependencies = [
|
||||
"hex 0.4.2",
|
||||
"libc",
|
||||
"log",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"rustc-workspace-hack",
|
||||
"rustc_version",
|
||||
"shell-escape",
|
||||
@ -2508,7 +2509,7 @@ dependencies = [
|
||||
"log",
|
||||
"mio-named-pipes",
|
||||
"miow 0.3.6",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"tokio",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
@ -2645,7 +2646,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2892,12 +2893,24 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.14",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc 0.2.0",
|
||||
"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]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
@ -2905,7 +2918,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"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]]
|
||||
@ -2917,13 +2940,31 @@ dependencies = [
|
||||
"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]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
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]]
|
||||
@ -2932,7 +2973,7 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2941,7 +2982,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2950,7 +2991,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3082,7 +3123,7 @@ dependencies = [
|
||||
"num_cpus",
|
||||
"ordslice",
|
||||
"racer",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"rayon",
|
||||
"regex",
|
||||
"rls-analysis",
|
||||
@ -3153,7 +3194,7 @@ dependencies = [
|
||||
"env_logger 0.7.1",
|
||||
"futures 0.3.12",
|
||||
"log",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"rls-data",
|
||||
"rls-ipc",
|
||||
"serde",
|
||||
@ -3933,7 +3974,7 @@ dependencies = [
|
||||
name = "rustc_incremental"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
"rustc_fs_util",
|
||||
@ -4975,7 +5016,7 @@ dependencies = [
|
||||
"panic_abort",
|
||||
"panic_unwind",
|
||||
"profiler_builtins",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"rustc-demangle",
|
||||
"unwind",
|
||||
"wasi",
|
||||
@ -5106,7 +5147,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"redox_syscall 0.1.57",
|
||||
"remove_dir_all",
|
||||
"winapi 0.3.9",
|
||||
|
@ -1073,7 +1073,7 @@ pub struct Expr {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
impl Expr {
|
||||
@ -2755,7 +2755,7 @@ pub enum ItemKind {
|
||||
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);
|
||||
|
||||
impl ItemKind {
|
||||
@ -2829,7 +2829,7 @@ pub enum AssocItemKind {
|
||||
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);
|
||||
|
||||
impl AssocItemKind {
|
||||
@ -2881,7 +2881,7 @@ pub enum ForeignItemKind {
|
||||
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);
|
||||
|
||||
impl From<ForeignItemKind> for ItemKind {
|
||||
|
@ -244,7 +244,7 @@ pub enum TokenKind {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
#[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.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
rustc_data_structures::static_assert_size!(Nonterminal, 48);
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
|
||||
|
@ -189,7 +189,7 @@ pub struct TokenStream(pub(crate) Lrc<Vec<TreeAndSpacing>>);
|
||||
pub type TreeAndSpacing = (TokenTree, Spacing);
|
||||
|
||||
// `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);
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable)]
|
||||
|
@ -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.
|
||||
// (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);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
|
||||
|
@ -3088,7 +3088,7 @@ impl<'hir> Node<'hir> {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
rustc_data_structures::static_assert_size!(super::Block<'static>, 48);
|
||||
rustc_data_structures::static_assert_size!(super::Expr<'static>, 72);
|
||||
|
@ -408,7 +408,7 @@ pub enum SubregionOrigin<'tcx> {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
/// Times when we replace late-bound regions with variables:
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
#[macro_use]
|
||||
extern crate rustc_data_structures;
|
||||
#[macro_use]
|
||||
|
@ -56,7 +56,7 @@ pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
|
||||
pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
|
||||
|
||||
// `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);
|
||||
|
||||
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
|
||||
|
@ -872,7 +872,7 @@ impl EarlyLintPass for UnusedParens {
|
||||
|
||||
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
|
||||
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)
|
||||
|
@ -40,7 +40,7 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
|
||||
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);
|
||||
|
||||
/// 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);
|
||||
|
||||
pub enum InterpError<'tcx> {
|
||||
|
@ -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);
|
||||
|
||||
impl<'tcx> ConstValue<'tcx> {
|
||||
@ -111,7 +111,7 @@ pub enum Scalar<Tag = ()> {
|
||||
Ptr(Pointer<Tag>),
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(Scalar, 24);
|
||||
|
||||
// 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,
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(ScalarMaybeUninit, 24);
|
||||
|
||||
impl<Tag> From<Scalar<Tag>> for ScalarMaybeUninit<Tag> {
|
||||
|
@ -951,7 +951,7 @@ pub struct LocalDecl<'tcx> {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
/// 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.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(Statement<'_>, 32);
|
||||
|
||||
impl Statement<'_> {
|
||||
@ -1755,7 +1755,7 @@ impl<V, T> ProjectionElem<V, T> {
|
||||
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
|
||||
|
||||
// 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);
|
||||
|
||||
/// Alias for projections as they appear in `UserTypeProjection`, where we
|
||||
|
@ -17,7 +17,7 @@ pub struct PlaceTy<'tcx> {
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
impl<'tcx> PlaceTy<'tcx> {
|
||||
|
@ -340,7 +340,7 @@ impl ObligationCauseCode<'_> {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
|
@ -23,7 +23,7 @@ pub struct Const<'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);
|
||||
|
||||
impl<'tcx> Const<'tcx> {
|
||||
|
@ -37,7 +37,7 @@ pub enum ConstKind<'tcx> {
|
||||
Error(ty::DelaySpanBugEmitted),
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(ConstKind<'_>, 40);
|
||||
|
||||
impl<'tcx> ConstKind<'tcx> {
|
||||
|
@ -483,7 +483,7 @@ impl<'tcx> TyS<'tcx> {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
impl<'tcx> Ord for TyS<'tcx> {
|
||||
@ -1030,7 +1030,7 @@ crate struct PredicateInner<'tcx> {
|
||||
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);
|
||||
|
||||
#[derive(Clone, Copy, Lift)]
|
||||
|
@ -231,7 +231,7 @@ impl TyKind<'tcx> {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
/// A closure can be modeled as a struct that looks like:
|
||||
|
@ -32,7 +32,7 @@ pub enum Immediate<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);
|
||||
|
||||
impl<Tag> From<ScalarMaybeUninit<Tag>> for Immediate<Tag> {
|
||||
@ -95,7 +95,7 @@ pub struct ImmTy<'tcx, Tag = ()> {
|
||||
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);
|
||||
|
||||
impl<Tag: Copy> std::fmt::Display for ImmTy<'tcx, Tag> {
|
||||
@ -162,7 +162,7 @@ pub struct OpTy<'tcx, Tag = ()> {
|
||||
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);
|
||||
|
||||
impl<'tcx, Tag> std::ops::Deref for OpTy<'tcx, Tag> {
|
||||
|
@ -33,7 +33,7 @@ pub enum MemPlaceMeta<Tag = ()> {
|
||||
Poison,
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
rustc_data_structures::static_assert_size!(MemPlaceMeta, 24);
|
||||
|
||||
impl<Tag> MemPlaceMeta<Tag> {
|
||||
@ -74,7 +74,7 @@ pub struct MemPlace<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);
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
|
||||
@ -87,7 +87,7 @@ pub enum Place<Tag = ()> {
|
||||
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);
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -96,7 +96,7 @@ pub struct PlaceTy<'tcx, Tag = ()> {
|
||||
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);
|
||||
|
||||
impl<'tcx, Tag> std::ops::Deref for PlaceTy<'tcx, Tag> {
|
||||
@ -114,7 +114,7 @@ pub struct MPlaceTy<'tcx, Tag = ()> {
|
||||
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);
|
||||
|
||||
impl<'tcx, Tag> std::ops::Deref for MPlaceTy<'tcx, Tag> {
|
||||
|
@ -96,7 +96,7 @@ crate enum StmtKind<'tcx> {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
/// The Thir trait implementor lowers their expressions (`&'tcx H::Expr`)
|
||||
|
@ -1757,8 +1757,9 @@ impl<'a> Parser<'a> {
|
||||
let (pat, ty) = if is_name_required || this.is_named_param() {
|
||||
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
|
||||
|
||||
let pat = this.parse_fn_param_pat()?;
|
||||
if let Err(mut err) = this.expect(&token::Colon) {
|
||||
let (pat, colon) = this.parse_fn_param_pat_colon()?;
|
||||
if !colon {
|
||||
let mut err = this.unexpected::<()>().unwrap_err();
|
||||
return if let Some(ident) =
|
||||
this.parameter_without_type(&mut err, pat, is_name_required, first_param)
|
||||
{
|
||||
|
@ -31,6 +31,18 @@ pub enum RecoverComma {
|
||||
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> {
|
||||
/// Parses a pattern.
|
||||
///
|
||||
@ -55,9 +67,26 @@ impl<'a> Parser<'a> {
|
||||
gate_or: GateOr,
|
||||
rc: RecoverComma,
|
||||
) -> 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).
|
||||
let leading_vert_span =
|
||||
if self.eat_or_separator(None) { Some(self.prev_token.span) } else { None };
|
||||
let (leading_vert_span, mut trailing_vert) = match self.eat_or_separator(None) {
|
||||
EatOrResult::AteOr => (Some(self.prev_token.span), false),
|
||||
EatOrResult::TrailingVert => (None, true),
|
||||
EatOrResult::None => (None, false),
|
||||
};
|
||||
|
||||
// Parse the first pattern (`p_0`).
|
||||
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
|
||||
// diagnostics.
|
||||
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`.
|
||||
let lo = leading_vert_span.unwrap_or(first_pat.span);
|
||||
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| {
|
||||
err.span_label(lo, WHILE_PARSING_OR_MSG);
|
||||
err
|
||||
@ -101,15 +138,63 @@ impl<'a> Parser<'a> {
|
||||
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.
|
||||
pub(super) fn parse_fn_param_pat(&mut self) -> PResult<'a, P<Pat>> {
|
||||
// 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
|
||||
// allows us to print a better error message.
|
||||
//
|
||||
/// Parse a pattern and (maybe) a `Colon` in positions where a pattern may be followed by a
|
||||
/// type annotation (e.g. for `let` bindings or `fn` params).
|
||||
///
|
||||
/// Generally, this corresponds to `pat_no_top_alt` followed by an optional `Colon`. It will
|
||||
/// 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
|
||||
// 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
|
||||
@ -128,53 +213,28 @@ impl<'a> Parser<'a> {
|
||||
self.bump();
|
||||
}
|
||||
|
||||
let pat = self.parse_pat_allow_top_alt(PARAM_EXPECTED, GateOr::No, RecoverComma::No)?;
|
||||
|
||||
if let PatKind::Or(..) = &pat.kind {
|
||||
self.ban_illegal_fn_param_or_pat(&pat);
|
||||
}
|
||||
|
||||
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();
|
||||
self.parse_pat_before_ty(
|
||||
PARAM_EXPECTED,
|
||||
GateOr::No,
|
||||
RecoverComma::No,
|
||||
"function parameters",
|
||||
)
|
||||
}
|
||||
|
||||
/// Eat the or-pattern `|` separator.
|
||||
/// 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) {
|
||||
return false;
|
||||
}
|
||||
|
||||
match self.token.kind {
|
||||
token::OrOr => {
|
||||
EatOrResult::TrailingVert
|
||||
} else if matches!(self.token.kind, token::OrOr) {
|
||||
// Found `||`; Recover and pretend we parsed `|`.
|
||||
self.ban_unexpected_or_or(lo);
|
||||
self.bump();
|
||||
true
|
||||
}
|
||||
_ => self.eat(&token::BinOp(token::Or)),
|
||||
EatOrResult::AteOr
|
||||
} else if self.eat(&token::BinOp(token::Or)) {
|
||||
EatOrResult::AteOr
|
||||
} else {
|
||||
EatOrResult::None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,8 @@ use rustc_ast::token::{self, TokenKind};
|
||||
use rustc_ast::util::classify;
|
||||
use rustc_ast::AstLike;
|
||||
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_span::source_map::{BytePos, Span};
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
@ -220,9 +221,10 @@ impl<'a> Parser<'a> {
|
||||
/// Parses a local variable declaration.
|
||||
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
|
||||
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 `:`
|
||||
// instead of an `=` typo.
|
||||
let parser_snapshot_before_type = self.clone();
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
#[macro_use]
|
||||
extern crate rustc_data_structures;
|
||||
#[macro_use]
|
||||
|
@ -87,7 +87,7 @@ pub struct PendingPredicateObligation<'tcx> {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
impl<'a, 'tcx> FulfillmentContext<'tcx> {
|
||||
|
@ -566,7 +566,7 @@ impl<T: Ord> BinaryHeap<T> {
|
||||
let mut 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
|
||||
// SAFETY: child < end - 1 < self.len() and
|
||||
// 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;
|
||||
|
||||
// Loop invariant: child == 2 * hole.pos() + 1.
|
||||
while child < end - 1 {
|
||||
while child <= end.saturating_sub(2) {
|
||||
// SAFETY: child < end - 1 < self.len() and
|
||||
// child + 1 < end <= self.len(), so they're valid indexes.
|
||||
// child == 2 * hole.pos() + 1 != hole.pos() and
|
||||
|
@ -579,6 +579,7 @@ impl Ordering {
|
||||
/// ```
|
||||
#[derive(PartialEq, Eq, Debug, Copy, Clone, Default, Hash)]
|
||||
#[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);
|
||||
|
||||
#[stable(feature = "reverse_cmp_key", since = "1.19.0")]
|
||||
|
@ -16,7 +16,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
|
||||
panic_unwind = { path = "../panic_unwind", optional = true }
|
||||
panic_abort = { path = "../panic_abort" }
|
||||
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" }
|
||||
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
||||
unwind = { path = "../unwind" }
|
||||
|
@ -93,7 +93,7 @@ crate struct Item {
|
||||
}
|
||||
|
||||
// `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);
|
||||
|
||||
impl fmt::Debug for Item {
|
||||
|
27
src/test/codegen/issue-75525-bounds-checks.rs
Normal file
27
src/test/codegen/issue-75525-bounds-checks.rs
Normal 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 }
|
||||
}
|
@ -18,10 +18,10 @@ fn main() {
|
||||
let (A(a, _) | B(a), a) = (A(0, 1), 2);
|
||||
//~^ 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
|
||||
|
||||
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
|
||||
|
||||
match A(0, 1) {
|
||||
@ -29,17 +29,17 @@ fn main() {
|
||||
//~^ 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 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 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
|
||||
}
|
||||
|
@ -23,15 +23,15 @@ LL | let (A(a, _) | B(a), a) = (A(0, 1), 2);
|
||||
| ^ used in a pattern more than once
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||
@ -41,51 +41,51 @@ LL | B(a) | A(a, a) => {} // Let's ensure `match` has no funny business.
|
||||
| ^ used in a pattern more than once
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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}>>`
|
||||
| | |
|
||||
| | expected integer, found enum `E`
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
fn main() {
|
||||
// One level:
|
||||
let Ok(a) | Err(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(a) | Err(a)) = Ok(0);
|
||||
let (Ok(ref a) | Err(ref a)) = Ok(0);
|
||||
let (Ok(ref mut a) | Err(ref mut a)) = Ok(0);
|
||||
|
||||
// Two levels:
|
||||
enum Tri<S, T, U> {
|
||||
@ -20,10 +20,10 @@ fn main() {
|
||||
}
|
||||
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));
|
||||
|
||||
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<_, _>,
|
||||
> = Ok((V1(1), 1));
|
||||
|
@ -3,28 +3,28 @@
|
||||
|
||||
const fn foo((Ok(a) | Err(a)): Result<i32, i32>) {
|
||||
let x = Ok(3);
|
||||
let Ok(y) | Err(y) = x;
|
||||
let (Ok(y) | Err(y)) = x;
|
||||
}
|
||||
|
||||
const X: () = {
|
||||
let x = Ok(3);
|
||||
let Ok(y) | Err(y) = x;
|
||||
let (Ok(y) | Err(y)) = x;
|
||||
};
|
||||
|
||||
static Y: () = {
|
||||
let x = Ok(3);
|
||||
let Ok(y) | Err(y) = x;
|
||||
let (Ok(y) | Err(y)) = x;
|
||||
};
|
||||
|
||||
static mut Z: () = {
|
||||
let x = Ok(3);
|
||||
let Ok(y) | Err(y) = x;
|
||||
let (Ok(y) | Err(y)) = x;
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let _: [(); {
|
||||
let x = Ok(3);
|
||||
let Ok(y) | Err(y) = x;
|
||||
let (Ok(y) | Err(y)) = x;
|
||||
2
|
||||
}];
|
||||
}
|
||||
|
@ -5,4 +5,5 @@ fn main() {}
|
||||
#[cfg(FALSE)]
|
||||
fn gated_leading_vert_in_let() {
|
||||
let | A; //~ ERROR or-patterns syntax is experimental
|
||||
//~^ ERROR top-level or-patterns are not allowed
|
||||
}
|
||||
|
@ -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
|
||||
--> $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
|
||||
= 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`.
|
||||
|
@ -26,7 +26,9 @@ fn or_patterns() {
|
||||
// Gated:
|
||||
|
||||
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
|
||||
//~^ 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
|
||||
fn fun((A | B): _) {} //~ ERROR or-patterns syntax is experimental
|
||||
|
@ -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
|
||||
--> $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
|
||||
|
||||
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;
|
||||
| ^^^^^
|
||||
@ -26,7 +38,7 @@ LL | let A | B;
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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 {}
|
||||
| ^^^^^^^
|
||||
@ -35,7 +47,7 @@ LL | for | A | B in 0 {}
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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 {}
|
||||
| ^^^^^
|
||||
@ -44,7 +56,7 @@ LL | for A | B in 0 {}
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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): _) {}
|
||||
| ^^^^^
|
||||
@ -53,7 +65,7 @@ LL | fn fun((A | B): _) {}
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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| ();
|
||||
| ^^^^^
|
||||
@ -62,7 +74,7 @@ LL | let _ = |(A | B): u8| ();
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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);
|
||||
| ^^^^^
|
||||
@ -71,7 +83,7 @@ LL | let (A | B);
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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,);
|
||||
| ^^^^^
|
||||
@ -80,7 +92,7 @@ LL | let (A | B,);
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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);
|
||||
| ^^^^^
|
||||
@ -89,7 +101,7 @@ LL | let A(B | C);
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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);
|
||||
| ^^^^^
|
||||
@ -98,7 +110,7 @@ LL | let E::V(B | C);
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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 };
|
||||
| ^^^^^
|
||||
@ -107,7 +119,7 @@ LL | let S { f1: B | C, f2 };
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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 };
|
||||
| ^^^^^
|
||||
@ -116,7 +128,7 @@ LL | let E::V { f1: B | C, f2 };
|
||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||
|
||||
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];
|
||||
| ^^^^^
|
||||
@ -169,6 +181,6 @@ LL | accept_pat!([p | q]);
|
||||
= 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
|
||||
|
||||
error: aborting due to 19 previous errors
|
||||
error: aborting due to 21 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -11,4 +11,4 @@ enum E { A, B }
|
||||
use E::*;
|
||||
|
||||
#[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
|
||||
|
@ -11,4 +11,4 @@ enum E { A, B }
|
||||
use E::*;
|
||||
|
||||
#[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
|
||||
|
@ -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
|
||||
|
|
||||
LL | fn fun1(A | B: E) {}
|
||||
|
@ -4,23 +4,23 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
fn main() {
|
||||
// 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
|
||||
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
|
||||
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 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 `b` is bound inconsistently
|
||||
//~| ERROR mismatched types
|
||||
|
||||
// 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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
@ -1,57 +1,57 @@
|
||||
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
|
||||
| |
|
||||
| first binding
|
||||
|
||||
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
|
||||
| |
|
||||
| first binding
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
| |
|
||||
| first binding
|
||||
|
||||
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
|
||||
| |
|
||||
| first binding
|
||||
|
||||
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
|
||||
| | |
|
||||
| | types differ in mutability
|
||||
@ -62,9 +62,9 @@ LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
|
||||
= note: a binding must have the same type in all alternatives
|
||||
|
||||
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}), (_, _)>`
|
||||
| | |
|
||||
| | types differ in mutability
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![feature(or_patterns)]
|
||||
|
||||
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 {
|
||||
//~^ ERROR non-exhaustive patterns
|
||||
0 | (1 | 2) => {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
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
|
||||
|
|
||||
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||
@ -9,8 +9,8 @@ LL | let 0 | (1 | 2) = 0;
|
||||
= note: the matched value is of type `i32`
|
||||
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
|
||||
--> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:5:11
|
||||
|
@ -3,7 +3,7 @@
|
||||
#![feature(or_patterns)]
|
||||
|
||||
fn main() {
|
||||
let 0 | (1 | _) = 0;
|
||||
let (0 | (1 | _)) = 0;
|
||||
if let 0 | (1 | 2) = 0 {}
|
||||
if let x @ 0 | x @ (1 | 2) = 0 {}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// run-pass
|
||||
|
||||
fn or_pat_let(x: Result<u32, u32>) -> u32 {
|
||||
let Ok(y) | Err(y) = x;
|
||||
let (Ok(y) | Err(y)) = x;
|
||||
y
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ async fn a((x | s): String) {}
|
||||
//~| ERROR variable `s` is not bound in all patterns
|
||||
|
||||
async fn b() {
|
||||
let x | s = String::new();
|
||||
let (x | s) = String::new();
|
||||
//~^ ERROR variable `x` is not bound in all patterns
|
||||
//~| ERROR variable `s` is not bound in all patterns
|
||||
}
|
||||
|
@ -15,17 +15,17 @@ LL | async fn a((x | s): String) {}
|
||||
| variable not 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
|
||||
| |
|
||||
| pattern doesn't bind `s`
|
||||
|
||||
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`
|
||||
| |
|
||||
| variable not in all patterns
|
||||
|
@ -17,7 +17,7 @@ fn check_handling_of_paths() {
|
||||
}
|
||||
|
||||
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) {
|
||||
Some(alpha | beta) => {} //~ ERROR variable `beta` is not bound in all patterns
|
||||
}
|
||||
@ -31,19 +31,19 @@ fn check_misc_nesting() {
|
||||
|
||||
// One level:
|
||||
const X: E<u8> = B(0);
|
||||
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 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) | B(a) = X; //~ ERROR variable `b` 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 (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) | B(a)) = X; //~ ERROR variable `b` is not bound in all patterns
|
||||
|
||||
// Two levels:
|
||||
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(a), _) | B(A(a, _) | B(a)) = Y;
|
||||
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;
|
||||
//~^ 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 `b` is not bound in all patterns
|
||||
|
@ -1,7 +1,7 @@
|
||||
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`
|
||||
| | |
|
||||
| | variable not in all patterns
|
||||
@ -16,129 +16,129 @@ LL | Some(alpha | beta) => {}
|
||||
| pattern doesn't bind `beta`
|
||||
|
||||
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`
|
||||
| |
|
||||
| variable not 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
|
||||
| |
|
||||
| pattern doesn't bind `a`
|
||||
|
||||
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
|
||||
| |
|
||||
| pattern doesn't bind `a`
|
||||
|
||||
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`
|
||||
| |
|
||||
| variable not 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`
|
||||
| |
|
||||
| variable not in all patterns
|
||||
|
||||
error[E0408]: variable `b` is not bound in all patterns
|
||||
--> $DIR/missing-bindings.rs:39:19
|
||||
--> $DIR/missing-bindings.rs:39:20
|
||||
|
|
||||
LL | let A(a, b) | B(a) = X;
|
||||
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:9
|
||||
--> $DIR/missing-bindings.rs:43:10
|
||||
|
|
||||
LL | let A(A(..) | B(_), _) | B(a) = Y;
|
||||
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
|
||||
--> $DIR/missing-bindings.rs:44:12
|
||||
|
|
||||
LL | let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
|
||||
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
|
||||
--> $DIR/missing-bindings.rs:46:22
|
||||
|
|
||||
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 `a`
|
||||
| |
|
||||
| variable not in all patterns
|
||||
|
||||
error[E0408]: variable `b` is not bound in all patterns
|
||||
--> $DIR/missing-bindings.rs:46:21
|
||||
--> $DIR/missing-bindings.rs:46:22
|
||||
|
|
||||
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`
|
||||
| |
|
||||
| variable not in all patterns
|
||||
|
||||
error[E0408]: variable `c` is not bound in all patterns
|
||||
--> $DIR/missing-bindings.rs:46:11
|
||||
--> $DIR/missing-bindings.rs:46:12
|
||||
|
|
||||
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`
|
||||
|
||||
error[E0408]: variable `a` 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 `a`
|
||||
| |
|
||||
| variable not in all patterns
|
||||
|
||||
error[E0408]: variable `b` 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 `b`
|
||||
| |
|
||||
| variable not in all patterns
|
||||
|
||||
error[E0408]: variable `c` 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 `c`
|
||||
| |
|
||||
| variable not 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`
|
||||
| |
|
||||
| variable not 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
|
||||
| |
|
||||
| pattern doesn't bind `e`
|
||||
|
46
src/test/ui/or-patterns/nested-undelimited-precedence.rs
Normal file
46
src/test/ui/or-patterns/nested-undelimited-precedence.rs
Normal 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() {}
|
86
src/test/ui/or-patterns/nested-undelimited-precedence.stderr
Normal file
86
src/test/ui/or-patterns/nested-undelimited-precedence.stderr
Normal 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`.
|
@ -52,10 +52,10 @@ fn main() {
|
||||
= 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
|
||||
|
||||
let (x, y) | (y, x) = (0u8, 1u16);
|
||||
let ((x, y) | (y, x)) = (0u8, 1u16);
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
|
||||
|
@ -187,9 +187,9 @@ LL | = Some((0u8, Some((1u16, 2u32))))
|
||||
= note: a binding must have the same type in all alternatives
|
||||
|
||||
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`
|
||||
| | |
|
||||
| | expected `usize`, found `isize`
|
||||
@ -198,9 +198,9 @@ LL | let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2);
|
||||
= note: a binding must have the same type in all alternatives
|
||||
|
||||
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)`
|
||||
| | |
|
||||
| | expected `u16`, found `u8`
|
||||
@ -209,9 +209,9 @@ LL | let (x, y) | (y, x) = (0u8, 1u16);
|
||||
= note: a binding must have the same type in all alternatives
|
||||
|
||||
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)`
|
||||
| | |
|
||||
| | expected `u8`, found `u16`
|
||||
|
@ -37,11 +37,11 @@ fn main() {
|
||||
if let &(Ok(x) | Err(x)) = res {
|
||||
drop::<u8>(x);
|
||||
}
|
||||
let Ok(mut x) | &Err(mut x) = res;
|
||||
let (Ok(mut x) | &Err(mut x)) = res;
|
||||
drop::<u8>(x);
|
||||
let &(Ok(x) | Err(x)) = res;
|
||||
drop::<u8>(x);
|
||||
let Ok(x) | Err(x) = res;
|
||||
let (Ok(x) | Err(x)) = res;
|
||||
drop::<&u8>(x);
|
||||
for Ok(mut x) | &Err(mut x) in std::iter::once(res) {
|
||||
drop::<u8>(x);
|
||||
@ -119,9 +119,9 @@ fn main() {
|
||||
}
|
||||
|
||||
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::C(Ok(mut x) | Err(mut x)) = tri;
|
||||
| &Tri::C(Ok(mut x) | Err(mut x))) = tri;
|
||||
drop::<u8>(x);
|
||||
|
||||
match tri {
|
||||
|
@ -14,8 +14,19 @@ fn no_top_level_or_patterns() {
|
||||
// -------- 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.
|
||||
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) {}
|
||||
//~^ 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
|
||||
}
|
||||
|
@ -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
|
||||
|
|
||||
LL | fn fun1(A | B: E) {}
|
||||
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
|
||||
|
||||
error: an or-pattern parameter must be wrapped in parentheses
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:19:13
|
||||
error: top-level or-patterns are not allowed in function parameters
|
||||
--> $DIR/or-patterns-syntactic-fail.rs:20:13
|
||||
|
|
||||
LL | fn fun2(| A | B: E) {}
|
||||
| ^^^^^^^ 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 | ()`
|
||||
--> $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`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0369`.
|
||||
|
@ -23,11 +23,11 @@ accept_pat!([p | q]);
|
||||
#[cfg(FALSE)]
|
||||
fn or_patterns() {
|
||||
// Top level of `let`:
|
||||
let | A | B;
|
||||
let A | B;
|
||||
let A | B: u8;
|
||||
let A | B = 0;
|
||||
let A | B: u8 = 0;
|
||||
let (| A | B);
|
||||
let (A | B);
|
||||
let (A | B): u8;
|
||||
let (A | B) = 0;
|
||||
let (A | B): u8 = 0;
|
||||
|
||||
// Top level of `for`:
|
||||
for | A | B in 0 {}
|
||||
@ -69,10 +69,10 @@ fn or_patterns() {
|
||||
let [A | B, .. | ..];
|
||||
|
||||
// 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 &0 | 1;
|
||||
let &mut 0 | 1;
|
||||
let x @ 0 | 1;
|
||||
let ref x @ 0 | 1;
|
||||
let ref mut x @ 0 | 1;
|
||||
let (box 0 | 1); // Unstable; we *can* change the precedence if we want.
|
||||
let (&0 | 1);
|
||||
let (&mut 0 | 1);
|
||||
let (x @ 0 | 1);
|
||||
let (ref x @ 0 | 1);
|
||||
let (ref mut x @ 0 | 1);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ fn main() {}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
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
|
||||
let ( | A): E;
|
||||
let ( | A): (E); //~ ERROR unexpected token `||` in pattern
|
||||
@ -40,6 +40,9 @@ fn trailing() {
|
||||
//~^ 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 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||
let a ; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||
|
@ -9,7 +9,7 @@ fn main() {}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
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
|
||||
let ( | A): E;
|
||||
let ( || A): (E); //~ ERROR unexpected token `||` in pattern
|
||||
@ -40,6 +40,9 @@ fn trailing() {
|
||||
//~^ 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 | = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||
let a | ; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||
|
@ -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
|
||||
|
|
||||
LL | fn fun1( | A: E) {}
|
||||
| ^^^ help: remove the leading `|`: `A`
|
||||
| ^^^ help: remove the `|`: `A`
|
||||
|
||||
error: unexpected `||` before function parameter
|
||||
--> $DIR/remove-leading-vert.rs:13:14
|
||||
@ -135,7 +135,7 @@ LL | | A | B | => {}
|
||||
| while parsing this or-pattern starting here
|
||||
|
||||
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;
|
||||
| - ^ help: remove the `|`
|
||||
@ -143,7 +143,7 @@ LL | let a | : u8 = 0;
|
||||
| while parsing this or-pattern starting here
|
||||
|
||||
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;
|
||||
| - ^ help: remove the `|`
|
||||
@ -151,7 +151,7 @@ LL | let a | = 0;
|
||||
| while parsing this or-pattern starting here
|
||||
|
||||
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 | ;
|
||||
| - ^ help: remove the `|`
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c68432f1e5cbbc09833699a951b1b5b059651dff
|
||||
Subproject commit 970bc67c3775781b9708c8a36893576b9459c64a
|
@ -885,7 +885,9 @@ struct MinifyingSugg<'a>(Sugg<'a>);
|
||||
|
||||
impl<'a> MinifyingSugg<'a> {
|
||||
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()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user