Use assert_matches around the compiler

This commit is contained in:
Michael Goulet 2024-08-11 12:10:36 -04:00
parent 68d2e8a66e
commit c361c924a0
39 changed files with 100 additions and 49 deletions

View File

@ -3,6 +3,8 @@
#![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
use std::assert_matches::assert_matches;
use rustc_errors::{Applicability, Diag}; use rustc_errors::{Applicability, Diag};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
@ -116,7 +118,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
// path_span must be `Some` as otherwise the if condition is true // path_span must be `Some` as otherwise the if condition is true
let path_span = path_span.unwrap(); let path_span = path_span.unwrap();
// path_span is only present in the case of closure capture // path_span is only present in the case of closure capture
assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture)); assert_matches!(later_use_kind, LaterUseKind::ClosureCapture);
if !borrow_span.is_some_and(|sp| sp.overlaps(var_or_use_span)) { if !borrow_span.is_some_and(|sp| sp.overlaps(var_or_use_span)) {
let path_label = "used here by closure"; let path_label = "used here by closure";
let capture_kind_label = message; let capture_kind_label = message;
@ -147,7 +149,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
// path_span must be `Some` as otherwise the if condition is true // path_span must be `Some` as otherwise the if condition is true
let path_span = path_span.unwrap(); let path_span = path_span.unwrap();
// path_span is only present in the case of closure capture // path_span is only present in the case of closure capture
assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture)); assert_matches!(later_use_kind, LaterUseKind::ClosureCapture);
if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) { if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) {
let path_label = "used here by closure"; let path_label = "used here by closure";
let capture_kind_label = message; let capture_kind_label = message;

View File

@ -1,3 +1,5 @@
use std::assert_matches::assert_matches;
use libc::{c_char, c_uint}; use libc::{c_char, c_uint};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_codegen_ssa::mir::operand::OperandValue; use rustc_codegen_ssa::mir::operand::OperandValue;
@ -89,7 +91,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
// if the target feature needed by the register class is // if the target feature needed by the register class is
// disabled. This is necessary otherwise LLVM will try // disabled. This is necessary otherwise LLVM will try
// to actually allocate a register for the dummy output. // to actually allocate a register for the dummy output.
assert!(matches!(reg, InlineAsmRegOrRegClass::Reg(_))); assert_matches!(reg, InlineAsmRegOrRegClass::Reg(_));
clobbers.push(format!("~{}", reg_to_llvm(reg, None))); clobbers.push(format!("~{}", reg_to_llvm(reg, None)));
continue; continue;
} else { } else {

View File

@ -1,3 +1,4 @@
use std::assert_matches::assert_matches;
use std::cmp::Ordering; use std::cmp::Ordering;
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
@ -1142,7 +1143,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
for (ty, arg) in arg_tys.iter().zip(args) { for (ty, arg) in arg_tys.iter().zip(args) {
if ty.is_simd() { if ty.is_simd() {
assert!(matches!(arg.val, OperandValue::Immediate(_))); assert_matches!(arg.val, OperandValue::Immediate(_));
} }
} }
} }

View File

@ -8,6 +8,7 @@
#![allow(internal_features)] #![allow(internal_features)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)] #![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(exact_size_is_empty)] #![feature(exact_size_is_empty)]
#![feature(extern_types)] #![feature(extern_types)]
#![feature(hash_raw_entry)] #![feature(hash_raw_entry)]

View File

@ -1,4 +1,5 @@
use std::any::Any; use std::any::Any;
use std::assert_matches::assert_matches;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::mpsc::{channel, Receiver, Sender};
@ -1963,7 +1964,7 @@ impl SharedEmitterMain {
sess.dcx().abort_if_errors(); sess.dcx().abort_if_errors();
} }
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => { Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
assert!(matches!(level, Level::Error | Level::Warning | Level::Note)); assert_matches!(level, Level::Error | Level::Warning | Level::Note);
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string(); let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
let mut err = Diag::<()>::new(sess.dcx(), level, msg); let mut err = Diag::<()>::new(sess.dcx(), level, msg);

View File

@ -4,6 +4,7 @@
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)] #![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(if_let_guard)] #![feature(if_let_guard)]
#![feature(let_chains)] #![feature(let_chains)]

