Auto merge of #130253 - workingjubilee:rollup-npqpnaf, r=workingjubilee

Rollup of 10 pull requests

Successful merges:

 - #129103 (Don't warn empty branches unreachable for now)
 - #129696 (update stdarch)
 - #129835 (enable const-float-classify test, and test_next_up/down on 32bit x86)
 - #130077 (Fix linking error when compiling for 32-bit watchOS)
 - #130114 (Remove needless returns detected by clippy in the compiler)
 - #130168 (maint: update docs for change_time ext and doc links)
 - #130228 (notify Miri when intrinsics are changed)
 - #130239 (miri: fix overflow detection for unsigned pointer offset)
 - #130244 (Use the same span for attributes and Try expansion of ?)
 - #130248 (Limit `libc::link` usage to `nto70` target only, not NTO OS)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-09-11 23:23:25 +00:00
commit 3afb2bb76c
83 changed files with 504 additions and 861 deletions

View File

@ -153,7 +153,7 @@ impl HasTokens for StmtKind {
StmtKind::Let(local) => local.tokens.as_ref(),
StmtKind::Item(item) => item.tokens(),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.tokens(),
StmtKind::Empty => return None,
StmtKind::Empty => None,
StmtKind::MacCall(mac) => mac.tokens.as_ref(),
}
}
@ -162,7 +162,7 @@ impl HasTokens for StmtKind {
StmtKind::Let(local) => Some(&mut local.tokens),
StmtKind::Item(item) => item.tokens_mut(),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.tokens_mut(),
StmtKind::Empty => return None,
StmtKind::Empty => None,
StmtKind::MacCall(mac) => Some(&mut mac.tokens),
}
}

View File

@ -1837,7 +1837,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Safety::Default,
sym::allow,
sym::unreachable_code,
self.lower_span(span),
try_span,
);
let attrs: AttrVec = thin_vec![attr];

View File

@ -1240,5 +1240,5 @@ pub fn parse_confusables(attr: &Attribute) -> Option<Vec<Symbol>> {
candidates.push(meta_lit.symbol);
}
return Some(candidates);
Some(candidates)
}

View File

@ -3669,7 +3669,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
reinits.push(location);
return true;
}
return false;
false
};
while let Some(location) = stack.pop() {

View File

@ -214,7 +214,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
let delegate = FnMutDelegate {
regions: &mut |br: ty::BoundRegion| {
if let Some(ex_reg_var) = reg_map.get(&br) {
return *ex_reg_var;
*ex_reg_var
} else {
let ex_reg_var = self.next_existential_region_var(true, br.kind.get_name());
debug!(?ex_reg_var);

View File

@ -290,7 +290,7 @@ pub(crate) fn check_tied_features(
}
}
}
return None;
None
}
/// Used to generate cfg variables and apply features

View File

@ -438,7 +438,7 @@ fn link_rlib<'a>(
ab.add_file(&lib)
}
return Ok(ab);
Ok(ab)
}
/// Extract all symbols defined in raw-dylib libraries, collated by library name.
@ -1319,7 +1319,7 @@ fn link_sanitizer_runtime(
fn find_sanitizer_runtime(sess: &Session, filename: &str) -> PathBuf {
let path = sess.target_tlib_path.dir.join(filename);
if path.exists() {
return sess.target_tlib_path.dir.clone();
sess.target_tlib_path.dir.clone()
} else {
let default_sysroot =
filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
@ -1327,7 +1327,7 @@ fn link_sanitizer_runtime(
&default_sysroot,
sess.opts.target_triple.triple(),
);
return default_tlib;
default_tlib
}
}

View File

@ -1484,7 +1484,6 @@ impl<'a> Linker for L4Bender<'a> {
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
// ToDo, not implemented, copy from GCC
self.sess.dcx().emit_warn(errors::L4BenderExportingSymbolsUnimplemented);
return;
}
fn subsystem(&mut self, subsystem: &str) {

View File

@ -171,10 +171,10 @@ pub(super) fn get_metadata_xcoff<'a>(path: &Path, data: &'a [u8]) -> Result<&'a
"Metadata at offset {offset} with size {len} is beyond .info section"
));
}
return Ok(&info_data[offset..(offset + len)]);
Ok(&info_data[offset..(offset + len)])
} else {
return Err(format!("Unable to find symbol {AIX_METADATA_SYMBOL_NAME}"));
};
Err(format!("Unable to find symbol {AIX_METADATA_SYMBOL_NAME}"))
}
}
pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static>> {
@ -413,7 +413,7 @@ fn macho_object_build_version_for_target(target: &Target) -> object::write::Mach
/// Is Apple's CPU subtype `arm64e`s
fn macho_is_arm64e(target: &Target) -> bool {
return target.llvm_target.starts_with("arm64e");
target.llvm_target.starts_with("arm64e")
}
pub enum MetadataPosition {

View File

@ -235,13 +235,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
if self.layout_compat(caller_abi.layout, callee_abi.layout)? {
// Ensure that our checks imply actual ABI compatibility for this concrete call.
assert!(caller_abi.eq_abi(callee_abi));
return Ok(true);
Ok(true)
} else {
trace!(
"check_argument_compat: incompatible ABIs:\ncaller: {:?}\ncallee: {:?}",
caller_abi, callee_abi
);
return Ok(false);
Ok(false)
}
}

View File

@ -303,8 +303,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let pointee_layout = self.layout_of(pointee_ty)?;
assert!(pointee_layout.abi.is_sized());
// We cannot overflow i64 as a type's size must be <= isize::MAX.
// The size always fits in `i64` as it can be at most `isize::MAX`.
let pointee_size = i64::try_from(pointee_layout.size.bytes()).unwrap();
// This uses the same type as `right`, which can be `isize` or `usize`.
// `pointee_size` is guaranteed to fit into both types.
let pointee_size = ImmTy::from_int(pointee_size, right.layout);
// Multiply element size and element count.
let (val, overflowed) = self
@ -316,6 +318,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
let offset_bytes = val.to_target_isize(self)?;
if !right.layout.abi.is_signed() && offset_bytes < 0 {
// We were supposed to do an unsigned offset but the result is negative -- this
// can only mean that the cast wrapped around.
throw_ub!(PointerArithOverflow)
}
let offset_ptr = self.ptr_offset_inbounds(ptr, offset_bytes)?;
Ok(ImmTy::from_scalar(Scalar::from_maybe_pointer(offset_ptr, self), left.layout))
}

View File

@ -773,18 +773,20 @@ fn extract_symbol_from_pnr<'a>(
match pnr {
ParseNtResult::Ident(nt_ident, is_raw) => {
if let IdentIsRaw::Yes = is_raw {
return Err(dcx.struct_span_err(span_err, RAW_IDENT_ERR));
Err(dcx.struct_span_err(span_err, RAW_IDENT_ERR))
} else {
Ok(nt_ident.name)
}
return Ok(nt_ident.name);
}
ParseNtResult::Tt(TokenTree::Token(
Token { kind: TokenKind::Ident(symbol, is_raw), .. },
_,
)) => {
if let IdentIsRaw::Yes = is_raw {
return Err(dcx.struct_span_err(span_err, RAW_IDENT_ERR));
Err(dcx.struct_span_err(span_err, RAW_IDENT_ERR))
} else {
Ok(*symbol)
}
return Ok(*symbol);
}
ParseNtResult::Tt(TokenTree::Token(
Token {
@ -792,15 +794,13 @@ fn extract_symbol_from_pnr<'a>(
..
},
_,
)) => {
return Ok(*symbol);
}
)) => Ok(*symbol),
ParseNtResult::Nt(nt)
if let Nonterminal::NtLiteral(expr) = &**nt
&& let ExprKind::Lit(Lit { kind: LitKind::Str, symbol, suffix: None }) =
&expr.kind =>
{
return Ok(*symbol);
Ok(*symbol)
}
_ => Err(dcx
.struct_err(

View File

@ -1038,7 +1038,7 @@ fn report_trait_method_mismatch<'tcx>(
false,
);
return diag.emit();
diag.emit()
}
fn check_region_bounds_on_impl_item<'tcx>(

View File

@ -274,7 +274,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
return false;
}
return true;
true
})
.collect::<Vec<_>>();

View File

@ -605,7 +605,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Abi::Rust,
));
return Some(ExpectedSig { cause_span, sig });
Some(ExpectedSig { cause_span, sig })
}
fn sig_of_closure(

View File

@ -1042,7 +1042,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return true;
}
}
return false;
false
}
fn explain_self_literal(

View File

@ -307,7 +307,7 @@ impl<'tcx> ArgMatrix<'tcx> {
permutation.into_iter().map(|x| x.unwrap()).collect();
return Some(Issue::Permutation(final_permutation));
}
return None;
None
}
// Obviously, detecting exact user intention is impossible, so the goal here is to
@ -410,6 +410,6 @@ impl<'tcx> ArgMatrix<'tcx> {
// sort errors with same type by the order they appear in the source
// so that suggestion will be handled properly, see #112507
errors.sort();
return (errors, matched_inputs);
(errors, matched_inputs)
}
}

View File

@ -2051,7 +2051,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let span = expr.span.find_oldest_ancestor_in_same_ctxt();
err.span_suggestion_verbose(span.shrink_to_hi(), msg, sugg, Applicability::HasPlaceholders);
return true;
true
}
pub(crate) fn suggest_coercing_result_via_try_operator(

View File

@ -1481,7 +1481,7 @@ impl<'tcx> InferCtxt<'tcx> {
// This hoists the borrow/release out of the loop body.
let inner = self.inner.try_borrow();
return move |infer_var: TyOrConstInferVar| match (infer_var, &inner) {
move |infer_var: TyOrConstInferVar| match (infer_var, &inner) {
(TyOrConstInferVar::Ty(ty_var), Ok(inner)) => {
use self::type_variable::TypeVariableValue;
@ -1491,7 +1491,7 @@ impl<'tcx> InferCtxt<'tcx> {
)
}
_ => false,
};
}
}
/// `ty_or_const_infer_var_changed` is equivalent to one of these two:

View File

@ -133,7 +133,7 @@ fn extract_iterator_next_call<'tcx>(
{
Some(recv)
} else {
return None;
None
}
}

