Skip to content

Rollup of 8 pull requests #120365

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jan 26, 2024
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
cce93f0
Add `str::Lines::remainder`
WaffleLapkin Jan 30, 2023
42afefa
Initial implementation of `str::from_raw_parts[_mut]`
Sky9x Dec 31, 2023
c824399
Fix broken markdown in csky-unknown-linux-gnuabiv2.md
mbrubeck Jan 4, 2024
1b9a013
specialize `Bytes` on `StdinLock<'_>` by using the underlying `BufRea…
AldanTanneo Jan 17, 2024
8c2ae80
Don't manually resolve async closures in rustc_resolve
compiler-errors Jan 24, 2024
886108b
Add feature gate
Nadrieril Jan 8, 2024
95a14d4
Implement feature gate logic
Nadrieril Jan 18, 2024
8866449
Split assembly tests for ELF and MachO
nikic Jan 19, 2024
27717db
Builtin macros effectively have implicit #[collapse_debuginfo(yes)] a…
azhogin Jan 21, 2024
f94a942
Export core::str::from_raw_parts{,_mut} into alloc::str and std::str
dtolnay Jan 26, 2024
c0992f5
Rollup merge of #107464 - WaffleLapkin:all_that_remains_of_lines, r=d…
matthiaskrgr Jan 26, 2024
a37fa37
Rollup merge of #118803 - Nadrieril:min-exhaustive-patterns, r=compil…
matthiaskrgr Jan 26, 2024
912877d
Rollup merge of #119466 - Sky9x:str_from_raw_parts, r=dtolnay
matthiaskrgr Jan 26, 2024
cfa583b
Rollup merge of #120053 - AldanTanneo:specialize-stdinlock-bytes, r=t…
matthiaskrgr Jan 26, 2024
e04cba2
Rollup merge of #120124 - nikic:fix-assembly-test, r=davidtwco
matthiaskrgr Jan 26, 2024
626797b
Rollup merge of #120204 - azhogin:azhogin/collapse_debuginfo_for_buil…
matthiaskrgr Jan 26, 2024
e400311
Rollup merge of #120322 - compiler-errors:higher-ranked-async-closure…
matthiaskrgr Jan 26, 2024
ee2a2a3
Rollup merge of #120356 - mbrubeck:patch-2, r=ehuss
matthiaskrgr Jan 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
@@ -796,9 +796,15 @@ impl SyntaxExtension {
/// | external | no | if-ext | if-ext | yes |
/// | yes | yes | yes | yes | yes |
fn get_collapse_debuginfo(sess: &Session, attrs: &[ast::Attribute], is_local: bool) -> bool {
let collapse_debuginfo_attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
let mut collapse_debuginfo_attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
.map(|v| Self::collapse_debuginfo_by_name(sess, v))
.unwrap_or(CollapseMacroDebuginfo::Unspecified);
if collapse_debuginfo_attr == CollapseMacroDebuginfo::Unspecified
&& attr::contains_name(attrs, sym::rustc_builtin_macro)
{
collapse_debuginfo_attr = CollapseMacroDebuginfo::Yes;
}

let flag = sess.opts.unstable_opts.collapse_macro_debuginfo;
let attr = collapse_debuginfo_attr;
let ext = !is_local;
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
@@ -516,6 +516,9 @@ declare_features! (
(unstable, macro_metavar_expr, "1.61.0", Some(83527)),
/// Allows `#[marker]` on certain traits allowing overlapping implementations.
(unstable, marker_trait_attr, "1.30.0", Some(29864)),
/// Allows exhaustive pattern matching on types that contain uninhabited types in cases that are
/// unambiguously sound.
(incomplete, min_exhaustive_patterns, "CURRENT_RUSTC_VERSION", Some(119612)),
/// A minimal, sound subset of specialization intended to be used by the
/// standard library until the soundness issues with specialization
/// are fixed.
1 change: 1 addition & 0 deletions compiler/rustc_pattern_analysis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -95,6 +95,7 @@ pub trait TypeCx: Sized + fmt::Debug {
type PatData: Clone;

fn is_exhaustive_patterns_feature_on(&self) -> bool;
fn is_min_exhaustive_patterns_feature_on(&self) -> bool;

/// The number of fields for this constructor.
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize;
7 changes: 6 additions & 1 deletion compiler/rustc_pattern_analysis/src/rustc.rs
Original file line number Diff line number Diff line change
@@ -181,7 +181,9 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
// `field.ty()` doesn't normalize after substituting.
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
let is_uninhabited = cx.tcx.features().exhaustive_patterns && cx.is_uninhabited(ty);
let is_uninhabited = (cx.tcx.features().exhaustive_patterns
|| cx.tcx.features().min_exhaustive_patterns)
&& cx.is_uninhabited(ty);

if is_uninhabited && (!is_visible || is_non_exhaustive) {
None
@@ -863,6 +865,9 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
fn is_exhaustive_patterns_feature_on(&self) -> bool {
self.tcx.features().exhaustive_patterns
}
fn is_min_exhaustive_patterns_feature_on(&self) -> bool {
self.tcx.features().min_exhaustive_patterns
}

fn ctor_arity(&self, ctor: &crate::constructor::Constructor<Self>, ty: &Self::Ty) -> usize {
self.ctor_arity(ctor, *ty)
26 changes: 17 additions & 9 deletions compiler/rustc_pattern_analysis/src/usefulness.rs
Original file line number Diff line number Diff line change
@@ -548,11 +548,12 @@
//! [`ValidityConstraint::specialize`].
//!
//! Having said all that, in practice we don't fully follow what's been presented in this section.
//! Under `exhaustive_patterns`, we allow omitting empty arms even in `!known_valid` places, for
//! backwards-compatibility until we have a better alternative. Without `exhaustive_patterns`, we
//! mostly treat empty types as inhabited, except specifically a non-nested `!` or empty enum. In
//! this specific case we also allow the empty match regardless of place validity, for
//! backwards-compatibility. Hopefully we can eventually deprecate this.
//! Let's call "toplevel exception" the case where the match scrutinee itself has type `!` or
//! `EmptyEnum`. First, on stable rust, we require `_` patterns for empty types in all cases apart
//! from the toplevel exception. The `exhaustive_patterns` and `min_exaustive_patterns` allow
//! omitting patterns in the cases described above. There's a final detail: in the toplevel
//! exception or with the `exhaustive_patterns` feature, we ignore place validity when checking
//! whether a pattern is required for exhaustiveness. I (Nadrieril) hope to deprecate this behavior.
//!
//!
//!
@@ -1442,10 +1443,17 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
// We treat match scrutinees of type `!` or `EmptyEnum` differently.
let is_toplevel_exception =
is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
// Whether empty patterns can be omitted for exhaustiveness.
let can_omit_empty_arms = is_toplevel_exception || mcx.tycx.is_exhaustive_patterns_feature_on();
// Whether empty patterns are counted as useful or not.
let empty_arms_are_unreachable = place_validity.is_known_valid() && can_omit_empty_arms;
// Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if
// it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`).
let empty_arms_are_unreachable = place_validity.is_known_valid()
&& (is_toplevel_exception
|| mcx.tycx.is_exhaustive_patterns_feature_on()
|| mcx.tycx.is_min_exhaustive_patterns_feature_on());
// Whether empty patterns can be omitted for exhaustiveness. We ignore place validity in the
// toplevel exception and `exhaustive_patterns` cases for backwards compatibility.
let can_omit_empty_arms = empty_arms_are_unreachable
|| is_toplevel_exception
|| mcx.tycx.is_exhaustive_patterns_feature_on();

// Analyze the constructors present in this column.
let ctors = matrix.heads().map(|p| p.ctor());
29 changes: 0 additions & 29 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
@@ -4424,35 +4424,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ExprKind::Type(ref _type_expr, ref _ty) => {
visit::walk_expr(self, expr);
}
// `async |x| ...` gets desugared to `|x| async {...}`, so we need to
// resolve the arguments within the proper scopes so that usages of them inside the
// closure are detected as upvars rather than normal closure arg usages.
//
// Similarly, `gen |x| ...` gets desugared to `|x| gen {...}`, so we handle that too.
ExprKind::Closure(box ast::Closure {
coroutine_kind: Some(_),
ref fn_decl,
ref body,
..
}) => {
self.with_rib(ValueNS, RibKind::Normal, |this| {
this.with_label_rib(RibKind::FnOrCoroutine, |this| {
// Resolve arguments:
this.resolve_params(&fn_decl.inputs);
// No need to resolve return type --
// the outer closure return type is `FnRetTy::Default`.

// Now resolve the inner closure
{
// No need to resolve arguments: the inner closure has none.
// Resolve the return type:
visit::walk_fn_ret_ty(this, &fn_decl.output);
// Resolve the body
this.visit_expr(body);
}
})
});
}
// For closures, RibKind::FnOrCoroutine is added in visit_fn
ExprKind::Closure(box ast::Closure {
binder: ClosureBinder::For { ref generic_params, span },
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -1029,6 +1029,7 @@ symbols! {
min_const_fn,
min_const_generics,
min_const_unsafe_fn,
min_exhaustive_patterns,
min_specialization,
min_type_alias_impl_trait,
minnumf32,
2 changes: 2 additions & 0 deletions library/alloc/src/str.rs
Original file line number Diff line number Diff line change
@@ -30,6 +30,8 @@ pub use core::str::SplitAsciiWhitespace;
pub use core::str::SplitInclusive;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::SplitWhitespace;
#[unstable(feature = "str_from_raw_parts", issue = "119206")]
pub use core::str::{from_raw_parts, from_raw_parts_mut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{from_utf8, from_utf8_mut, Bytes, CharIndices, Chars};
#[stable(feature = "rust1", since = "1.0.0")]
40 changes: 39 additions & 1 deletion library/core/src/str/converts.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Ways to create a `str` from bytes slice.

use crate::mem;
use crate::{mem, ptr};

use super::validations::run_utf8_validation;
use super::Utf8Error;
@@ -205,3 +205,41 @@ pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
// comes from a reference which is guaranteed to be valid for writes.
unsafe { &mut *(v as *mut [u8] as *mut str) }
}

/// Creates an `&str` from a pointer and a length.
///
/// The pointed-to bytes must be valid UTF-8.
/// If this might not be the case, use `str::from_utf8(slice::from_raw_parts(ptr, len))`,
/// which will return an `Err` if the data isn't valid UTF-8.
///
/// This function is the `str` equivalent of [`slice::from_raw_parts`](crate::slice::from_raw_parts).
/// See that function's documentation for safety concerns and examples.
///
/// The mutable version of this function is [`from_raw_parts_mut`].
#[inline]
#[must_use]
#[unstable(feature = "str_from_raw_parts", issue = "119206")]
#[rustc_const_unstable(feature = "str_from_raw_parts", issue = "119206")]
pub const unsafe fn from_raw_parts<'a>(ptr: *const u8, len: usize) -> &'a str {
// SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
unsafe { &*ptr::from_raw_parts(ptr.cast(), len) }
}

/// Creates an `&mut str` from a pointer and a length.
///
/// The pointed-to bytes must be valid UTF-8.
/// If this might not be the case, use `str::from_utf8_mut(slice::from_raw_parts_mut(ptr, len))`,
/// which will return an `Err` if the data isn't valid UTF-8.
///
/// This function is the `str` equivalent of [`slice::from_raw_parts_mut`](crate::slice::from_raw_parts_mut).
/// See that function's documentation for safety concerns and examples.
///
/// The immutable version of this function is [`from_raw_parts`].
#[inline]
#[must_use]
#[unstable(feature = "str_from_raw_parts", issue = "119206")]
#[rustc_const_unstable(feature = "const_str_from_raw_parts_mut", issue = "119206")]
pub const unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a str {
// SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
unsafe { &mut *ptr::from_raw_parts_mut(ptr.cast(), len) }
}
25 changes: 25 additions & 0 deletions library/core/src/str/iter.rs
Original file line number Diff line number Diff line change
@@ -1187,6 +1187,31 @@ impl<'a> DoubleEndedIterator for Lines<'a> {
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for Lines<'_> {}

impl<'a> Lines<'a> {
/// Returns the remaining lines of the split string.
///
/// # Examples
///
/// ```
/// #![feature(str_lines_remainder)]
///
/// let mut lines = "a\nb\nc\nd".lines();
/// assert_eq!(lines.remainder(), Some("a\nb\nc\nd"));
///
/// lines.next();
/// assert_eq!(lines.remainder(), Some("b\nc\nd"));
///
/// lines.by_ref().for_each(drop);
/// assert_eq!(lines.remainder(), None);
/// ```
#[inline]
#[must_use]
#[unstable(feature = "str_lines_remainder", issue = "77998")]
pub fn remainder(&self) -> Option<&'a str> {
self.0.iter.remainder()
}
}

/// Created with the method [`lines_any`].
///
/// [`lines_any`]: str::lines_any
3 changes: 3 additions & 0 deletions library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
@@ -33,6 +33,9 @@ pub use converts::{from_utf8, from_utf8_unchecked};
#[stable(feature = "str_mut_extras", since = "1.20.0")]
pub use converts::{from_utf8_mut, from_utf8_unchecked_mut};

#[unstable(feature = "str_from_raw_parts", issue = "119206")]
pub use converts::{from_raw_parts, from_raw_parts_mut};

#[stable(feature = "rust1", since = "1.0.0")]
pub use error::{ParseBoolError, Utf8Error};

11 changes: 10 additions & 1 deletion library/std/src/io/stdio.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,9 @@ use crate::io::prelude::*;
use crate::cell::{Cell, RefCell};
use crate::fmt;
use crate::fs::File;
use crate::io::{self, BorrowedCursor, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
use crate::io::{
self, BorrowedCursor, BufReader, IoSlice, IoSliceMut, LineWriter, Lines, SpecReadByte,
};
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::{Arc, Mutex, MutexGuard, OnceLock, ReentrantMutex, ReentrantMutexGuard};
use crate::sys::stdio;
@@ -483,6 +485,13 @@ impl Read for StdinLock<'_> {
}
}

impl SpecReadByte for StdinLock<'_> {
#[inline]
fn spec_read_byte(&mut self) -> Option<io::Result<u8>> {
BufReader::spec_read_byte(&mut *self.inner)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for StdinLock<'_> {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@ cc = "${TOOLCHAIN_PATH}/bin/csky-linux-gnuabiv2-gcc"
[target.csky-unknown-linux-gnuabiv2hf]
# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN
cc = "${TOOLCHAIN_PATH}/bin/csky-linux-gnuabiv2-gcc"
```

### Build

65 changes: 1 addition & 64 deletions tests/assembly/targets/targets-elf.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,5 @@
// assembly-output: emit-asm
// ignore-tidy-linelength
// revisions: aarch64_apple_darwin
// [aarch64_apple_darwin] compile-flags: --target aarch64-apple-darwin
// [aarch64_apple_darwin] needs-llvm-components: aarch64
// revisions: aarch64_apple_ios
// [aarch64_apple_ios] compile-flags: --target aarch64-apple-ios
// [aarch64_apple_ios] needs-llvm-components: aarch64
// revisions: aarch64_apple_ios_macabi
// [aarch64_apple_ios_macabi] compile-flags: --target aarch64-apple-ios-macabi
// [aarch64_apple_ios_macabi] needs-llvm-components: aarch64
// revisions: aarch64_apple_ios_sim
// [aarch64_apple_ios_sim] compile-flags: --target aarch64-apple-ios-sim
// [aarch64_apple_ios_sim] needs-llvm-components: aarch64
// revisions: aarch64_apple_tvos
// [aarch64_apple_tvos] compile-flags: --target aarch64-apple-tvos
// [aarch64_apple_tvos] needs-llvm-components: aarch64
// revisions: aarch64_apple_tvos_sim
// [aarch64_apple_tvos_sim] compile-flags: --target aarch64-apple-tvos-sim
// [aarch64_apple_tvos_sim] needs-llvm-components: aarch64
// revisions: aarch64_apple_watchos
// [aarch64_apple_watchos] compile-flags: --target aarch64-apple-watchos
// [aarch64_apple_watchos] needs-llvm-components: aarch64
// revisions: aarch64_apple_watchos_sim
// [aarch64_apple_watchos_sim] compile-flags: --target aarch64-apple-watchos-sim
// [aarch64_apple_watchos_sim] needs-llvm-components: aarch64
// revisions: aarch64_be_unknown_linux_gnu
// [aarch64_be_unknown_linux_gnu] compile-flags: --target aarch64_be-unknown-linux-gnu
// [aarch64_be_unknown_linux_gnu] needs-llvm-components: aarch64
@@ -93,15 +69,6 @@
// revisions: aarch64_wrs_vxworks
// [aarch64_wrs_vxworks] compile-flags: --target aarch64-wrs-vxworks
// [aarch64_wrs_vxworks] needs-llvm-components: aarch64
// revisions: arm64_32_apple_watchos
// [arm64_32_apple_watchos] compile-flags: --target arm64_32-apple-watchos
// [arm64_32_apple_watchos] needs-llvm-components: aarch64
// revisions: arm64e_apple_darwin
// [arm64e_apple_darwin] compile-flags: --target arm64e-apple-darwin
// [arm64e_apple_darwin] needs-llvm-components: aarch64
// revisions: arm64e_apple_ios
// [arm64e_apple_ios] compile-flags: --target arm64e-apple-ios
// [arm64e_apple_ios] needs-llvm-components: aarch64
// revisions: arm_linux_androideabi
// [arm_linux_androideabi] compile-flags: --target arm-linux-androideabi
// [arm_linux_androideabi] needs-llvm-components: arm
@@ -201,18 +168,12 @@
// revisions: armv7a_none_eabihf
// [armv7a_none_eabihf] compile-flags: --target armv7a-none-eabihf
// [armv7a_none_eabihf] needs-llvm-components: arm
// revisions: armv7k_apple_watchos
// [armv7k_apple_watchos] compile-flags: --target armv7k-apple-watchos
// [armv7k_apple_watchos] needs-llvm-components: arm
// revisions: armv7r_none_eabi
// [armv7r_none_eabi] compile-flags: --target armv7r-none-eabi
// [armv7r_none_eabi] needs-llvm-components: arm
// revisions: armv7r_none_eabihf
// [armv7r_none_eabihf] compile-flags: --target armv7r-none-eabihf
// [armv7r_none_eabihf] needs-llvm-components: arm
// revisions: armv7s_apple_ios
// [armv7s_apple_ios] compile-flags: --target armv7s-apple-ios
// [armv7s_apple_ios] needs-llvm-components: arm
// FIXME: disabled since it fails on CI saying the csky component is missing
/*
revisions: csky_unknown_linux_gnuabiv2
@@ -228,9 +189,6 @@
// revisions: hexagon_unknown_none_elf
// [hexagon_unknown_none_elf] compile-flags: --target hexagon-unknown-none-elf
// [hexagon_unknown_none_elf] needs-llvm-components: hexagon
// revisions: i386_apple_ios
// [i386_apple_ios] compile-flags: --target i386-apple-ios
// [i386_apple_ios] needs-llvm-components: x86
// revisions: i586_pc_nto_qnx700
// [i586_pc_nto_qnx700] compile-flags: --target i586-pc-nto-qnx700
// [i586_pc_nto_qnx700] needs-llvm-components: x86
@@ -243,9 +201,6 @@
// revisions: i586_unknown_netbsd
// [i586_unknown_netbsd] compile-flags: --target i586-unknown-netbsd
// [i586_unknown_netbsd] needs-llvm-components: x86
// revisions: i686_apple_darwin
// [i686_apple_darwin] compile-flags: --target i686-apple-darwin
// [i686_apple_darwin] needs-llvm-components: x86
// revisions: i686_linux_android
// [i686_linux_android] compile-flags: --target i686-linux-android
// [i686_linux_android] needs-llvm-components: x86
@@ -537,21 +492,6 @@
// revisions: wasm32_wasi_preview2
// [wasm32_wasi_preview2] compile-flags: --target wasm32-wasi-preview2
// [wasm32_wasi_preview2] needs-llvm-components: webassembly
// revisions: x86_64_apple_darwin
// [x86_64_apple_darwin] compile-flags: --target x86_64-apple-darwin
// [x86_64_apple_darwin] needs-llvm-components: x86
// revisions: x86_64_apple_ios
// [x86_64_apple_ios] compile-flags: --target x86_64-apple-ios
// [x86_64_apple_ios] needs-llvm-components: x86
// revisions: x86_64_apple_ios_macabi
// [x86_64_apple_ios_macabi] compile-flags: --target x86_64-apple-ios-macabi
// [x86_64_apple_ios_macabi] needs-llvm-components: x86
// revisions: x86_64_apple_tvos
// [x86_64_apple_tvos] compile-flags: --target x86_64-apple-tvos
// [x86_64_apple_tvos] needs-llvm-components: x86
// revisions: x86_64_apple_watchos_sim
// [x86_64_apple_watchos_sim] compile-flags: --target x86_64-apple-watchos-sim
// [x86_64_apple_watchos_sim] needs-llvm-components: x86
// revisions: x86_64_fortanix_unknown_sgx
// [x86_64_fortanix_unknown_sgx] compile-flags: --target x86_64-fortanix-unknown-sgx
// [x86_64_fortanix_unknown_sgx] needs-llvm-components: x86
@@ -618,9 +558,6 @@
// revisions: x86_64_wrs_vxworks
// [x86_64_wrs_vxworks] compile-flags: --target x86_64-wrs-vxworks
// [x86_64_wrs_vxworks] needs-llvm-components: x86
// revisions: x86_64h_apple_darwin
// [x86_64h_apple_darwin] compile-flags: --target x86_64h-apple-darwin
// [x86_64h_apple_darwin] needs-llvm-components: x86

// Sanity-check that each target can produce assembly code.

@@ -636,4 +573,4 @@ pub fn test() -> u8 {
42
}

// CHECK: .section
// CHECK: .text
81 changes: 81 additions & 0 deletions tests/assembly/targets/targets-macho.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// assembly-output: emit-asm
// ignore-tidy-linelength
// revisions: aarch64_apple_darwin
// [aarch64_apple_darwin] compile-flags: --target aarch64-apple-darwin
// [aarch64_apple_darwin] needs-llvm-components: aarch64
// revisions: aarch64_apple_ios
// [aarch64_apple_ios] compile-flags: --target aarch64-apple-ios
// [aarch64_apple_ios] needs-llvm-components: aarch64
// revisions: aarch64_apple_ios_macabi
// [aarch64_apple_ios_macabi] compile-flags: --target aarch64-apple-ios-macabi
// [aarch64_apple_ios_macabi] needs-llvm-components: aarch64
// revisions: aarch64_apple_ios_sim
// [aarch64_apple_ios_sim] compile-flags: --target aarch64-apple-ios-sim
// [aarch64_apple_ios_sim] needs-llvm-components: aarch64
// revisions: aarch64_apple_tvos
// [aarch64_apple_tvos] compile-flags: --target aarch64-apple-tvos
// [aarch64_apple_tvos] needs-llvm-components: aarch64
// revisions: aarch64_apple_tvos_sim
// [aarch64_apple_tvos_sim] compile-flags: --target aarch64-apple-tvos-sim
// [aarch64_apple_tvos_sim] needs-llvm-components: aarch64
// revisions: aarch64_apple_watchos
// [aarch64_apple_watchos] compile-flags: --target aarch64-apple-watchos
// [aarch64_apple_watchos] needs-llvm-components: aarch64
// revisions: aarch64_apple_watchos_sim
// [aarch64_apple_watchos_sim] compile-flags: --target aarch64-apple-watchos-sim
// [aarch64_apple_watchos_sim] needs-llvm-components: aarch64
// revisions: arm64_32_apple_watchos
// [arm64_32_apple_watchos] compile-flags: --target arm64_32-apple-watchos
// [arm64_32_apple_watchos] needs-llvm-components: aarch64
// revisions: arm64e_apple_darwin
// [arm64e_apple_darwin] compile-flags: --target arm64e-apple-darwin
// [arm64e_apple_darwin] needs-llvm-components: aarch64
// revisions: arm64e_apple_ios
// [arm64e_apple_ios] compile-flags: --target arm64e-apple-ios
// [arm64e_apple_ios] needs-llvm-components: aarch64
// revisions: armv7k_apple_watchos
// [armv7k_apple_watchos] compile-flags: --target armv7k-apple-watchos
// [armv7k_apple_watchos] needs-llvm-components: arm
// revisions: armv7s_apple_ios
// [armv7s_apple_ios] compile-flags: --target armv7s-apple-ios
// [armv7s_apple_ios] needs-llvm-components: arm
// revisions: i386_apple_ios
// [i386_apple_ios] compile-flags: --target i386-apple-ios
// [i386_apple_ios] needs-llvm-components: x86
// revisions: i686_apple_darwin
// [i686_apple_darwin] compile-flags: --target i686-apple-darwin
// [i686_apple_darwin] needs-llvm-components: x86
// revisions: x86_64_apple_darwin
// [x86_64_apple_darwin] compile-flags: --target x86_64-apple-darwin
// [x86_64_apple_darwin] needs-llvm-components: x86
// revisions: x86_64_apple_ios
// [x86_64_apple_ios] compile-flags: --target x86_64-apple-ios
// [x86_64_apple_ios] needs-llvm-components: x86
// revisions: x86_64_apple_ios_macabi
// [x86_64_apple_ios_macabi] compile-flags: --target x86_64-apple-ios-macabi
// [x86_64_apple_ios_macabi] needs-llvm-components: x86
// revisions: x86_64_apple_tvos
// [x86_64_apple_tvos] compile-flags: --target x86_64-apple-tvos
// [x86_64_apple_tvos] needs-llvm-components: x86
// revisions: x86_64_apple_watchos_sim
// [x86_64_apple_watchos_sim] compile-flags: --target x86_64-apple-watchos-sim
// [x86_64_apple_watchos_sim] needs-llvm-components: x86
// revisions: x86_64h_apple_darwin
// [x86_64h_apple_darwin] compile-flags: --target x86_64h-apple-darwin
// [x86_64h_apple_darwin] needs-llvm-components: x86

// Sanity-check that each target can produce assembly code.

#![feature(no_core, lang_items)]
#![no_std]
#![no_core]
#![crate_type = "lib"]

#[lang = "sized"]
trait Sized {}

pub fn test() -> u8 {
42
}

// CHECK: .section __TEXT,__text
12 changes: 12 additions & 0 deletions tests/ui/async-await/async-closures/higher-ranked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// edition:2021

#![feature(async_closure)]

fn main() {
let x = async move |x: &str| {
//~^ ERROR lifetime may not live long enough
// This error is proof that the `&str` type is higher-ranked.
// This won't work until async closures are fully impl'd.
println!("{x}");
};
}
17 changes: 17 additions & 0 deletions tests/ui/async-await/async-closures/higher-ranked.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error: lifetime may not live long enough
--> $DIR/higher-ranked.rs:6:34
|
LL | let x = async move |x: &str| {
| ____________________________-___-_^
| | | |
| | | return type of closure `{async closure body@$DIR/higher-ranked.rs:6:34: 11:6}` contains a lifetime `'2`
| | let's call the lifetime of this reference `'1`
LL | |
LL | | // This error is proof that the `&str` type is higher-ranked.
LL | | // This won't work until async closures are fully impl'd.
LL | | println!("{x}");
LL | | };
| |_____^ returning this value requires that `'1` must outlive `'2`

error: aborting due to 1 previous error

100 changes: 50 additions & 50 deletions tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
error: unreachable pattern
--> $DIR/empty-types.rs:47:9
--> $DIR/empty-types.rs:50:9
|
LL | _ => {}
| ^
|
note: the lint level is defined here
--> $DIR/empty-types.rs:13:9
--> $DIR/empty-types.rs:16:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:50:9
--> $DIR/empty-types.rs:53:9
|
LL | _x => {}
| ^^

error[E0004]: non-exhaustive patterns: type `&!` is non-empty
--> $DIR/empty-types.rs:54:11
--> $DIR/empty-types.rs:57:11
|
LL | match ref_never {}
| ^^^^^^^^^
@@ -32,31 +32,31 @@ LL + }
|

error: unreachable pattern
--> $DIR/empty-types.rs:69:9
--> $DIR/empty-types.rs:72:9
|
LL | (_, _) => {}
| ^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:76:9
--> $DIR/empty-types.rs:79:9
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:79:9
--> $DIR/empty-types.rs:82:9
|
LL | (_, _) => {}
| ^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:83:9
--> $DIR/empty-types.rs:86:9
|
LL | _ => {}
| ^

error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
--> $DIR/empty-types.rs:87:11
--> $DIR/empty-types.rs:90:11
|
LL | match res_u32_never {}
| ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
@@ -75,19 +75,19 @@ LL + }
|

error: unreachable pattern
--> $DIR/empty-types.rs:95:9
--> $DIR/empty-types.rs:98:9
|
LL | Err(_) => {}
| ^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:100:9
--> $DIR/empty-types.rs:103:9
|
LL | Err(_) => {}
| ^^^^^^

error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
--> $DIR/empty-types.rs:97:11
--> $DIR/empty-types.rs:100:11
|
LL | match res_u32_never {
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
@@ -105,7 +105,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!()
|

error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:104:9
--> $DIR/empty-types.rs:107:9
|
LL | let Ok(_x) = res_u32_never.as_ref();
| ^^^^^^ pattern `Err(_)` not covered
@@ -119,121 +119,121 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
| ++++++++++++++++

error: unreachable pattern
--> $DIR/empty-types.rs:115:9
--> $DIR/empty-types.rs:118:9
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:119:9
--> $DIR/empty-types.rs:122:9
|
LL | Ok(_) => {}
| ^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:122:9
--> $DIR/empty-types.rs:125:9
|
LL | Ok(_) => {}
| ^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:123:9
--> $DIR/empty-types.rs:126:9
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:126:9
--> $DIR/empty-types.rs:129:9
|
LL | Ok(_) => {}
| ^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:127:9
--> $DIR/empty-types.rs:130:9
|
LL | Err(_) => {}
| ^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:136:13
--> $DIR/empty-types.rs:139:13
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:139:13
--> $DIR/empty-types.rs:142:13
|
LL | _ if false => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:148:13
--> $DIR/empty-types.rs:151:13
|
LL | Some(_) => {}
| ^^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:152:13
--> $DIR/empty-types.rs:155:13
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:204:13
--> $DIR/empty-types.rs:207:13
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:209:13
--> $DIR/empty-types.rs:212:13
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:214:13
--> $DIR/empty-types.rs:217:13
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:219:13
--> $DIR/empty-types.rs:222:13
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:225:13
--> $DIR/empty-types.rs:228:13
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:284:9
--> $DIR/empty-types.rs:287:9
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:287:9
--> $DIR/empty-types.rs:290:9
|
LL | (_, _) => {}
| ^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:290:9
--> $DIR/empty-types.rs:293:9
|
LL | Ok(_) => {}
| ^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:291:9
--> $DIR/empty-types.rs:294:9
|
LL | Err(_) => {}
| ^^^^^^

error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
--> $DIR/empty-types.rs:323:11
--> $DIR/empty-types.rs:326:11
|
LL | match slice_never {}
| ^^^^^^^^^^^
@@ -247,7 +247,7 @@ LL + }
|

error[E0004]: non-exhaustive patterns: `&[]` not covered
--> $DIR/empty-types.rs:334:11
--> $DIR/empty-types.rs:337:11
|
LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[]` not covered
@@ -260,7 +260,7 @@ LL + &[] => todo!()
|

error[E0004]: non-exhaustive patterns: `&[]` not covered
--> $DIR/empty-types.rs:347:11
--> $DIR/empty-types.rs:350:11
|
LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[]` not covered
@@ -274,7 +274,7 @@ LL + &[] => todo!()
|

error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
--> $DIR/empty-types.rs:353:11
--> $DIR/empty-types.rs:356:11
|
LL | match *slice_never {}
| ^^^^^^^^^^^^
@@ -288,25 +288,25 @@ LL + }
|

error: unreachable pattern
--> $DIR/empty-types.rs:363:9
--> $DIR/empty-types.rs:366:9
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:366:9
--> $DIR/empty-types.rs:369:9
|
LL | [_, _, _] => {}
| ^^^^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:369:9
--> $DIR/empty-types.rs:372:9
|
LL | [_, ..] => {}
| ^^^^^^^

error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
--> $DIR/empty-types.rs:383:11
--> $DIR/empty-types.rs:386:11
|
LL | match array_0_never {}
| ^^^^^^^^^^^^^
@@ -320,13 +320,13 @@ LL + }
|

error: unreachable pattern
--> $DIR/empty-types.rs:390:9
--> $DIR/empty-types.rs:393:9
|
LL | _ => {}
| ^

error[E0004]: non-exhaustive patterns: `[]` not covered
--> $DIR/empty-types.rs:392:11
--> $DIR/empty-types.rs:395:11
|
LL | match array_0_never {
| ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -340,49 +340,49 @@ LL + [] => todo!()
|

error: unreachable pattern
--> $DIR/empty-types.rs:411:9
--> $DIR/empty-types.rs:414:9
|
LL | Some(_) => {}
| ^^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:416:9
--> $DIR/empty-types.rs:419:9
|
LL | Some(_a) => {}
| ^^^^^^^^

error: unreachable pattern
--> $DIR/empty-types.rs:421:9
--> $DIR/empty-types.rs:424:9
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:426:9
--> $DIR/empty-types.rs:429:9
|
LL | _a => {}
| ^^

error: unreachable pattern
--> $DIR/empty-types.rs:598:9
--> $DIR/empty-types.rs:601:9
|
LL | _ => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:601:9
--> $DIR/empty-types.rs:604:9
|
LL | _x => {}
| ^^

error: unreachable pattern
--> $DIR/empty-types.rs:604:9
--> $DIR/empty-types.rs:607:9
|
LL | _ if false => {}
| ^

error: unreachable pattern
--> $DIR/empty-types.rs:607:9
--> $DIR/empty-types.rs:610:9
|
LL | _x if false => {}
| ^^
630 changes: 630 additions & 0 deletions tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr

Large diffs are not rendered by default.

98 changes: 49 additions & 49 deletions tests/ui/pattern/usefulness/empty-types.normal.stderr

Large diffs are not rendered by default.

84 changes: 44 additions & 40 deletions tests/ui/pattern/usefulness/empty-types.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// revisions: normal exhaustive_patterns
// revisions: normal min_exh_pats exhaustive_patterns
// gate-test-min_exhaustive_patterns
//
// This tests correct handling of empty types in exhaustiveness checking.
//
@@ -9,6 +10,8 @@
// This feature is useful to avoid `!` falling back to `()` all the time.
#![feature(never_type_fallback)]
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
#![cfg_attr(min_exh_pats, feature(min_exhaustive_patterns))]
//[min_exh_pats]~^ WARN the feature `min_exhaustive_patterns` is incomplete
#![allow(dead_code, unreachable_code)]
#![deny(unreachable_patterns)]

@@ -66,17 +69,17 @@ fn basic(x: NeverBundle) {
match tuple_half_never {}
//[normal]~^ ERROR non-empty
match tuple_half_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
(_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}

let tuple_never: (!, !) = x.tuple_never;
match tuple_never {}
//[normal]~^ ERROR non-empty
match tuple_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match tuple_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
(_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match tuple_never.0 {}
match tuple_never.0 {
@@ -92,12 +95,12 @@ fn basic(x: NeverBundle) {
}
match res_u32_never {
Ok(_) => {}
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match res_u32_never {
//~^ ERROR non-exhaustive
Ok(0) => {}
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
let Ok(_x) = res_u32_never;
//[normal]~^ ERROR refutable
@@ -106,25 +109,25 @@ fn basic(x: NeverBundle) {
// Non-obvious difference: here there's an implicit dereference in the patterns, which makes the
// inner place !known_valid. `exhaustive_patterns` ignores this.
let Ok(_x) = &res_u32_never;
//[normal]~^ ERROR refutable
//[normal,min_exh_pats]~^ ERROR refutable

let result_never: Result<!, !> = x.result_never;
match result_never {}
//[normal]~^ ERROR non-exhaustive
match result_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match result_never {
//[normal]~^ ERROR non-exhaustive
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
}

@@ -145,11 +148,11 @@ fn void_same_as_never(x: NeverBundle) {
}
match opt_void {
None => {}
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match opt_void {
None => {}
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}

let ref_void: &Void = &x.void;
@@ -159,7 +162,7 @@ fn void_same_as_never(x: NeverBundle) {
}
let ref_opt_void: &Option<Void> = &None;
match *ref_opt_void {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
None => {}
}
match *ref_opt_void {
@@ -284,11 +287,11 @@ fn nested_validity_tracking(bundle: NeverBundle) {
_ => {} //~ ERROR unreachable pattern
}
match tuple_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
(_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}

// These should be considered !known_valid and not warn unreachable.
@@ -309,21 +312,21 @@ fn invalid_empty_match(bundle: NeverBundle) {
match *x {}

let x: &(u32, !) = &bundle.tuple_half_never;
match *x {} //[normal]~ ERROR non-exhaustive
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
let x: &(!, !) = &bundle.tuple_never;
match *x {} //[normal]~ ERROR non-exhaustive
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
let x: &Result<!, !> = &bundle.result_never;
match *x {} //[normal]~ ERROR non-exhaustive
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
let x: &[!; 3] = &bundle.array_3_never;
match *x {} //[normal]~ ERROR non-exhaustive
match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
}

fn arrays_and_slices(x: NeverBundle) {
let slice_never: &[!] = &[];
match slice_never {}
//~^ ERROR non-empty
match slice_never {
//[normal]~^ ERROR not covered
//[normal,min_exh_pats]~^ ERROR not covered
[] => {}
}
match slice_never {
@@ -332,7 +335,7 @@ fn arrays_and_slices(x: NeverBundle) {
[_, _, ..] => {}
}
match slice_never {
//[normal]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
//[normal,min_exh_pats]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
//[exhaustive_patterns]~^^ ERROR `&[]` not covered
[_, _, _, ..] => {}
}
@@ -345,7 +348,7 @@ fn arrays_and_slices(x: NeverBundle) {
_x => {}
}
match slice_never {
//[normal]~^ ERROR `&[]` and `&[_, ..]` not covered
//[normal,min_exh_pats]~^ ERROR `&[]` and `&[_, ..]` not covered
//[exhaustive_patterns]~^^ ERROR `&[]` not covered
&[..] if false => {}
}
@@ -360,13 +363,13 @@ fn arrays_and_slices(x: NeverBundle) {
match array_3_never {}
//[normal]~^ ERROR non-empty
match array_3_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match array_3_never {
[_, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
[_, _, _] => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match array_3_never {
[_, ..] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
[_, ..] => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}

let ref_array_3_never: &[!; 3] = &array_3_never;
@@ -408,22 +411,22 @@ fn bindings(x: NeverBundle) {
match opt_never {
None => {}
// !useful, !reachable
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
Some(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Some(_a) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_a => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
}

// The scrutinee is known_valid, but under the `&` isn't anymore.
@@ -444,7 +447,7 @@ fn bindings(x: NeverBundle) {
&_a => {}
}
match ref_opt_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
&None => {}
}
match ref_opt_never {
@@ -485,7 +488,7 @@ fn bindings(x: NeverBundle) {
ref _a => {}
}
match *ref_opt_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
None => {}
}
match *ref_opt_never {
@@ -533,7 +536,7 @@ fn bindings(x: NeverBundle) {

let ref_res_never: &Result<!, !> = &x.result_never;
match *ref_res_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
// useful, reachable
Ok(_) => {}
}
@@ -544,7 +547,7 @@ fn bindings(x: NeverBundle) {
_ => {}
}
match *ref_res_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
// useful, !reachable
Ok(_a) => {}
}
@@ -563,7 +566,7 @@ fn bindings(x: NeverBundle) {

let ref_tuple_half_never: &(u32, !) = &x.tuple_half_never;
match *ref_tuple_half_never {}
//[normal]~^ ERROR non-empty
//[normal,min_exh_pats]~^ ERROR non-empty
match *ref_tuple_half_never {
// useful, reachable
(_, _) => {}
@@ -614,6 +617,7 @@ fn guards_and_validity(x: NeverBundle) {
// useful, reachable
_ => {}
}

// Now the madness commences. The guard caused a load of the value thus asserting validity. So
// there's no invalid value for `_` to catch. So the second pattern is unreachable despite the
// guard not being taken.
@@ -629,7 +633,7 @@ fn guards_and_validity(x: NeverBundle) {
_a if false => {}
}
match ref_never {
//[normal]~^ ERROR non-exhaustive
//[normal,min_exh_pats]~^ ERROR non-exhaustive
// useful, !reachable
&_a if false => {}
}
@@ -657,7 +661,7 @@ fn diagnostics_subtlety(x: NeverBundle) {
// Regression test for diagnostics: don't report `Some(Ok(_))` and `Some(Err(_))`.
let x: &Option<Result<!, !>> = &None;
match *x {
//[normal]~^ ERROR `Some(_)` not covered
//[normal,min_exh_pats]~^ ERROR `Some(_)` not covered
None => {}
}
}