View File

@ -1,3 +1,4 @@
use std::assert_matches::assert_matches;
use std::fmt; use std::fmt;
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
@ -389,7 +390,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
} }
// Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]); // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
(OperandValue::Immediate(llval), Abi::Aggregate { sized: true }) => { (OperandValue::Immediate(llval), Abi::Aggregate { sized: true }) => {
assert!(matches!(self.layout.abi, Abi::Vector { .. })); assert_matches!(self.layout.abi, Abi::Vector { .. });
let llfield_ty = bx.cx().backend_type(field); let llfield_ty = bx.cx().backend_type(field);

View File

@ -1,3 +1,5 @@
use std::assert_matches::assert_matches;
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
@ -220,7 +222,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
match operand.val { match operand.val {
OperandValue::Ref(source_place_val) => { OperandValue::Ref(source_place_val) => {
assert_eq!(source_place_val.llextra, None); assert_eq!(source_place_val.llextra, None);
assert!(matches!(operand_kind, OperandValueKind::Ref)); assert_matches!(operand_kind, OperandValueKind::Ref);
Some(bx.load_operand(source_place_val.with_type(cast)).val) Some(bx.load_operand(source_place_val.with_type(cast)).val)
} }
OperandValue::ZeroSized => { OperandValue::ZeroSized => {

View File

@ -1,3 +1,5 @@
use std::assert_matches::assert_matches;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout}; use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
use rustc_middle::ty::{Instance, Ty}; use rustc_middle::ty::{Instance, Ty};
@ -254,10 +256,10 @@ pub trait BuilderMethods<'a, 'tcx>:
} else { } else {
(in_ty, dest_ty) (in_ty, dest_ty)
}; };
assert!(matches!( assert_matches!(
self.cx().type_kind(float_ty), self.cx().type_kind(float_ty),
TypeKind::Half | TypeKind::Float | TypeKind::Double | TypeKind::FP128 TypeKind::Half | TypeKind::Float | TypeKind::Double | TypeKind::FP128
)); );
assert_eq!(self.cx().type_kind(int_ty), TypeKind::Integer); assert_eq!(self.cx().type_kind(int_ty), TypeKind::Integer);
if let Some(false) = self.cx().sess().opts.unstable_opts.saturating_float_casts { if let Some(false) = self.cx().sess().opts.unstable_opts.saturating_float_casts {

View File

@ -1,5 +1,6 @@
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
use std::assert_matches::assert_matches;
use std::mem; use std::mem;
use std::ops::Deref; use std::ops::Deref;
@ -590,7 +591,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) { if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
// Int, bool, and char operations are fine. // Int, bool, and char operations are fine.
} else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() { } else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
assert!(matches!( assert_matches!(
op, op,
BinOp::Eq BinOp::Eq
| BinOp::Ne | BinOp::Ne
@ -599,7 +600,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
| BinOp::Ge | BinOp::Ge
| BinOp::Gt | BinOp::Gt
| BinOp::Offset | BinOp::Offset
)); );
self.check_op(ops::RawPtrComparison); self.check_op(ops::RawPtrComparison);
} else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() { } else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {

View File

@ -1,5 +1,6 @@
//! Manages calling a concrete function (with known MIR body) with argument passing, //! Manages calling a concrete function (with known MIR body) with argument passing,
//! and returning the return value to the caller. //! and returning the return value to the caller.
use std::assert_matches::assert_matches;
use std::borrow::Cow; use std::borrow::Cow;
use either::{Left, Right}; use either::{Left, Right};
@ -557,7 +558,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
unwind, unwind,
)? { )? {
assert!(!self.tcx.intrinsic(fallback.def_id()).unwrap().must_be_overridden); assert!(!self.tcx.intrinsic(fallback.def_id()).unwrap().must_be_overridden);
assert!(matches!(fallback.def, ty::InstanceKind::Item(_))); assert_matches!(fallback.def, ty::InstanceKind::Item(_));
return self.init_fn_call( return self.init_fn_call(
FnVal::Instance(fallback), FnVal::Instance(fallback),
(caller_abi, caller_fn_abi), (caller_abi, caller_fn_abi),

View File

@ -2,6 +2,8 @@
//! looking at their MIR. Intrinsics/functions supported here are shared by CTFE //! looking at their MIR. Intrinsics/functions supported here are shared by CTFE
//! and miri. //! and miri.
use std::assert_matches::assert_matches;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
use rustc_middle::ty::layout::{LayoutOf as _, TyAndLayout, ValidityRequirement}; use rustc_middle::ty::layout::{LayoutOf as _, TyAndLayout, ValidityRequirement};
@ -510,7 +512,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
dest: &MPlaceTy<'tcx, M::Provenance>, dest: &MPlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
assert_eq!(a.layout.ty, b.layout.ty); assert_eq!(a.layout.ty, b.layout.ty);
assert!(matches!(a.layout.ty.kind(), ty::Int(..) | ty::Uint(..))); assert_matches!(a.layout.ty.kind(), ty::Int(..) | ty::Uint(..));
// Performs an exact division, resulting in undefined behavior where // Performs an exact division, resulting in undefined behavior where
// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`. // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
@ -536,8 +538,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
r: &ImmTy<'tcx, M::Provenance>, r: &ImmTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, Scalar<M::Provenance>> { ) -> InterpResult<'tcx, Scalar<M::Provenance>> {
assert_eq!(l.layout.ty, r.layout.ty); assert_eq!(l.layout.ty, r.layout.ty);
assert!(matches!(l.layout.ty.kind(), ty::Int(..) | ty::Uint(..))); assert_matches!(l.layout.ty.kind(), ty::Int(..) | ty::Uint(..));
assert!(matches!(mir_op, BinOp::Add | BinOp::Sub)); assert_matches!(mir_op, BinOp::Add | BinOp::Sub);
let (val, overflowed) = let (val, overflowed) =
self.binary_op(mir_op.wrapping_to_overflowing().unwrap(), l, r)?.to_scalar_pair(); self.binary_op(mir_op.wrapping_to_overflowing().unwrap(), l, r)?.to_scalar_pair();

View File

@ -342,7 +342,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
} }
// extract fields from types with `ScalarPair` ABI // extract fields from types with `ScalarPair` ABI
(Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => { (Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
assert!(matches!(layout.abi, Abi::Scalar(..))); assert_matches!(layout.abi, Abi::Scalar(..));
Immediate::from(if offset.bytes() == 0 { Immediate::from(if offset.bytes() == 0 {
debug_assert_eq!(layout.size, a.size(cx)); debug_assert_eq!(layout.size, a.size(cx));
a_val a_val

View File

@ -8,6 +8,7 @@
//! Typical examples would include: minimum element in SCC, maximum element //! Typical examples would include: minimum element in SCC, maximum element
//! reachable from it, etc. //! reachable from it, etc.
use std::assert_matches::debug_assert_matches;
use std::fmt::Debug; use std::fmt::Debug;
use std::ops::Range; use std::ops::Range;
@ -569,7 +570,7 @@ where
// This None marks that we still have the initialize this node's frame. // This None marks that we still have the initialize this node's frame.
debug!(?depth, ?node); debug!(?depth, ?node);
debug_assert!(matches!(self.node_states[node], NodeState::NotVisited)); debug_assert_matches!(self.node_states[node], NodeState::NotVisited);
// Push `node` onto the stack. // Push `node` onto the stack.
self.node_states[node] = NodeState::BeingVisited { self.node_states[node] = NodeState::BeingVisited {

View File

@ -18,6 +18,7 @@
#![feature(array_windows)] #![feature(array_windows)]
#![feature(ascii_char)] #![feature(ascii_char)]
#![feature(ascii_char_variants)] #![feature(ascii_char_variants)]
#![feature(assert_matches)]
#![feature(auto_traits)] #![feature(auto_traits)]
#![feature(cfg_match)] #![feature(cfg_match)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]

View File

@ -10,6 +10,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)] #![doc(rust_logo)]
#![feature(array_windows)] #![feature(array_windows)]
#![feature(assert_matches)]
#![feature(associated_type_defaults)] #![feature(associated_type_defaults)]
#![feature(box_into_inner)] #![feature(box_into_inner)]
#![feature(box_patterns)] #![feature(box_patterns)]
@ -28,6 +29,7 @@
extern crate self as rustc_errors; extern crate self as rustc_errors;
use std::assert_matches::assert_matches;
use std::backtrace::{Backtrace, BacktraceStatus}; use std::backtrace::{Backtrace, BacktraceStatus};
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::Cell; use std::cell::Cell;
@ -1490,7 +1492,7 @@ impl DiagCtxtInner {
// Future breakages aren't emitted if they're `Level::Allow` or // Future breakages aren't emitted if they're `Level::Allow` or
// `Level::Expect`, but they still need to be constructed and // `Level::Expect`, but they still need to be constructed and
// stashed below, so they'll trigger the must_produce_diag check. // stashed below, so they'll trigger the must_produce_diag check.
assert!(matches!(diagnostic.level, Error | Warning | Allow | Expect(_))); assert_matches!(diagnostic.level, Error | Warning | Allow | Expect(_));
self.future_breakage_diagnostics.push(diagnostic.clone()); self.future_breakage_diagnostics.push(diagnostic.clone());
} }

View File

@ -1,3 +1,5 @@
use std::assert_matches::debug_assert_matches;
use rustc_ast::InlineAsmTemplatePiece; use rustc_ast::InlineAsmTemplatePiece;
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_hir::{self as hir, LangItem}; use rustc_hir::{self as hir, LangItem};
@ -457,17 +459,17 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
} }
// Typeck has checked that Const operands are integers. // Typeck has checked that Const operands are integers.
hir::InlineAsmOperand::Const { anon_const } => { hir::InlineAsmOperand::Const { anon_const } => {
debug_assert!(matches!( debug_assert_matches!(
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(), self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
ty::Error(_) | ty::Int(_) | ty::Uint(_) ty::Error(_) | ty::Int(_) | ty::Uint(_)
)); );
} }
// Typeck has checked that SymFn refers to a function. // Typeck has checked that SymFn refers to a function.
hir::InlineAsmOperand::SymFn { anon_const } => { hir::InlineAsmOperand::SymFn { anon_const } => {
debug_assert!(matches!( debug_assert_matches!(
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(), self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
ty::Error(_) | ty::FnDef(..) ty::Error(_) | ty::FnDef(..)
)); );
} }
// AST lowering guarantees that SymStatic points to a static. // AST lowering guarantees that SymStatic points to a static.
hir::InlineAsmOperand::SymStatic { .. } => {} hir::InlineAsmOperand::SymStatic { .. } => {}

View File

@ -1,6 +1,7 @@
//! Check properties that are required by built-in traits and set //! Check properties that are required by built-in traits and set
//! up data structures required by type-checking/codegen. //! up data structures required by type-checking/codegen.
use std::assert_matches::assert_matches;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
@ -129,7 +130,7 @@ fn visit_implementation_of_const_param_ty(
checker: &Checker<'_>, checker: &Checker<'_>,
kind: LangItem, kind: LangItem,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
assert!(matches!(kind, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy)); assert_matches!(kind, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy);
let tcx = checker.tcx; let tcx = checker.tcx;
let header = checker.impl_header; let header = checker.impl_header;

View File

@ -1,3 +1,4 @@
use std::assert_matches::assert_matches;
use std::ops::ControlFlow; use std::ops::ControlFlow;
use hir::intravisit::{self, Visitor}; use hir::intravisit::{self, Visitor};
@ -207,9 +208,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
.. ..
}) => { }) => {
if in_trait { if in_trait {
assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn)) assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
} else { } else {
assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn)) assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
} }
Some(fn_def_id.to_def_id()) Some(fn_def_id.to_def_id())
} }
@ -218,9 +219,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
.. ..
}) => { }) => {
if in_assoc_ty { if in_assoc_ty {
assert!(matches!(tcx.def_kind(parent), DefKind::AssocTy)); assert_matches!(tcx.def_kind(parent), DefKind::AssocTy);
} else { } else {
assert!(matches!(tcx.def_kind(parent), DefKind::TyAlias)); assert_matches!(tcx.def_kind(parent), DefKind::TyAlias);
} }
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent); debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent);
// Opaque types are always nested within another item, and // Opaque types are always nested within another item, and