View File

@ -71,7 +71,7 @@ impl<'hir> Iterator for ParentHirIterator<'hir> {
debug_assert_ne!(parent_id, self.current_id);
self.current_id = parent_id;
return Some(parent_id);
Some(parent_id)
}
}
@ -103,7 +103,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
self.current_id = HirId::make_owner(parent_id.def_id);
let node = self.map.tcx.hir_owner_node(self.current_id.owner);
return Some((self.current_id.owner, node));
Some((self.current_id.owner, node))
}
}
@ -1233,14 +1233,14 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
body_owners,
..
} = collector;
return ModuleItems {
ModuleItems {
submodules: submodules.into_boxed_slice(),
free_items: items.into_boxed_slice(),
trait_items: trait_items.into_boxed_slice(),
impl_items: impl_items.into_boxed_slice(),
foreign_items: foreign_items.into_boxed_slice(),
body_owners: body_owners.into_boxed_slice(),
};
}
}
pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
@ -1262,14 +1262,14 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
..
} = collector;
return ModuleItems {
ModuleItems {
submodules: submodules.into_boxed_slice(),
free_items: items.into_boxed_slice(),
trait_items: trait_items.into_boxed_slice(),
impl_items: impl_items.into_boxed_slice(),
foreign_items: foreign_items.into_boxed_slice(),
body_owners: body_owners.into_boxed_slice(),
};
}
}
struct ItemCollector<'tcx> {

View File

@ -641,7 +641,7 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
pub fn write_uninit(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult {
self.mark_init(range, false);
self.provenance.clear(range, cx)?;
return Ok(());
Ok(())
}
/// Remove all provenance in the given memory range.

View File

@ -1166,10 +1166,9 @@ impl<'tcx> LocalDecl<'tcx> {
/// Returns `true` if this is a DerefTemp
pub fn is_deref_temp(&self) -> bool {
match self.local_info() {
LocalInfo::DerefTemp => return true,
_ => (),
LocalInfo::DerefTemp => true,
_ => false,
}
return false;
}
/// Returns `true` is the local is from a compiler desugaring, e.g.,

View File

@ -2007,7 +2007,7 @@ impl<'tcx> TyCtxt<'tcx> {
));
}
}
return None;
None
}
/// Checks if the bound region is in Impl Item.

View File

@ -431,7 +431,7 @@ impl BoundRegionKind {
pub fn get_id(&self) -> Option<DefId> {
match *self {
BoundRegionKind::BrNamed(id, _) => return Some(id),
BoundRegionKind::BrNamed(id, _) => Some(id),
_ => None,
}
}

View File

@ -82,13 +82,11 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
fn statement_as_expr(&self, stmt_id: StmtId) -> PResult<ExprId> {
match &self.thir[stmt_id].kind {
StmtKind::Expr { expr, .. } => Ok(*expr),
kind @ StmtKind::Let { pattern, .. } => {
return Err(ParseError {
span: pattern.span,
item_description: format!("{kind:?}"),
expected: "expression".to_string(),
});
}
kind @ StmtKind::Let { pattern, .. } => Err(ParseError {
span: pattern.span,
item_description: format!("{kind:?}"),
expected: "expression".to_string(),
}),
}
}

View File

@ -1193,7 +1193,7 @@ fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) ->
return Some(new.def_id);
}
}
return None;
None
}
/// Scans the MIR in order to find function calls, closures, and drop-glue.

View File

@ -299,7 +299,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
}
return diff_errs;
}
return errs;
errs
}
fn close_delim_err(&mut self, delim: Delimiter) -> PErr<'psess> {

View File

@ -2553,7 +2553,7 @@ impl<'a> Parser<'a> {
err.delay_as_bug();
}
}
return Ok(false); // Don't continue.
Ok(false) // Don't continue.
}
/// Attempt to parse a generic const argument that has not been enclosed in braces.

View File

@ -457,7 +457,7 @@ impl<'a> Parser<'a> {
fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> {
// To be expanded
return Ok(None);
Ok(None)
}
/// Parses an item macro, e.g., `item!();`.

View File

@ -1905,10 +1905,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|| (int_reprs == 1
&& is_c
&& item.is_some_and(|item| {
if let ItemLike::Item(item) = item {
return is_c_like_enum(item);
}
return false;
if let ItemLike::Item(item) = item { is_c_like_enum(item) } else { false }
}))
{
self.tcx.emit_node_span_lint(

View File

@ -394,7 +394,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
}
}
return false;
false
}
fn visit_node(&mut self, node: Node<'tcx>) {

View File

@ -951,7 +951,11 @@ impl<Cx: PatCx> PlaceInfo<Cx> {
self.is_scrutinee && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
// 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 = self.validity.is_known_valid();
// We don't want to warn empty patterns as unreachable by default just yet. We will in a
// later version of rust or under a different lint name, see
// https://github.com/rust-lang/rust/pull/129103.
let empty_arms_are_unreachable = self.validity.is_known_valid()
&& (is_toplevel_exception || cx.is_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 = self.validity.is_known_valid()

View File

@ -3076,7 +3076,7 @@ fn search_for_any_use_in_items(items: &[P<ast::Item>]) -> Option<Span> {
}
}
}
return None;
None
}
fn is_span_suitable_for_use_injection(s: Span) -> bool {

View File

@ -5016,5 +5016,5 @@ fn def_id_matches_path(tcx: TyCtxt<'_>, mut def_id: DefId, expected_path: &[&str
}
def_id = parent;
}
return true;
true
}

View File

@ -779,7 +779,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
candidates = self.smart_resolve_partial_mod_path_errors(path, following_seg);
}
return (false, candidates);
(false, candidates)
}
fn suggest_trait_and_bounds(

View File

@ -182,7 +182,7 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
}
}
return sysroot_candidates;
sysroot_candidates
}
/// Returns the provided sysroot or calls [`get_or_default_sysroot`] if it's none.

View File

@ -353,7 +353,7 @@ fn build_options<O: Default>(
None => early_dcx.early_fatal(format!("unknown {outputname} option: `{key}`")),
}
}
return op;
op
}
#[allow(non_upper_case_globals)]

View File

@ -779,7 +779,7 @@ impl SourceMap {
return Ok(false);
}
}
return Ok(true);
Ok(true)
})
.is_ok_and(|is_accessible| is_accessible)
}

View File

@ -188,7 +188,7 @@ impl ArgAttributes {
if self.arg_ext != other.arg_ext {
return false;
}
return true;
true
}
}
@ -632,7 +632,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
PassMode::Indirect { .. } => {
self.mode = PassMode::Direct(ArgAttributes::new());
}
PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => return, // already direct
PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => {} // already direct
_ => panic!("Tried to make {:?} direct", self.mode),
}
}
@ -646,7 +646,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
}
PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => {
// already indirect
return;
}
_ => panic!("Tried to make {:?} indirect", self.mode),
}
@ -661,7 +660,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
}
PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => {
// already indirect
return;
}
_ => panic!("Tried to make {:?} indirect (expected `PassMode::Ignore`)", self.mode),
}

View File

@ -66,7 +66,7 @@ where
data.last_offset = offset + Reg::f64().size;
}
data.prefix_index += 1;
return data;
data
}
fn arg_scalar_pair<C>(
@ -92,7 +92,7 @@ where
offset += Size::from_bytes(4 - (offset.bytes() % 4));
}
data = arg_scalar(cx, scalar2, offset, data);
return data;
data
}
fn parse_structure<'a, Ty, C>(
@ -128,7 +128,7 @@ where
}
}
return data;
data
}
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, in_registers_max: Size)

View File