View File

@ -1,3 +1,5 @@
use std::assert_matches::assert_matches;
use hir::{HirId, Node}; use hir::{HirId, Node};
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir; use rustc_hir as hir;
@ -601,7 +603,7 @@ pub(super) fn implied_predicates_with_filter(
let Some(trait_def_id) = trait_def_id.as_local() else { let Some(trait_def_id) = trait_def_id.as_local() else {
// if `assoc_name` is None, then the query should've been redirected to an // if `assoc_name` is None, then the query should've been redirected to an
// external provider // external provider
assert!(matches!(filter, PredicateFilter::SelfThatDefines(_))); assert_matches!(filter, PredicateFilter::SelfThatDefines(_));
return tcx.explicit_super_predicates_of(trait_def_id); return tcx.explicit_super_predicates_of(trait_def_id);
}; };

View File

@ -1,3 +1,5 @@
use std::assert_matches::debug_assert_matches;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
@ -63,7 +65,7 @@ enum FnKind {
} }
fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> FnKind { fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> FnKind {
debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn)); debug_assert_matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
let parent = tcx.parent(def_id); let parent = tcx.parent(def_id);
match tcx.def_kind(parent) { match tcx.def_kind(parent) {

View File

@ -8,6 +8,8 @@
//! specialization errors. These things can (and probably should) be //! specialization errors. These things can (and probably should) be
//! fixed, but for the moment it's easier to do these checks early. //! fixed, but for the moment it's easier to do these checks early.
use std::assert_matches::debug_assert_matches;
use min_specialization::check_min_specialization; use min_specialization::check_min_specialization;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::codes::*; use rustc_errors::codes::*;
@ -54,7 +56,7 @@ mod min_specialization;
pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
let min_specialization = tcx.features().min_specialization; let min_specialization = tcx.features().min_specialization;
let mut res = Ok(()); let mut res = Ok(());
debug_assert!(matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. })); debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. });
res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id)); res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id));
if min_specialization { if min_specialization {
res = res.and(check_min_specialization(tcx, impl_def_id)); res = res.and(check_min_specialization(tcx, impl_def_id));

View File

@ -62,6 +62,7 @@ This API is completely unstable and subject to change.
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)] #![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(control_flow_enum)] #![feature(control_flow_enum)]
#![feature(if_let_guard)] #![feature(if_let_guard)]
#![feature(iter_intersperse)] #![feature(iter_intersperse)]

View File

@ -1,3 +1,5 @@
use std::assert_matches::assert_matches;
use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt}; use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt};
use rustc_type_ir::outlives::{compute_alias_components_recursive, Component}; use rustc_type_ir::outlives::{compute_alias_components_recursive, Component};
use smallvec::smallvec; use smallvec::smallvec;
@ -181,7 +183,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
&self, &self,
generic_ty: Ty<'tcx>, generic_ty: Ty<'tcx>,
) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> { ) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
assert!(matches!(generic_ty.kind(), ty::Param(_) | ty::Placeholder(_))); assert_matches!(generic_ty.kind(), ty::Param(_) | ty::Placeholder(_));
self.declared_generic_bounds_from_env_for_erased_ty(generic_ty) self.declared_generic_bounds_from_env_for_erased_ty(generic_ty)
} }

View File

@ -18,6 +18,7 @@
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)] #![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(control_flow_enum)] #![feature(control_flow_enum)]
#![feature(extend_one)] #![feature(extend_one)]

View File

@ -1,3 +1,5 @@
use std::assert_matches::assert_matches;
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
use super::Const; use super::Const;
@ -80,7 +82,7 @@ impl<'tcx> Expr<'tcx> {
} }
pub fn binop_args(self) -> (Ty<'tcx>, Ty<'tcx>, Const<'tcx>, Const<'tcx>) { pub fn binop_args(self) -> (Ty<'tcx>, Ty<'tcx>, Const<'tcx>, Const<'tcx>) {
assert!(matches!(self.kind, ExprKind::Binop(_))); assert_matches!(self.kind, ExprKind::Binop(_));
match self.args().as_slice() { match self.args().as_slice() {
[lhs_ty, rhs_ty, lhs_ct, rhs_ct] => ( [lhs_ty, rhs_ty, lhs_ct, rhs_ct] => (
@ -101,7 +103,7 @@ impl<'tcx> Expr<'tcx> {
} }
pub fn unop_args(self) -> (Ty<'tcx>, Const<'tcx>) { pub fn unop_args(self) -> (Ty<'tcx>, Const<'tcx>) {
assert!(matches!(self.kind, ExprKind::UnOp(_))); assert_matches!(self.kind, ExprKind::UnOp(_));
match self.args().as_slice() { match self.args().as_slice() {
[ty, ct] => (ty.expect_ty(), ct.expect_const()), [ty, ct] => (ty.expect_ty(), ct.expect_const()),
@ -125,7 +127,7 @@ impl<'tcx> Expr<'tcx> {
} }
pub fn call_args(self) -> (Ty<'tcx>, Const<'tcx>, impl Iterator<Item = Const<'tcx>>) { pub fn call_args(self) -> (Ty<'tcx>, Const<'tcx>, impl Iterator<Item = Const<'tcx>>) {
assert!(matches!(self.kind, ExprKind::FunctionCall)); assert_matches!(self.kind, ExprKind::FunctionCall);
match self.args().as_slice() { match self.args().as_slice() {
[func_ty, func, rest @ ..] => ( [func_ty, func, rest @ ..] => (
@ -152,7 +154,7 @@ impl<'tcx> Expr<'tcx> {
} }
pub fn cast_args(self) -> (Ty<'tcx>, Const<'tcx>, Ty<'tcx>) { pub fn cast_args(self) -> (Ty<'tcx>, Const<'tcx>, Ty<'tcx>) {
assert!(matches!(self.kind, ExprKind::Cast(_))); assert_matches!(self.kind, ExprKind::Cast(_));
match self.args().as_slice() { match self.args().as_slice() {
[value_ty, value, to_ty] => { [value_ty, value, to_ty] => {

View File

@ -1,3 +1,5 @@
use std::assert_matches::assert_matches;
use rustc_index::bit_set::{BitSet, ChunkedBitSet}; use rustc_index::bit_set::{BitSet, ChunkedBitSet};
use rustc_index::Idx; use rustc_index::Idx;
use rustc_middle::bug; use rustc_middle::bug;
@ -496,7 +498,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> {
}); });
if self.skip_unreachable_unwind.contains(location.block) { if self.skip_unreachable_unwind.contains(location.block) {
let mir::TerminatorKind::Drop { target, unwind, .. } = terminator.kind else { bug!() }; let mir::TerminatorKind::Drop { target, unwind, .. } = terminator.kind else { bug!() };
assert!(matches!(unwind, mir::UnwindAction::Cleanup(_))); assert_matches!(unwind, mir::UnwindAction::Cleanup(_));
TerminatorEdges::Single(target) TerminatorEdges::Single(target)
} else { } else {
terminator.edges() terminator.edges()

View File

@ -1,4 +1,5 @@
// tidy-alphabetical-start // tidy-alphabetical-start
#![feature(assert_matches)]
#![feature(associated_type_defaults)] #![feature(associated_type_defaults)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(exact_size_is_empty)] #![feature(exact_size_is_empty)]

View File

@ -32,6 +32,7 @@
//! Because of that, we can assume that the only way to change the value behind a tracked place is //! Because of that, we can assume that the only way to change the value behind a tracked place is
//! by direct assignment. //! by direct assignment.
use std::assert_matches::assert_matches;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::ops::Range; use std::ops::Range;
@ -54,7 +55,7 @@ use crate::{Analysis, AnalysisDomain, JoinSemiLattice, SwitchIntEdgeEffects};
pub trait ValueAnalysis<'tcx> { pub trait ValueAnalysis<'tcx> {
/// For each place of interest, the analysis tracks a value of the given type. /// For each place of interest, the analysis tracks a value of the given type.
type Value: Clone + JoinSemiLattice + HasBottom + HasTop; type Value: Clone + JoinSemiLattice + HasBottom + HasTop + Debug;
const NAME: &'static str; const NAME: &'static str;
@ -344,7 +345,7 @@ impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper
fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) { fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
// The initial state maps all tracked places of argument projections to and the rest to ⊥. // The initial state maps all tracked places of argument projections to and the rest to ⊥.
assert!(matches!(state, State::Unreachable)); assert_matches!(state, State::Unreachable);
*state = State::new_reachable(); *state = State::new_reachable();
for arg in body.args_iter() { for arg in body.args_iter() {
state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map()); state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map());

View File

@ -468,7 +468,7 @@ impl<'tcx> Validator<'_, 'tcx> {
if let ty::RawPtr(_, _) | ty::FnPtr(..) = lhs_ty.kind() { if let ty::RawPtr(_, _) | ty::FnPtr(..) = lhs_ty.kind() {
// Raw and fn pointer operations are not allowed inside consts and thus not promotable. // Raw and fn pointer operations are not allowed inside consts and thus not promotable.
assert!(matches!( assert_matches!(
op, op,
BinOp::Eq BinOp::Eq
| BinOp::Ne | BinOp::Ne
@ -477,7 +477,7 @@ impl<'tcx> Validator<'_, 'tcx> {
| BinOp::Ge | BinOp::Ge
| BinOp::Gt | BinOp::Gt
| BinOp::Offset | BinOp::Offset
)); );
return Err(Unpromotable); return Err(Unpromotable);
} }

View File

@ -996,7 +996,7 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
/// } /// }
/// ``` /// ```
fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> { fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {
assert!(matches!(self_ty.kind(), ty::FnPtr(..)), "expected fn ptr, found {self_ty}"); assert_matches!(self_ty.kind(), ty::FnPtr(..), "expected fn ptr, found {self_ty}");
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
let Some(sig) = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).no_bound_vars() else { let Some(sig) = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).no_bound_vars() else {
span_bug!(span, "FnPtr::addr with bound vars for `{self_ty}`"); span_bug!(span, "FnPtr::addr with bound vars for `{self_ty}`");

View File

@ -5,6 +5,7 @@
#![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
#![feature(array_windows)] #![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(debug_closure_helpers)] #![feature(debug_closure_helpers)]
#![feature(if_let_guard)] #![feature(if_let_guard)]

View File

@ -10,6 +10,7 @@ mod path;
mod stmt; mod stmt;
mod ty; mod ty;
use std::assert_matches::debug_assert_matches;
use std::ops::Range; use std::ops::Range;
use std::{fmt, mem, slice}; use std::{fmt, mem, slice};
@ -1385,7 +1386,7 @@ impl<'a> Parser<'a> {
// can capture these tokens if necessary. // can capture these tokens if necessary.
self.bump(); self.bump();
if self.token_cursor.stack.len() == target_depth { if self.token_cursor.stack.len() == target_depth {
debug_assert!(matches!(self.token.kind, token::CloseDelim(_))); debug_assert_matches!(self.token.kind, token::CloseDelim(_));
break; break;
} }
} }

View File

@ -1,3 +1,4 @@
use std::assert_matches::assert_matches;
use std::io::prelude::*; use std::io::prelude::*;
use std::iter::Peekable; use std::iter::Peekable;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -1747,7 +1748,7 @@ fn out_of_line_mod() {
.unwrap(); .unwrap();
let ast::ItemKind::Mod(_, mod_kind) = &item.kind else { panic!() }; let ast::ItemKind::Mod(_, mod_kind) = &item.kind else { panic!() };
assert!(matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2)); assert_matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2);
}); });
} }

View File

@ -1,3 +1,5 @@
use std::assert_matches::assert_matches;
use super::*; use super::*;
#[allow(non_snake_case)] #[allow(non_snake_case)]
@ -16,7 +18,7 @@ fn lookup_cdecl() {
#[test] #[test]
fn lookup_baz() { fn lookup_baz() {
let abi = lookup("baz"); let abi = lookup("baz");
assert!(matches!(abi, Err(AbiUnsupported::Unrecognized))) assert_matches!(abi, Err(AbiUnsupported::Unrecognized));
} }
#[test] #[test]

View File

@ -9,6 +9,8 @@
//! coherence right now and was annoying to implement, so I am leaving it //! coherence right now and was annoying to implement, so I am leaving it
//! as is until we start using it for something else. //! as is until we start using it for something else.
use std::assert_matches::assert_matches;
use rustc_ast_ir::try_visit; use rustc_ast_ir::try_visit;
use rustc_ast_ir::visit::VisitorResult; use rustc_ast_ir::visit::VisitorResult;
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
@ -273,10 +275,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
steps.push(step) steps.push(step)
} }
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => { inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
assert!(matches!( assert_matches!(
shallow_certainty.replace(c), shallow_certainty.replace(c),
None | Some(Certainty::Maybe(MaybeCause::Ambiguity)) None | Some(Certainty::Maybe(MaybeCause::Ambiguity))
)); );
} }
inspect::ProbeStep::NestedProbe(ref probe) => { inspect::ProbeStep::NestedProbe(ref probe) => {
match probe.kind { match probe.kind {

View File

@ -1,3 +1,4 @@
use std::assert_matches::assert_matches;
use std::fmt::Debug; use std::fmt::Debug;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -63,7 +64,7 @@ where
E: FromSolverError<'tcx, NextSolverError<'tcx>>, E: FromSolverError<'tcx, NextSolverError<'tcx>>,
{ {
fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> { fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
assert!(matches!(alias_ty.kind(), ty::Alias(..))); assert_matches!(alias_ty.kind(), ty::Alias(..));
let infcx = self.at.infcx; let infcx = self.at.infcx;
let tcx = infcx.tcx; let tcx = infcx.tcx;

View File

@ -1,5 +1,7 @@
//! Miscellaneous type-system utilities that are too small to deserve their own modules. //! Miscellaneous type-system utilities that are too small to deserve their own modules.
use std::assert_matches::assert_matches;
use hir::LangItem; use hir::LangItem;
use rustc_ast::Mutability; use rustc_ast::Mutability;
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
@ -92,7 +94,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
lang_item: LangItem, lang_item: LangItem,
parent_cause: ObligationCause<'tcx>, parent_cause: ObligationCause<'tcx>,
) -> Result<(), ConstParamTyImplementationError<'tcx>> { ) -> Result<(), ConstParamTyImplementationError<'tcx>> {
assert!(matches!(lang_item, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy)); assert_matches!(lang_item, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy);
let inner_tys: Vec<_> = match *self_type.kind() { let inner_tys: Vec<_> = match *self_type.kind() {
// Trivially okay as these types are all: // Trivially okay as these types are all:

View File

@ -249,7 +249,7 @@ pub(super) fn sanity_check_layout<'tcx>(
if let Variants::Multiple { variants, .. } = &layout.variants { if let Variants::Multiple { variants, .. } = &layout.variants {
for variant in variants.iter() { for variant in variants.iter() {
// No nested "multiple". // No nested "multiple".
assert!(matches!(variant.variants, Variants::Single { .. })); assert_matches!(variant.variants, Variants::Single { .. });
// Variants should have the same or a smaller size as the full thing, // Variants should have the same or a smaller size as the full thing,
// and same for alignment. // and same for alignment.
if variant.size > layout.size { if variant.size > layout.size {