@ -435,6 +435,7 @@ impl f16 {
// WASM, see llvm/llvm-project#96437). These are platforms bugs, and Rust will misbehave on
// such platforms, but we can at least try to make things seem as sane as possible by being
// careful here.
// see also https://github.com/rust-lang/rust/issues/114479
if self.is_infinite() {
// Thus, a value may compare unequal to infinity, despite having a "full" exponent mask.
FpCategory::Infinite

View File

@ -662,10 +662,7 @@ impl f32 {
// hardware flushes subnormals to zero. These are platforms bugs, and Rust will misbehave on
// such hardware, but we can at least try to make things seem as sane as possible by being
// careful here.
//
// FIXME(jubilee): Using x87 operations is never necessary in order to function
// on x86 processors for Rust-to-Rust calls, so this issue should not happen.
// Code generation should be adjusted to use non-C calling conventions, avoiding this.
// see also https://github.com/rust-lang/rust/issues/114479
if self.is_infinite() {
// A value may compare unequal to infinity, despite having a "full" exponent mask.
FpCategory::Infinite

View File

@ -660,10 +660,7 @@ impl f64 {
// float semantics Rust relies on: x87 uses a too-large exponent, and some hardware flushes
// subnormals to zero. These are platforms bugs, and Rust will misbehave on such hardware,
// but we can at least try to make things seem as sane as possible by being careful here.
//
// FIXME(jubilee): Using x87 operations is never necessary in order to function
// on x86 processors for Rust-to-Rust calls, so this issue should not happen.
// Code generation should be adjusted to use non-C calling conventions, avoiding this.
// see also https://github.com/rust-lang/rust/issues/114479
//
// Thus, a value may compare unequal to infinity, despite having a "full" exponent mask.
// And it may not be NaN, as it can simply be an "overextended" finite value.

View File

@ -2,31 +2,24 @@ use crate::f32::consts;
use crate::num::{FpCategory as Fp, *};
/// Smallest number
#[allow(dead_code)] // unused on x86
const TINY_BITS: u32 = 0x1;
/// Next smallest number
#[allow(dead_code)] // unused on x86
const TINY_UP_BITS: u32 = 0x2;
/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
#[allow(dead_code)] // unused on x86
const MAX_DOWN_BITS: u32 = 0x7f7f_fffe;
/// Zeroed exponent, full significant
#[allow(dead_code)] // unused on x86
const LARGEST_SUBNORMAL_BITS: u32 = 0x007f_ffff;
/// Exponent = 0b1, zeroed significand
#[allow(dead_code)] // unused on x86
const SMALLEST_NORMAL_BITS: u32 = 0x0080_0000;
/// First pattern over the mantissa
#[allow(dead_code)] // unused on x86
const NAN_MASK1: u32 = 0x002a_aaaa;
/// Second pattern over the mantissa
#[allow(dead_code)] // unused on x86
const NAN_MASK2: u32 = 0x0055_5555;
#[allow(unused_macros)]
@ -353,9 +346,6 @@ fn test_is_sign_negative() {
assert!((-f32::NAN).is_sign_negative());
}
// Ignore test on x87 floating point, these platforms do not guarantee NaN
// payloads are preserved and flush denormals to zero, failing the tests.
#[cfg(not(target_arch = "x86"))]
#[test]
fn test_next_up() {
let tiny = f32::from_bits(TINY_BITS);
@ -386,9 +376,6 @@ fn test_next_up() {
assert_f32_biteq!(nan2.next_up(), nan2);
}
// Ignore test on x87 floating point, these platforms do not guarantee NaN
// payloads are preserved and flush denormals to zero, failing the tests.
#[cfg(not(target_arch = "x86"))]
#[test]
fn test_next_down() {
let tiny = f32::from_bits(TINY_BITS);

View File

@ -2,31 +2,24 @@ use crate::f64::consts;
use crate::num::{FpCategory as Fp, *};
/// Smallest number
#[allow(dead_code)] // unused on x86
const TINY_BITS: u64 = 0x1;
/// Next smallest number
#[allow(dead_code)] // unused on x86
const TINY_UP_BITS: u64 = 0x2;
/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
#[allow(dead_code)] // unused on x86
const MAX_DOWN_BITS: u64 = 0x7fef_ffff_ffff_fffe;
/// Zeroed exponent, full significant
#[allow(dead_code)] // unused on x86
const LARGEST_SUBNORMAL_BITS: u64 = 0x000f_ffff_ffff_ffff;
/// Exponent = 0b1, zeroed significand
#[allow(dead_code)] // unused on x86
const SMALLEST_NORMAL_BITS: u64 = 0x0010_0000_0000_0000;
/// First pattern over the mantissa
#[allow(dead_code)] // unused on x86
const NAN_MASK1: u64 = 0x000a_aaaa_aaaa_aaaa;
/// Second pattern over the mantissa
#[allow(dead_code)] // unused on x86
const NAN_MASK2: u64 = 0x0005_5555_5555_5555;
#[allow(unused_macros)]
@ -343,9 +336,6 @@ fn test_is_sign_negative() {
assert!((-f64::NAN).is_sign_negative());
}
// Ignore test on x87 floating point, these platforms do not guarantee NaN
// payloads are preserved and flush denormals to zero, failing the tests.
#[cfg(not(target_arch = "x86"))]
#[test]
fn test_next_up() {
let tiny = f64::from_bits(TINY_BITS);
@ -375,9 +365,6 @@ fn test_next_up() {
assert_f64_biteq!(nan2.next_up(), nan2);
}
// Ignore test on x87 floating point, these platforms do not guarantee NaN
// payloads are preserved and flush denormals to zero, failing the tests.
#[cfg(not(target_arch = "x86"))]
#[test]
fn test_next_down() {
let tiny = f64::from_bits(TINY_BITS);

View File

@ -298,7 +298,7 @@ impl OpenOptionsExt for OpenOptions {
/// of the [`BY_HANDLE_FILE_INFORMATION`] structure.
///
/// [`BY_HANDLE_FILE_INFORMATION`]:
/// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information
/// https://docs.microsoft.com/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information
#[stable(feature = "metadata_ext", since = "1.1.0")]
pub trait MetadataExt {
/// Returns the value of the `dwFileAttributes` field of this metadata.
@ -322,7 +322,7 @@ pub trait MetadataExt {
/// ```
///
/// [File Attribute Constants]:
/// https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
/// https://docs.microsoft.com/windows/win32/fileio/file-attribute-constants
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn file_attributes(&self) -> u32;
@ -351,7 +351,7 @@ pub trait MetadataExt {
/// }
/// ```
///
/// [`FILETIME`]: https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
/// [`FILETIME`]: https://docs.microsoft.com/windows/win32/api/minwinbase/ns-minwinbase-filetime
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn creation_time(&self) -> u64;
@ -386,7 +386,7 @@ pub trait MetadataExt {
/// }
/// ```
///
/// [`FILETIME`]: https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
/// [`FILETIME`]: https://docs.microsoft.com/windows/win32/api/minwinbase/ns-minwinbase-filetime
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn last_access_time(&self) -> u64;
@ -419,11 +419,11 @@ pub trait MetadataExt {
/// }
/// ```
///
/// [`FILETIME`]: https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
/// [`FILETIME`]: https://docs.microsoft.com/windows/win32/api/minwinbase/ns-minwinbase-filetime
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn last_write_time(&self) -> u64;
/// Returns the value of the `nFileSize{High,Low}` fields of this
/// Returns the value of the `nFileSize` fields of this
/// metadata.
///
/// The returned value does not have meaning for directories.
@ -462,7 +462,7 @@ pub trait MetadataExt {
#[unstable(feature = "windows_by_handle", issue = "63010")]
fn number_of_links(&self) -> Option<u32>;
/// Returns the value of the `nFileIndex{Low,High}` fields of this
/// Returns the value of the `nFileIndex` fields of this
/// metadata.
///
/// This will return `None` if the `Metadata` instance was created from a
@ -471,10 +471,14 @@ pub trait MetadataExt {
#[unstable(feature = "windows_by_handle", issue = "63010")]
fn file_index(&self) -> Option<u64>;
/// Returns the change time, which is the last time file metadata was changed, such as
/// renames, attributes, etc
/// Returns the value of the `ChangeTime` fields of this metadata.
///
/// This will return `None` if the `Metadata` instance was not created using the `FILE_BASIC_INFO` type.
/// `ChangeTime` is the last time file metadata was changed, such as
/// renames, attributes, etc.
///
/// This will return `None` if `Metadata` instance was created from a call to
/// `DirEntry::metadata` or if the `target_vendor` is outside the current platform
/// support for this api.
#[unstable(feature = "windows_change_time", issue = "121478")]
fn change_time(&self) -> Option<u64>;
}

View File

@ -1731,7 +1731,7 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
run_path_with_cstr(original, &|original| {
run_path_with_cstr(link, &|link| {
cfg_if::cfg_if! {
if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nto"))] {
if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70"))] {
// VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
// it implementation-defined whether `link` follows symlinks, so rely on the
// `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.

View File

@ -54,10 +54,10 @@ pub enum EHAction {
Terminate,
}
/// 32-bit Apple ARM uses SjLj exceptions, except for watchOS.
/// 32-bit ARM Darwin platforms uses SjLj exceptions.
///
/// I.e. iOS and tvOS, as those are the only Apple OSes that used 32-bit ARM
/// devices.
/// The exception is watchOS armv7k (specifically that subarchitecture), which
/// instead uses DWARF Call Frame Information (CFI) unwinding.
///
/// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.4/clang/lib/Driver/ToolChains/Darwin.cpp#L3107-L3119>
pub const USING_SJLJ_EXCEPTIONS: bool =

View File

@ -95,14 +95,15 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
cfg_if::cfg_if! {
if #[cfg(all(
target_arch = "arm",
not(all(target_vendor = "apple", not(target_os = "watchos"))),
not(target_os = "netbsd"),
))] {
target_arch = "arm",
not(target_vendor = "apple"),
not(target_os = "netbsd"),
))] {
/// personality fn called by [ARM EHABI][armeabi-eh]
///
/// Apple 32-bit ARM (but not watchOS) uses the default routine instead
/// since it uses "setjmp-longjmp" unwinding.
/// 32-bit ARM on iOS/tvOS/watchOS does not use ARM EHABI, it uses
/// either "setjmp-longjmp" unwinding or DWARF CFI unwinding, which is
/// handled by the default routine.
///
/// [armeabi-eh]: https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
#[lang = "eh_personality"]

@ -1 +1 @@
Subproject commit d9466edb4c53cece8686ee6e17b028436ddf4151
Subproject commit ace72223a0e321c1b0a37b5862aa756fe8ab5111

View File

@ -33,10 +33,10 @@ pub const unwinder_private_data_size: usize = 2;
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
pub const unwinder_private_data_size: usize = 6;
#[cfg(all(target_arch = "arm", not(all(target_vendor = "apple", not(target_os = "watchos")))))]
#[cfg(all(target_arch = "arm", not(target_vendor = "apple")))]
pub const unwinder_private_data_size: usize = 20;
#[cfg(all(target_arch = "arm", all(target_vendor = "apple", not(target_os = "watchos"))))]
#[cfg(all(target_arch = "arm", target_vendor = "apple"))]
pub const unwinder_private_data_size: usize = 5;
#[cfg(all(target_arch = "aarch64", target_pointer_width = "64", not(target_os = "windows")))]
@ -123,8 +123,11 @@ extern "C" {
}
cfg_if::cfg_if! {
if #[cfg(any(all(target_vendor = "apple", not(target_os = "watchos")), target_os = "netbsd", not(target_arch = "arm")))] {
if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "arm")))] {
// Not ARM EHABI
//
// 32-bit ARM on iOS/tvOS/watchOS use either DWARF/Compact unwinding or
// "setjmp-longjmp" / SjLj unwinding.
#[repr(C)]
#[derive(Copy, Clone, PartialEq)]
pub enum _Unwind_Action {
@ -259,8 +262,8 @@ if #[cfg(any(all(target_vendor = "apple", not(target_os = "watchos")), target_os
cfg_if::cfg_if! {
if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm"))] {
// 32-bit ARM Apple (except for watchOS) uses SjLj and does not provide
// _Unwind_Backtrace()
// 32-bit ARM Apple (except for watchOS armv7k specifically) uses SjLj and
// does not provide _Unwind_Backtrace()
extern "C-unwind" {
pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
}

View File

@ -666,22 +666,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let (right, right_len) = this.operand_to_simd(right)?;
let (dest, dest_len) = this.mplace_to_simd(dest)?;
// `index` is an array, not a SIMD type
let ty::Array(_, index_len) = index.layout.ty.kind() else {
span_bug!(
this.cur_span(),
"simd_shuffle index argument has non-array type {}",
index.layout.ty
)
// `index` is an array or a SIMD type
let (index, index_len) = match index.layout.ty.kind() {
// FIXME: remove this once `index` must always be a SIMD vector.
ty::Array(..) => (index.assert_mem_place(), index.len(this)?),
_ => this.operand_to_simd(index)?,
};
let index_len = index_len.eval_target_usize(*this.tcx, this.param_env());
assert_eq!(left_len, right_len);
assert_eq!(index_len, dest_len);
for i in 0..dest_len {
let src_index: u64 = this
.read_immediate(&this.project_index(index, i)?)?
.read_immediate(&this.project_index(&index, i)?)?
.to_scalar()
.to_u32()?
.into();

View File

@ -0,0 +1,7 @@
fn main() {
let x = &[0i32; 2];
let x = x.as_ptr().wrapping_add(1);
// If the `!0` is interpreted as `isize`, it is just `-1` and hence harmless.
// However, this is unsigned arithmetic, so really this is `usize::MAX` and hence UB.
unsafe { x.byte_add(!0).read() }; //~ERROR: does not fit in an `isize`
}

View File

@ -0,0 +1,15 @@
error: Undefined Behavior: overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`
--> $DIR/ptr_offset_unsigned_overflow.rs:LL:CC
|
LL | unsafe { x.byte_add(!0).read() };
| ^^^^^^^^^^^^^^ overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `main` at $DIR/ptr_offset_unsigned_overflow.rs:LL:CC
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error

View File

@ -620,6 +620,10 @@ fn simd_intrinsics() {
);
assert_eq!(simd_shuffle_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,);
assert_eq!(simd_shuffle::<_, _, i32x4>(a, b, const { [3u32, 1, 0, 2] }), a,);
assert_eq!(
simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([3u32, 1, 0, 2]) }),
a,
);
assert_eq!(
simd_shuffle_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b),
i32x4::from_array([4, 2, 1, 10]),
@ -628,6 +632,10 @@ fn simd_intrinsics() {
simd_shuffle::<_, _, i32x4>(a, b, const { [7u32, 5, 4, 6] }),
i32x4::from_array([4, 2, 1, 10]),
);
assert_eq!(
simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([7u32, 5, 4, 6]) }),
i32x4::from_array([4, 2, 1, 10]),
);
}
}

View File

@ -1,161 +0,0 @@
//@ compile-flags: -Zmir-opt-level=0
//@ run-pass
#![feature(const_float_classify)]
#![feature(f16, f16_const)]
#![feature(f128, f128_const)]
#![allow(unused_macro_rules)]
// Don't promote
const fn nop<T>(x: T) -> T { x }
macro_rules! const_assert {
($a:expr) => {
{
const _: () = assert!($a);
assert!(nop($a));
}
};
($a:expr, $b:expr) => {
{
const _: () = assert!($a == $b);
assert_eq!(nop($a), nop($b));
}
};
}
fn has_broken_floats() -> bool {
// i586 targets are broken due to <https://github.com/rust-lang/rust/issues/114479>.
std::env::var("TARGET").is_ok_and(|v| v.contains("i586"))
}
#[cfg(target_arch = "x86_64")]
fn f16(){
const_assert!((1f16).to_bits(), 0x3c00);
const_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00);
const_assert!((12.5f16).to_bits(), 0x4a40);
const_assert!(u16::from_le_bytes(12.5f16.to_le_bytes()), 0x4a40);
const_assert!((1337f16).to_bits(), 0x6539);
const_assert!(u16::from_ne_bytes(1337f16.to_ne_bytes()), 0x6539);
const_assert!((-14.25f16).to_bits(), 0xcb20);
const_assert!(f16::from_bits(0x3c00), 1.0);
const_assert!(f16::from_be_bytes(0x3c00u16.to_be_bytes()), 1.0);
const_assert!(f16::from_bits(0x4a40), 12.5);
const_assert!(f16::from_le_bytes(0x4a40u16.to_le_bytes()), 12.5);
const_assert!(f16::from_bits(0x5be0), 252.0);
const_assert!(f16::from_ne_bytes(0x5be0u16.to_ne_bytes()), 252.0);
const_assert!(f16::from_bits(0xcb20), -14.25);
// Check that NaNs roundtrip their bits regardless of signalingness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
const QUIET_NAN: u16 = f16::NAN.to_bits() ^ 0x0155;
const SIGNALING_NAN: u16 = f16::NAN.to_bits() ^ 0x02AA;
const_assert!(f16::from_bits(QUIET_NAN).is_nan());
const_assert!(f16::from_bits(SIGNALING_NAN).is_nan());
const_assert!(f16::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
if !has_broken_floats() {
const_assert!(f16::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
}
}
fn f32() {
const_assert!((1f32).to_bits(), 0x3f800000);
const_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000);
const_assert!((12.5f32).to_bits(), 0x41480000);
const_assert!(u32::from_le_bytes(12.5f32.to_le_bytes()), 0x41480000);
const_assert!((1337f32).to_bits(), 0x44a72000);
const_assert!(u32::from_ne_bytes(1337f32.to_ne_bytes()), 0x44a72000);
const_assert!((-14.25f32).to_bits(), 0xc1640000);
const_assert!(f32::from_bits(0x3f800000), 1.0);
const_assert!(f32::from_be_bytes(0x3f800000u32.to_be_bytes()), 1.0);
const_assert!(f32::from_bits(0x41480000), 12.5);
const_assert!(f32::from_le_bytes(0x41480000u32.to_le_bytes()), 12.5);
const_assert!(f32::from_bits(0x44a72000), 1337.0);
const_assert!(f32::from_ne_bytes(0x44a72000u32.to_ne_bytes()), 1337.0);
const_assert!(f32::from_bits(0xc1640000), -14.25);
// Check that NaNs roundtrip their bits regardless of signalingness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
const QUIET_NAN: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA;
const SIGNALING_NAN: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
const_assert!(f32::from_bits(QUIET_NAN).is_nan());
const_assert!(f32::from_bits(SIGNALING_NAN).is_nan());
const_assert!(f32::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
if !has_broken_floats() {
const_assert!(f32::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
}
}
fn f64() {
const_assert!((1f64).to_bits(), 0x3ff0000000000000);
const_assert!(u64::from_be_bytes(1f64.to_be_bytes()), 0x3ff0000000000000);
const_assert!((12.5f64).to_bits(), 0x4029000000000000);
const_assert!(u64::from_le_bytes(12.5f64.to_le_bytes()), 0x4029000000000000);
const_assert!((1337f64).to_bits(), 0x4094e40000000000);
const_assert!(u64::from_ne_bytes(1337f64.to_ne_bytes()), 0x4094e40000000000);
const_assert!((-14.25f64).to_bits(), 0xc02c800000000000);
const_assert!(f64::from_bits(0x3ff0000000000000), 1.0);
const_assert!(f64::from_be_bytes(0x3ff0000000000000u64.to_be_bytes()), 1.0);
const_assert!(f64::from_bits(0x4029000000000000), 12.5);
const_assert!(f64::from_le_bytes(0x4029000000000000u64.to_le_bytes()), 12.5);
const_assert!(f64::from_bits(0x4094e40000000000), 1337.0);
const_assert!(f64::from_ne_bytes(0x4094e40000000000u64.to_ne_bytes()), 1337.0);
const_assert!(f64::from_bits(0xc02c800000000000), -14.25);
// Check that NaNs roundtrip their bits regardless of signalingness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
const QUIET_NAN: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
const SIGNALING_NAN: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
const_assert!(f64::from_bits(QUIET_NAN).is_nan());
const_assert!(f64::from_bits(SIGNALING_NAN).is_nan());
const_assert!(f64::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
if !has_broken_floats() {
const_assert!(f64::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
}
}
#[cfg(target_arch = "x86_64")]
fn f128() {
const_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
const_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000);
const_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
const_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000);
const_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000);
const_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000);
const_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000);
const_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0);
const_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0);
const_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5);
const_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5);
const_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0);
assert_eq!(f128::from_ne_bytes(0x40094e40000000000000000000000000u128.to_ne_bytes()), 1337.0);
const_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25);
// Check that NaNs roundtrip their bits regardless of signalingness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
const QUIET_NAN: u128 = f128::NAN.to_bits() | 0x0000_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA;
const SIGNALING_NAN: u128 = f128::NAN.to_bits() ^ 0x0000_5555_5555_5555_5555_5555_5555_5555;
const_assert!(f128::from_bits(QUIET_NAN).is_nan());
const_assert!(f128::from_bits(SIGNALING_NAN).is_nan());
const_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
if !has_broken_floats() {
const_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
}
}
fn main() {
#[cfg(target_arch = "x86_64")]
{
f16();
f128();
}
f32();
f64();
}

View File

@ -1,76 +0,0 @@
//@ compile-flags: -Zmir-opt-level=0 -Znext-solver
//@ known-bug: #110395
// FIXME(effects) run-pass
#![feature(const_float_classify)]
#![feature(const_trait_impl, effects)]
#![allow(incomplete_features)]
// Don't promote
const fn nop<T>(x: T) -> T { x }
impl const PartialEq<NonDet> for bool {
fn eq(&self, _: &NonDet) -> bool {
true
}
}
macro_rules! const_assert {
($a:expr, $b:expr) => {
{
const _: () = assert!($a == $b);
assert!(nop($a) == nop($b));
}
};
}
macro_rules! suite {
( $( $tt:tt )* ) => {
fn f32() {
suite_inner!(f32 $($tt)*);
}
fn f64() {
suite_inner!(f64 $($tt)*);
}
}
}
macro_rules! suite_inner {
(
$ty:ident [$( $fn:ident ),*]
$val:expr => [$($out:ident),*]
$( $tail:tt )*
) => {
$( const_assert!($ty::$fn($val), $out); )*
suite_inner!($ty [$($fn),*] $($tail)*)
};
( $ty:ident [$( $fn:ident ),*]) => {};
}
#[derive(Debug)]
struct NonDet;
// The result of the `is_sign` methods are not checked for correctness, since LLVM does not
// guarantee anything about the signedness of NaNs. See
// https://github.com/rust-lang/rust/issues/55131.
suite! {
[is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative]
-0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet]
0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet]
1.0 => [ false, false, true, true, true, false]
-1.0 => [ false, false, true, true, false, true]
0.0 => [ false, false, true, false, true, false]
-0.0 => [ false, false, true, false, false, true]
1.0 / 0.0 => [ false, true, false, false, true, false]
-1.0 / 0.0 => [ false, true, false, false, false, true]
}
fn main() {
f32();
f64();
}

View File

@ -1,11 +0,0 @@
error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
--> $DIR/const-float-classify.rs:12:12
|
LL | impl const PartialEq<NonDet> for bool {
| ^^^^^^^^^^^^^^^^^
|
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
= note: adding a non-const method body in the future would be a breaking change
error: aborting due to 1 previous error

View File

@ -0,0 +1,82 @@
//@ compile-flags: -Zmir-opt-level=0 -Znext-solver
//@ run-pass
// ignore-tidy-linelength
// This tests the float classification functions, for regular runtime code and for const evaluation.
#![feature(f16_const)]
#![feature(f128_const)]
#![feature(const_float_classify)]
use std::hint::black_box;
use std::num::FpCategory::*;
macro_rules! both_assert {
($a:expr, NonDet) => {
{
// Compute `a`, but do not compare with anything as the result is non-deterministic.
const _: () = { let _val = $a; };
// `black_box` prevents promotion, and MIR opts are disabled above, so this is truly
// going through LLVM.
let _val = black_box($a);
}
};
($a:expr, $b:ident) => {
{
const _: () = assert!(matches!($a, $b));
assert!(black_box($a) == black_box($b));
}
};
}
macro_rules! suite {
( $tyname:ident: $( $tt:tt )* ) => {
fn f32() {
type $tyname = f32;
suite_inner!(f32 $($tt)*);
}
fn f64() {
type $tyname = f64;
suite_inner!(f64 $($tt)*);
}
}
}
macro_rules! suite_inner {
(
$ty:ident [$( $fn:ident ),*]
$val:expr => [$($out:ident),*]
$( $tail:tt )*
) => {
$( both_assert!($ty::$fn($val), $out); )*
suite_inner!($ty [$($fn),*] $($tail)*)
};
( $ty:ident [$( $fn:ident ),*]) => {};
}
// The result of the `is_sign` methods are not checked for correctness, since we do not
// guarantee anything about the signedness of NaNs. See
// https://rust-lang.github.io/rfcs/3514-float-semantics.html.
suite! { T: // type alias for the type we are testing
[ classify, is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative]
-0.0 / 0.0 => [ Nan, true, false, false, false, NonDet, NonDet]
0.0 / 0.0 => [ Nan, true, false, false, false, NonDet, NonDet]
1.0 => [ Normal, false, false, true, true, true, false]
-1.0 => [ Normal, false, false, true, true, false, true]
0.0 => [ Zero, false, false, true, false, true, false]
-0.0 => [ Zero, false, false, true, false, false, true]
1.0 / 0.0 => [ Infinite, false, true, false, false, true, false]
-1.0 / 0.0 => [ Infinite, false, true, false, false, false, true]
1.0 / T::MAX => [Subnormal, false, false, true, false, true, false]
-1.0 / T::MAX => [Subnormal, false, false, true, false, false, true]
}
fn main() {
f32();
f64();
// FIXME(f16_f128): also test f16 and f128
}

View File

@ -0,0 +1,168 @@
//@ compile-flags: -Zmir-opt-level=0
//@ run-pass
// This tests the float classification functions, for regular runtime code and for const evaluation.
#![feature(const_float_classify)]
#![feature(f16)]
#![feature(f128)]
#![feature(f16_const)]
#![feature(f128_const)]
#![allow(unused_macro_rules)]
use std::hint::black_box;
macro_rules! both_assert {
($a:expr) => {
{
const _: () = assert!($a);
// `black_box` prevents promotion, and MIR opts are disabled above, so this is truly
// going through LLVM.
assert!(black_box($a));
}
};
($a:expr, $b:expr) => {
{
const _: () = assert!($a == $b);
assert_eq!(black_box($a), black_box($b));
}
};
}
fn has_broken_floats() -> bool {
// i586 targets are broken due to <https://github.com/rust-lang/rust/issues/114479>.
cfg!(all(target_arch = "x86", not(target_feature = "sse2")))
}
#[cfg(target_arch = "x86_64")]
fn f16(){
both_assert!((1f16).to_bits(), 0x3c00);
both_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00);
both_assert!((12.5f16).to_bits(), 0x4a40);
both_assert!(u16::from_le_bytes(12.5f16.to_le_bytes()), 0x4a40);
both_assert!((1337f16).to_bits(), 0x6539);
both_assert!(u16::from_ne_bytes(1337f16.to_ne_bytes()), 0x6539);
both_assert!((-14.25f16).to_bits(), 0xcb20);
both_assert!(f16::from_bits(0x3c00), 1.0);
both_assert!(f16::from_be_bytes(0x3c00u16.to_be_bytes()), 1.0);
both_assert!(f16::from_bits(0x4a40), 12.5);
both_assert!(f16::from_le_bytes(0x4a40u16.to_le_bytes()), 12.5);
both_assert!(f16::from_bits(0x5be0), 252.0);
both_assert!(f16::from_ne_bytes(0x5be0u16.to_ne_bytes()), 252.0);
both_assert!(f16::from_bits(0xcb20), -14.25);
// Check that NaNs roundtrip their bits regardless of signalingness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
const QUIET_NAN: u16 = f16::NAN.to_bits() ^ 0x0155;
const SIGNALING_NAN: u16 = f16::NAN.to_bits() ^ 0x02AA;
both_assert!(f16::from_bits(QUIET_NAN).is_nan());
both_assert!(f16::from_bits(SIGNALING_NAN).is_nan());
both_assert!(f16::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
if !has_broken_floats() {
both_assert!(f16::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
}
}
fn f32() {
both_assert!((1f32).to_bits(), 0x3f800000);
both_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000);
both_assert!((12.5f32).to_bits(), 0x41480000);
both_assert!(u32::from_le_bytes(12.5f32.to_le_bytes()), 0x41480000);
both_assert!((1337f32).to_bits(), 0x44a72000);
both_assert!(u32::from_ne_bytes(1337f32.to_ne_bytes()), 0x44a72000);
both_assert!((-14.25f32).to_bits(), 0xc1640000);
both_assert!(f32::from_bits(0x3f800000), 1.0);
both_assert!(f32::from_be_bytes(0x3f800000u32.to_be_bytes()), 1.0);
both_assert!(f32::from_bits(0x41480000), 12.5);
both_assert!(f32::from_le_bytes(0x41480000u32.to_le_bytes()), 12.5);
both_assert!(f32::from_bits(0x44a72000), 1337.0);
both_assert!(f32::from_ne_bytes(0x44a72000u32.to_ne_bytes()), 1337.0);
both_assert!(f32::from_bits(0xc1640000), -14.25);
// Check that NaNs roundtrip their bits regardless of signalingness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
const QUIET_NAN: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA;
const SIGNALING_NAN: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
both_assert!(f32::from_bits(QUIET_NAN).is_nan());
both_assert!(f32::from_bits(SIGNALING_NAN).is_nan());
both_assert!(f32::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
if !has_broken_floats() {
both_assert!(f32::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
}
}
fn f64() {
both_assert!((1f64).to_bits(), 0x3ff0000000000000);
both_assert!(u64::from_be_bytes(1f64.to_be_bytes()), 0x3ff0000000000000);
both_assert!((12.5f64).to_bits(), 0x4029000000000000);
both_assert!(u64::from_le_bytes(12.5f64.to_le_bytes()), 0x4029000000000000);
both_assert!((1337f64).to_bits(), 0x4094e40000000000);
both_assert!(u64::from_ne_bytes(1337f64.to_ne_bytes()), 0x4094e40000000000);
both_assert!((-14.25f64).to_bits(), 0xc02c800000000000);
both_assert!(f64::from_bits(0x3ff0000000000000), 1.0);
both_assert!(f64::from_be_bytes(0x3ff0000000000000u64.to_be_bytes()), 1.0);
both_assert!(f64::from_bits(0x4029000000000000), 12.5);
both_assert!(f64::from_le_bytes(0x4029000000000000u64.to_le_bytes()), 12.5);
both_assert!(f64::from_bits(0x4094e40000000000), 1337.0);
both_assert!(f64::from_ne_bytes(0x4094e40000000000u64.to_ne_bytes()), 1337.0);
both_assert!(f64::from_bits(0xc02c800000000000), -14.25);
// Check that NaNs roundtrip their bits regardless of signalingness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
const QUIET_NAN: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
const SIGNALING_NAN: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
both_assert!(f64::from_bits(QUIET_NAN).is_nan());
both_assert!(f64::from_bits(SIGNALING_NAN).is_nan());
both_assert!(f64::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
if !has_broken_floats() {
both_assert!(f64::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
}
}
#[cfg(target_arch = "x86_64")]
fn f128() {
both_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
both_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000);
both_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
both_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000);
both_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000);
both_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000);
both_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000);
both_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0);
both_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0);
both_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5);
both_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5);
both_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0);
assert_eq!(f128::from_ne_bytes(0x40094e40000000000000000000000000u128.to_ne_bytes()), 1337.0);
both_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25);
// Check that NaNs roundtrip their bits regardless of signalingness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
const QUIET_NAN: u128 = f128::NAN.to_bits() | 0x0000_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA;
const SIGNALING_NAN: u128 = f128::NAN.to_bits() ^ 0x0000_5555_5555_5555_5555_5555_5555_5555;
both_assert!(f128::from_bits(QUIET_NAN).is_nan());
both_assert!(f128::from_bits(SIGNALING_NAN).is_nan());
both_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
if !has_broken_floats() {
both_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
}
}
fn main() {
f32();
f64();
#[cfg(target_arch = "x86_64")]
{
f16();
f128();
}
}

View File

@ -11,6 +11,7 @@ fn main() {
assert_ne!((n as f64) as f32, n as f32);
// FIXME: these assertions fail if only x87 is enabled
// see also https://github.com/rust-lang/rust/issues/114479
assert_eq!(n as i64 as f32, r);
assert_eq!(n as u64 as f32, r);
}

View File

@ -43,30 +43,6 @@ LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:70:9
|
LL | (_, _) => {}
| ^^^^^^ matches no values because `(u32, !)` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:76:9
|
LL | _ => {}
| ^ matches no values because `(!, !)` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:79:9
|
LL | (_, _) => {}
| ^^^^^^ matches no values because `(!, !)` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:83:9
|
@ -94,22 +70,6 @@ LL + Ok(_) => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:94:9
|
LL | Err(_) => {}
| ^^^^^^ matches no values because `!` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:99:9
|
LL | Err(_) => {}
| ^^^^^^ matches no values because `!` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
--> $DIR/empty-types.rs:96:11
|
@ -156,54 +116,6 @@ help: you might want to use `let else` to handle the variant that isn't matched
LL | let Ok(_x) = &res_u32_never else { todo!() };
| ++++++++++++++++
error: unreachable pattern
--> $DIR/empty-types.rs:112:9
|
LL | _ => {}
| ^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:115:9
|
LL | Ok(_) => {}
| ^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:118:9
|
LL | Ok(_) => {}
| ^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:119:9
|
LL | _ => {}
| ^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:122:9
|
LL | Ok(_) => {}
| ^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:123:9
|
LL | Err(_) => {}
| ^^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:132:13
|
@ -220,22 +132,6 @@ LL | _ if false => {}
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:143:13
|
LL | Some(_) => {}
| ^^^^^^^ matches no values because `Void` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:147:13
|
LL | None => {}
| ---- matches all the relevant values
LL | _ => {}
| ^ no value can reach this
error[E0004]: non-exhaustive patterns: `Some(!)` not covered
--> $DIR/empty-types.rs:156:15
|
@ -303,30 +199,6 @@ LL | _ => {}
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:284:9
|
LL | (_, _) => {}
| ^^^^^^ matches no values because `(!, !)` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:287:9
|
LL | Ok(_) => {}
| ^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:288:9
|
LL | Err(_) => {}
| ^^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:297:13
|
@ -474,30 +346,6 @@ LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:368:9
|
LL | _ => {}
| ^ matches no values because `[!; 3]` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:371:9
|
LL | [_, _, _] => {}
| ^^^^^^^^^ matches no values because `[!; 3]` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:374:9
|
LL | [_, ..] => {}
| ^^^^^^^ matches no values because `[!; 3]` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
--> $DIR/empty-types.rs:388:11
|
@ -534,40 +382,6 @@ LL ~ [..] if false => {},
LL + [] => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:416:9
|
LL | Some(_) => {}
| ^^^^^^^ matches no values because `!` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:421:9
|
LL | Some(_a) => {}
| ^^^^^^^^ matches no values because `!` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:426:9
|
LL | None => {}
| ---- matches all the relevant values
LL | // !useful, !reachable
LL | _ => {}
| ^ no value can reach this
error: unreachable pattern
--> $DIR/empty-types.rs:431:9
|
LL | None => {}
| ---- matches all the relevant values
LL | // !useful, !reachable
LL | _a => {}
| ^^ no value can reach this
error[E0004]: non-exhaustive patterns: `&Some(!)` not covered
--> $DIR/empty-types.rs:451:11
|
@ -744,7 +558,7 @@ LL ~ None => {},
LL + Some(!)
|
error: aborting due to 65 previous errors; 1 warning emitted
error: aborting due to 42 previous errors; 1 warning emitted
Some errors have detailed explanations: E0004, E0005.
For more information about an error, try `rustc --explain E0004`.

View File

@ -34,30 +34,6 @@ LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:70:9
|
LL | (_, _) => {}
| ^^^^^^ matches no values because `(u32, !)` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:76:9
|
LL | _ => {}
| ^ matches no values because `(!, !)` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:79:9
|
LL | (_, _) => {}
| ^^^^^^ matches no values because `(!, !)` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:83:9
|
@ -85,22 +61,6 @@ LL + Ok(_) => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:94:9
|
LL | Err(_) => {}
| ^^^^^^ matches no values because `!` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:99:9
|
LL | Err(_) => {}
| ^^^^^^ matches no values because `!` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
--> $DIR/empty-types.rs:96:11
|
@ -147,54 +107,6 @@ help: you might want to use `let else` to handle the variant that isn't matched
LL | let Ok(_x) = &res_u32_never else { todo!() };
| ++++++++++++++++
error: unreachable pattern
--> $DIR/empty-types.rs:112:9
|
LL | _ => {}
| ^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:115:9
|
LL | Ok(_) => {}
| ^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:118:9
|
LL | Ok(_) => {}
| ^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:119:9
|
LL | _ => {}
| ^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:122:9
|
LL | Ok(_) => {}
| ^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:123:9
|
LL | Err(_) => {}
| ^^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:132:13
|
@ -211,22 +123,6 @@ LL | _ if false => {}
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:143:13
|
LL | Some(_) => {}
| ^^^^^^^ matches no values because `Void` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:147:13
|
LL | None => {}
| ---- matches all the relevant values
LL | _ => {}
| ^ no value can reach this
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:156:15
|
@ -294,30 +190,6 @@ LL | _ => {}
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:284:9
|
LL | (_, _) => {}
| ^^^^^^ matches no values because `(!, !)` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:287:9
|
LL | Ok(_) => {}
| ^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:288:9
|
LL | Err(_) => {}
| ^^^^^^ matches no values because `Result<!, !>` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:297:13
|
@ -465,30 +337,6 @@ LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:368:9
|
LL | _ => {}
| ^ matches no values because `[!; 3]` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:371:9
|
LL | [_, _, _] => {}
| ^^^^^^^^^ matches no values because `[!; 3]` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:374:9
|
LL | [_, ..] => {}
| ^^^^^^^ matches no values because `[!; 3]` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
--> $DIR/empty-types.rs:388:11
|
@ -525,40 +373,6 @@ LL ~ [..] if false => {},
LL + [] => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:416:9
|
LL | Some(_) => {}
| ^^^^^^^ matches no values because `!` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:421:9
|
LL | Some(_a) => {}
| ^^^^^^^^ matches no values because `!` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/empty-types.rs:426:9
|
LL | None => {}
| ---- matches all the relevant values
LL | // !useful, !reachable
LL | _ => {}
| ^ no value can reach this
error: unreachable pattern
--> $DIR/empty-types.rs:431:9
|
LL | None => {}
| ---- matches all the relevant values
LL | // !useful, !reachable
LL | _a => {}
| ^^ no value can reach this
error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
--> $DIR/empty-types.rs:451:11
|
@ -735,7 +549,7 @@ LL ~ None => {},
LL + Some(_) => todo!()
|
error: aborting due to 65 previous errors
error: aborting due to 42 previous errors
Some errors have detailed explanations: E0004, E0005.
For more information about an error, try `rustc --explain E0004`.

View File

@ -67,16 +67,16 @@ fn basic(x: NeverBundle) {
let tuple_half_never: (u32, !) = x.tuple_half_never;
match tuple_half_never {}
match tuple_half_never {
(_, _) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let tuple_never: (!, !) = x.tuple_never;
match tuple_never {}
match tuple_never {
_ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match tuple_never {
(_, _) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match tuple_never.0 {}
match tuple_never.0 {
@ -91,12 +91,12 @@ fn basic(x: NeverBundle) {
}
match res_u32_never {
Ok(_) => {}
Err(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match res_u32_never {
//~^ ERROR non-exhaustive
Ok(0) => {}
Err(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let Ok(_x) = res_u32_never;
let Ok(_x) = res_u32_never.as_ref();
@ -109,18 +109,18 @@ fn basic(x: NeverBundle) {
let result_never: Result<!, !> = x.result_never;
match result_never {}
match result_never {
_ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
}
@ -140,11 +140,11 @@ fn void_same_as_never(x: NeverBundle) {
}
match opt_void {
None => {}
Some(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match opt_void {
None => {}
_ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let ref_void: &Void = &x.void;
@ -281,11 +281,11 @@ fn nested_validity_tracking(bundle: NeverBundle) {
_ => {} //~ ERROR unreachable pattern
}
match tuple_never {
(_, _) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
// These should be considered !known_valid and not warn unreachable.
@ -365,13 +365,13 @@ fn arrays_and_slices(x: NeverBundle) {
let array_3_never: [!; 3] = x.array_3_never;
match array_3_never {}
match array_3_never {
_ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match array_3_never {
[_, _, _] => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
[_, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match array_3_never {
[_, ..] => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
[_, ..] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let ref_array_3_never: &[!; 3] = &array_3_never;
@ -413,22 +413,22 @@ fn bindings(x: NeverBundle) {
match opt_never {
None => {}
// !useful, !reachable
Some(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
Some(_a) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
Some(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
_ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
_a => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
// The scrutinee is known_valid, but under the `&` isn't anymore.

View File

@ -1,4 +1,5 @@
#![feature(never_type)]
#![feature(exhaustive_patterns)]
#![deny(unreachable_patterns)]
//~^ NOTE lint level is defined here

View File

@ -1,5 +1,5 @@
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:10:9
--> $DIR/explain-unreachable-pats.rs:11:9
|
LL | (1 | 2,) => {}
| -------- matches all the relevant values
@ -8,19 +8,19 @@ LL | (2,) => {}
| ^^^^ no value can reach this
|
note: the lint level is defined here
--> $DIR/explain-unreachable-pats.rs:2:9
--> $DIR/explain-unreachable-pats.rs:3:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:21:9
--> $DIR/explain-unreachable-pats.rs:22:9
|
LL | (1 | 2,) => {}
| ^^^^^^^^ no value can reach this
|
note: multiple earlier patterns match some of the same values
--> $DIR/explain-unreachable-pats.rs:21:9
--> $DIR/explain-unreachable-pats.rs:22:9
|
LL | (1,) => {}
| ---- matches some of the same values
@ -32,13 +32,13 @@ LL | (1 | 2,) => {}
| ^^^^^^^^ collectively making this unreachable
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:40:9
--> $DIR/explain-unreachable-pats.rs:41:9
|
LL | 1 ..= 6 => {}
| ^^^^^^^ no value can reach this
|
note: multiple earlier patterns match some of the same values
--> $DIR/explain-unreachable-pats.rs:40:9
--> $DIR/explain-unreachable-pats.rs:41:9
|
LL | 1 => {}
| - matches some of the same values
@ -56,7 +56,7 @@ LL | 1 ..= 6 => {}
| ^^^^^^^ ...and 2 other patterns collectively make this unreachable
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:51:9
--> $DIR/explain-unreachable-pats.rs:52:9
|
LL | Err(_) => {}
| ^^^^^^ matches no values because `!` is uninhabited
@ -64,7 +64,7 @@ LL | Err(_) => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:65:9
--> $DIR/explain-unreachable-pats.rs:66:9
|
LL | (Err(_), Err(_)) => {}
| ^^^^^^^^^^^^^^^^ matches no values because `Void2` is uninhabited
@ -72,7 +72,7 @@ LL | (Err(_), Err(_)) => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:72:9
--> $DIR/explain-unreachable-pats.rs:73:9
|
LL | (Err(_), Err(_)) => {}
| ^^^^^^^^^^^^^^^^ matches no values because `Void1` is uninhabited
@ -80,7 +80,7 @@ LL | (Err(_), Err(_)) => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:82:11
--> $DIR/explain-unreachable-pats.rs:83:11
|
LL | if let (0
| - matches all the relevant values
@ -89,13 +89,13 @@ LL | | 0, _) = (0, 0) {}
| ^ no value can reach this
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:92:9
--> $DIR/explain-unreachable-pats.rs:93:9
|
LL | (_, true) => {}
| ^^^^^^^^^ no value can reach this
|
note: multiple earlier patterns match some of the same values
--> $DIR/explain-unreachable-pats.rs:92:9
--> $DIR/explain-unreachable-pats.rs:93:9
|
LL | (true, _) => {}
| --------- matches some of the same values
@ -107,7 +107,7 @@ LL | (_, true) => {}
| ^^^^^^^^^ collectively making this unreachable
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:105:9
--> $DIR/explain-unreachable-pats.rs:106:9
|
LL | (true, _) => {}
| --------- matches all the relevant values
@ -116,7 +116,7 @@ LL | (true, true) => {}
| ^^^^^^^^^^^^ no value can reach this
error: unreachable pattern
--> $DIR/explain-unreachable-pats.rs:117:9
--> $DIR/explain-unreachable-pats.rs:118:9
|
LL | (_, true, 0..10) => {}
| ---------------- matches all the relevant values

View File

@ -1,6 +1,7 @@
#![feature(never_type)]
#![feature(type_alias_impl_trait)]
#![feature(non_exhaustive_omitted_patterns_lint)]
#![feature(exhaustive_patterns)]
#![deny(unreachable_patterns)]
// Test that the lint traversal handles opaques correctly
#![deny(non_exhaustive_omitted_patterns)]

View File

@ -1,18 +1,18 @@
error: unreachable pattern
--> $DIR/impl-trait.rs:16:13
--> $DIR/impl-trait.rs:17:13
|
LL | _ => {}
| ^ matches no values because `Void` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
note: the lint level is defined here
--> $DIR/impl-trait.rs:4:9
--> $DIR/impl-trait.rs:5:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/impl-trait.rs:30:13
--> $DIR/impl-trait.rs:31:13
|
LL | _ => {}
| ^ matches no values because `Void` is uninhabited
@ -20,7 +20,7 @@ LL | _ => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/impl-trait.rs:44:13
--> $DIR/impl-trait.rs:45:13
|
LL | Some(_) => {}
| ^^^^^^^ matches no values because `Void` is uninhabited
@ -28,7 +28,7 @@ LL | Some(_) => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/impl-trait.rs:48:13
--> $DIR/impl-trait.rs:49:13
|
LL | None => {}
| ---- matches all the relevant values
@ -36,7 +36,7 @@ LL | _ => {}
| ^ no value can reach this
error: unreachable pattern
--> $DIR/impl-trait.rs:58:13
--> $DIR/impl-trait.rs:59:13
|
LL | Some(_) => {}
| ^^^^^^^ matches no values because `Void` is uninhabited
@ -44,7 +44,7 @@ LL | Some(_) => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/impl-trait.rs:62:13
--> $DIR/impl-trait.rs:63:13
|
LL | None => {}
| ---- matches all the relevant values
@ -52,7 +52,7 @@ LL | _ => {}
| ^ no value can reach this
error: unreachable pattern
--> $DIR/impl-trait.rs:75:9
--> $DIR/impl-trait.rs:76:9
|
LL | _ => {}
| ^ matches no values because `Void` is uninhabited
@ -60,7 +60,7 @@ LL | _ => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/impl-trait.rs:85:9
--> $DIR/impl-trait.rs:86:9
|
LL | _ => {}
| - matches any value
@ -68,7 +68,7 @@ LL | Some((a, b)) => {}
| ^^^^^^^^^^^^ no value can reach this
error: unreachable pattern
--> $DIR/impl-trait.rs:93:13
--> $DIR/impl-trait.rs:94:13
|
LL | _ => {}
| ^ matches no values because `Void` is uninhabited
@ -76,7 +76,7 @@ LL | _ => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/impl-trait.rs:104:9
--> $DIR/impl-trait.rs:105:9
|
LL | Some((a, b)) => {}
| ------------ matches all the relevant values
@ -84,7 +84,7 @@ LL | Some((mut x, mut y)) => {
| ^^^^^^^^^^^^^^^^^^^^ no value can reach this
error: unreachable pattern
--> $DIR/impl-trait.rs:123:13
--> $DIR/impl-trait.rs:124:13
|
LL | _ => {}
| - matches any value
@ -92,7 +92,7 @@ LL | Rec { n: 0, w: Some(Rec { n: 0, w: _ }) } => {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no value can reach this
error: unreachable pattern
--> $DIR/impl-trait.rs:137:13
--> $DIR/impl-trait.rs:138:13
|
LL | _ => {}
| ^ matches no values because `SecretelyVoid` is uninhabited
@ -100,7 +100,7 @@ LL | _ => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/impl-trait.rs:150:13
--> $DIR/impl-trait.rs:151:13
|
LL | _ => {}
| ^ matches no values because `SecretelyDoubleVoid` is uninhabited
@ -108,7 +108,7 @@ LL | _ => {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty
--> $DIR/impl-trait.rs:22:11
--> $DIR/impl-trait.rs:23:11
|
LL | match return_never_rpit(x) {}
| ^^^^^^^^^^^^^^^^^^^^
@ -122,7 +122,7 @@ LL + }
|
error[E0004]: non-exhaustive patterns: type `T` is non-empty
--> $DIR/impl-trait.rs:36:11
--> $DIR/impl-trait.rs:37:11
|
LL | match return_never_tait(x) {}
| ^^^^^^^^^^^^^^^^^^^^

View File

@ -1,3 +1,4 @@
#![feature(exhaustive_patterns)]
#![feature(never_type, never_type_fallback)]
#![allow(unreachable_code)]
#![deny(unreachable_patterns)]

View File

@ -1,12 +1,12 @@
error: unreachable pattern
--> $DIR/unreachable-loop-patterns.rs:16:9
--> $DIR/unreachable-loop-patterns.rs:17:9
|
LL | for _ in unimplemented!() as Void {}
| ^ matches no values because `Void` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
note: the lint level is defined here
--> $DIR/unreachable-loop-patterns.rs:3:9
--> $DIR/unreachable-loop-patterns.rs:4:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^

View File

@ -1,3 +1,4 @@
#![feature(exhaustive_patterns)]
#![feature(never_patterns)]
#![allow(incomplete_features)]
#![allow(dead_code, unreachable_code)]

View File

@ -1,18 +1,18 @@
error: unreachable pattern
--> $DIR/unreachable.rs:14:9
--> $DIR/unreachable.rs:15:9
|
LL | Err(!),
| ^^^^^^ matches no values because `Void` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
note: the lint level is defined here
--> $DIR/unreachable.rs:4:9
--> $DIR/unreachable.rs:5:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/unreachable.rs:17:19
--> $DIR/unreachable.rs:18:19
|
LL | let (Ok(_x) | Err(!)) = res_void;
| ^^^^^^ matches no values because `Void` is uninhabited
@ -20,7 +20,7 @@ LL | let (Ok(_x) | Err(!)) = res_void;
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/unreachable.rs:19:12
--> $DIR/unreachable.rs:20:12
|
LL | if let Err(!) = res_void {}
| ^^^^^^ matches no values because `Void` is uninhabited
@ -28,7 +28,7 @@ LL | if let Err(!) = res_void {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/unreachable.rs:21:24
--> $DIR/unreachable.rs:22:24
|
LL | if let (Ok(true) | Err(!)) = res_void {}
| ^^^^^^ matches no values because `Void` is uninhabited
@ -36,7 +36,7 @@ LL | if let (Ok(true) | Err(!)) = res_void {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/unreachable.rs:23:23
--> $DIR/unreachable.rs:24:23
|
LL | for (Ok(mut _x) | Err(!)) in [res_void] {}
| ^^^^^^ matches no values because `Void` is uninhabited
@ -44,7 +44,7 @@ LL | for (Ok(mut _x) | Err(!)) in [res_void] {}
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/unreachable.rs:27:18
--> $DIR/unreachable.rs:28:18
|
LL | fn foo((Ok(_x) | Err(!)): Result<bool, Void>) {}
| ^^^^^^ matches no values because `Void` is uninhabited

View File

@ -12,7 +12,6 @@ use uninhabited::PartiallyInhabitedVariants;
pub fn foo(x: PartiallyInhabitedVariants) {
match x {
PartiallyInhabitedVariants::Struct { .. } => {}
//~^ ERROR unreachable pattern
PartiallyInhabitedVariants::Struct { .. } => {}
//~^ ERROR unreachable pattern
_ => {}

View File

@ -1,23 +1,16 @@
error: unreachable pattern
--> $DIR/issue-65157-repeated-match-arm.rs:14:9
--> $DIR/issue-65157-repeated-match-arm.rs:15:9
|
LL | PartiallyInhabitedVariants::Struct { .. } => {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `PartiallyInhabitedVariants` is uninhabited
| ----------------------------------------- matches all the relevant values
LL | PartiallyInhabitedVariants::Struct { .. } => {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no value can reach this
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
note: the lint level is defined here
--> $DIR/issue-65157-repeated-match-arm.rs:2:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/issue-65157-repeated-match-arm.rs:16:9
|
LL | PartiallyInhabitedVariants::Struct { .. } => {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `PartiallyInhabitedVariants` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: aborting due to 2 previous errors
error: aborting due to 1 previous error

View File

@ -1,4 +1,5 @@
//@ aux-build:uninhabited.rs
#![feature(exhaustive_patterns)]
#![deny(unreachable_patterns)]
extern crate uninhabited;

View File

@ -1,18 +1,18 @@
error: unreachable pattern
--> $DIR/patterns.rs:41:9
--> $DIR/patterns.rs:42:9
|
LL | Some(_x) => (),
| ^^^^^^^^ matches no values because `UninhabitedVariants` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
note: the lint level is defined here
--> $DIR/patterns.rs:2:9
--> $DIR/patterns.rs:3:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/patterns.rs:46:15
--> $DIR/patterns.rs:47:15
|
LL | while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `!` is uninhabited
@ -20,7 +20,7 @@ LL | while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inha
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/patterns.rs:48:15
--> $DIR/patterns.rs:49:15
|
LL | while let Some(_x) = uninhabited_struct() {
| ^^^^^^^^ matches no values because `UninhabitedStruct` is uninhabited
@ -28,7 +28,7 @@ LL | while let Some(_x) = uninhabited_struct() {
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/patterns.rs:51:15
--> $DIR/patterns.rs:52:15
|
LL | while let Some(_x) = uninhabited_tuple_struct() {
| ^^^^^^^^ matches no values because `UninhabitedTupleStruct` is uninhabited

View File

@ -1,3 +1,4 @@
#![feature(exhaustive_patterns)]
#![deny(unreachable_patterns)]
#![feature(never_type)]

View File

@ -1,18 +1,18 @@
error: unreachable pattern
--> $DIR/patterns_same_crate.rs:52:9
--> $DIR/patterns_same_crate.rs:53:9
|
LL | Some(_x) => (),
| ^^^^^^^^ matches no values because `UninhabitedEnum` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
note: the lint level is defined here
--> $DIR/patterns_same_crate.rs:1:9
--> $DIR/patterns_same_crate.rs:2:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/patterns_same_crate.rs:57:9
--> $DIR/patterns_same_crate.rs:58:9
|
LL | Some(_x) => (),
| ^^^^^^^^ matches no values because `UninhabitedVariants` is uninhabited
@ -20,7 +20,7 @@ LL | Some(_x) => (),
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/patterns_same_crate.rs:61:15
--> $DIR/patterns_same_crate.rs:62:15
|
LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `!` is uninhabited
@ -28,7 +28,7 @@ LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabite
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/patterns_same_crate.rs:65:15
--> $DIR/patterns_same_crate.rs:66:15
|
LL | while let Some(_x) = uninhabited_struct() {
| ^^^^^^^^ matches no values because `UninhabitedStruct` is uninhabited
@ -36,7 +36,7 @@ LL | while let Some(_x) = uninhabited_struct() {
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/patterns_same_crate.rs:68:15
--> $DIR/patterns_same_crate.rs:69:15
|
LL | while let Some(_x) = uninhabited_tuple_struct() {
| ^^^^^^^^ matches no values because `UninhabitedTupleStruct` is uninhabited

View File

@ -1,3 +1,4 @@
#![feature(exhaustive_patterns)]
#![feature(box_patterns)]
#![feature(never_type)]
#![deny(unreachable_patterns)]

View File

@ -1,18 +1,18 @@
error: unreachable pattern
--> $DIR/uninhabited-patterns.rs:29:9
--> $DIR/uninhabited-patterns.rs:30:9
|
LL | Ok(box _) => (),
| ^^^^^^^^^ matches no values because `NotSoSecretlyEmpty` is uninhabited
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
note: the lint level is defined here
--> $DIR/uninhabited-patterns.rs:3:9
--> $DIR/uninhabited-patterns.rs:4:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/uninhabited-patterns.rs:38:9
--> $DIR/uninhabited-patterns.rs:39:9
|
LL | Err(Ok(_y)) => (),
| ^^^^^^^^^^^ matches no values because `NotSoSecretlyEmpty` is uninhabited
@ -20,7 +20,7 @@ LL | Err(Ok(_y)) => (),
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error: unreachable pattern
--> $DIR/uninhabited-patterns.rs:41:15
--> $DIR/uninhabited-patterns.rs:42:15
|
LL | while let Some(_y) = foo() {
| ^^^^^^^^ matches no values because `NotSoSecretlyEmpty` is uninhabited

View File

@ -570,7 +570,7 @@ cc = ["@bjorn3"]
cc = ["@antoyo", "@GuillaumeGomez"]
[mentions."compiler/rustc_const_eval/src/interpret"]
message = "Some changes occurred to the CTFE / Miri engine"
message = "Some changes occurred to the CTFE / Miri interpreter"
cc = ["@rust-lang/miri"]
[mentions."compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs"]
@ -590,7 +590,7 @@ message = "changes to `inspect_obligations.rs`"
cc = ["@compiler-errors", "@lcnr"]
[mentions."compiler/rustc_middle/src/mir/interpret"]
message = "Some changes occurred to the CTFE / Miri engine"
message = "Some changes occurred to the CTFE / Miri interpreter"
cc = ["@rust-lang/miri"]
[mentions."compiler/rustc_mir_transform/src/"]
@ -659,6 +659,13 @@ LLVM backend as well as portable-simd gets adapted for the changes.
"""
cc = ["@antoyo", "@GuillaumeGomez", "@bjorn3", "@calebzulawski", "@programmerjake"]
[mentions."library/core/src/intrinsics"]
message = """
Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.
"""
cc = ["@rust-lang/miri"]
[mentions."library/portable-simd"]
message = """
Portable SIMD is developed in its own repository. If possible, consider \