diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/lint.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/allocation.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/error.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/mod.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/pointer.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/value.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 44 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/pretty.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/syntax.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/visit.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/cast.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts/int.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 6 | 
13 files changed, 102 insertions, 55 deletions
| diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 215d8decf2a..32c0a7e2605 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -3,7 +3,8 @@ use std::cmp; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::{ - Diagnostic, DiagnosticBuilder, DiagnosticId, EmissionGuarantee, ErrorGuaranteed, MultiSpan, + Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee, + ErrorGuaranteed, MultiSpan, }; use rustc_hir::HirId; use rustc_index::vec::IndexVec; @@ -231,7 +232,7 @@ pub struct LintDiagnosticBuilder<'a, G: EmissionGuarantee>(DiagnosticBuilder<'a, impl<'a, G: EmissionGuarantee> LintDiagnosticBuilder<'a, G> { /// Return the inner `DiagnosticBuilder`, first setting the primary message to `msg`. - pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a, G> { + pub fn build(mut self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'a, G> { self.0.set_primary_message(msg); self.0.set_is_lint(); self.0 diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 1e2b53040d2..1bbd71c3f1f 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -160,12 +160,18 @@ impl AllocError { } /// The information that makes up a memory access: offset and size. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone)] pub struct AllocRange { pub start: Size, pub size: Size, } +impl fmt::Debug for AllocRange { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "[{:#x}..{:#x}]", self.start.bytes(), self.end().bytes()) + } +} + /// Free-starting constructor for less syntactic overhead. #[inline(always)] pub fn alloc_range(start: Size, size: Size) -> AllocRange { diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index a33a2921f57..f30769248c0 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -334,36 +334,30 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> { p, ), PointerUseAfterFree(a) => { - write!(f, "pointer to {} was dereferenced after this allocation got freed", a) + write!(f, "pointer to {a:?} was dereferenced after this allocation got freed") } PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size: Size::ZERO, msg } => { write!( f, - "{}{alloc_id} has size {alloc_size}, so pointer at offset {ptr_offset} is out-of-bounds", - msg, - alloc_id = alloc_id, + "{msg}{alloc_id:?} has size {alloc_size}, so pointer at offset {ptr_offset} is out-of-bounds", alloc_size = alloc_size.bytes(), - ptr_offset = ptr_offset, ) } PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => write!( f, - "{}{alloc_id} has size {alloc_size}, so pointer to {ptr_size} byte{ptr_size_p} starting at offset {ptr_offset} is out-of-bounds", - msg, - alloc_id = alloc_id, + "{msg}{alloc_id:?} has size {alloc_size}, so pointer to {ptr_size} byte{ptr_size_p} starting at offset {ptr_offset} is out-of-bounds", alloc_size = alloc_size.bytes(), ptr_size = ptr_size.bytes(), ptr_size_p = pluralize!(ptr_size.bytes()), - ptr_offset = ptr_offset, ), DanglingIntPointer(0, CheckInAllocMsg::InboundsTest) => { write!(f, "null pointer is not a valid pointer for this operation") } DanglingIntPointer(0, msg) => { - write!(f, "{}null pointer is not a valid pointer", msg) + write!(f, "{msg}null pointer is not a valid pointer") } DanglingIntPointer(i, msg) => { - write!(f, "{}0x{:x} is not a valid pointer", msg, i) + write!(f, "{msg}{i:#x} is not a valid pointer") } AlignmentCheckFailed { required, has } => write!( f, @@ -371,8 +365,8 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> { has.bytes(), required.bytes() ), - WriteToReadOnly(a) => write!(f, "writing to {} which is read-only", a), - DerefFunctionPointer(a) => write!(f, "accessing {} which contains a function", a), + WriteToReadOnly(a) => write!(f, "writing to {a:?} which is read-only"), + DerefFunctionPointer(a) => write!(f, "accessing {a:?} which contains a function"), ValidationFailure { path: None, msg } => { write!(f, "constructing invalid value: {}", msg) } diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 8733a85ef3f..698024b2330 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -190,11 +190,7 @@ impl fmt::Debug for AllocId { } } -impl fmt::Display for AllocId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self, f) - } -} +// No "Display" since AllocIds are not usually user-visible. #[derive(TyDecodable, TyEncodable)] enum AllocDiscriminant { @@ -470,7 +466,7 @@ impl<'tcx> TyCtxt<'tcx> { return alloc_id; } let id = alloc_map.reserve(); - debug!("creating alloc {:?} with id {}", alloc, id); + debug!("creating alloc {alloc:?} with id {id:?}"); alloc_map.alloc_map.insert(id, alloc.clone()); alloc_map.dedup.insert(alloc, id); id @@ -538,7 +534,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn global_alloc(self, id: AllocId) -> GlobalAlloc<'tcx> { match self.get_global_alloc(id) { Some(alloc) => alloc, - None => bug!("could not find allocation for {}", id), + None => bug!("could not find allocation for {id:?}"), } } @@ -546,7 +542,7 @@ impl<'tcx> TyCtxt<'tcx> { /// call this function twice, even with the same `Allocation` will ICE the compiler. pub fn set_alloc_id_memory(self, id: AllocId, mem: ConstAllocation<'tcx>) { if let Some(old) = self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Memory(mem)) { - bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old); + bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}"); } } diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index 26da93b9dce..81d744107fd 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -144,7 +144,7 @@ impl Provenance for AllocId { } // Print offset only if it is non-zero. if ptr.offset.bytes() > 0 { - write!(f, "+0x{:x}", ptr.offset.bytes())?; + write!(f, "+{:#x}", ptr.offset.bytes())?; } Ok(()) } @@ -181,7 +181,7 @@ impl<Tag: Provenance> fmt::Debug for Pointer<Option<Tag>> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.provenance { Some(tag) => Provenance::fmt(&Pointer::new(tag, self.offset), f), - None => write!(f, "0x{:x}", self.offset.bytes()), + None => write!(f, "{:#x}", self.offset.bytes()), } } } diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index e80918d5e5d..8ecbb5ab0b3 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -167,7 +167,7 @@ impl<Tag: Provenance> fmt::LowerHex for Scalar<Tag> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Scalar::Ptr(ptr, _size) => write!(f, "pointer to {:?}", ptr), - Scalar::Int(int) => write!(f, "0x{:x}", int), + Scalar::Int(int) => write!(f, "{:#x}", int), } } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index ad33a54e0a2..11d20b886c9 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -357,10 +357,7 @@ impl<'tcx> Body<'tcx> { // // FIXME: Use a finer-grained API for this, so only transformations that alter terminators // invalidate the caches. - self.predecessor_cache.invalidate(); - self.switch_source_cache.invalidate(); - self.is_cyclic.invalidate(); - self.postorder_cache.invalidate(); + self.invalidate_cfg_cache(); &mut self.basic_blocks } @@ -368,10 +365,7 @@ impl<'tcx> Body<'tcx> { pub fn basic_blocks_and_local_decls_mut( &mut self, ) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) { - self.predecessor_cache.invalidate(); - self.switch_source_cache.invalidate(); - self.is_cyclic.invalidate(); - self.postorder_cache.invalidate(); + self.invalidate_cfg_cache(); (&mut self.basic_blocks, &mut self.local_decls) } @@ -383,11 +377,43 @@ impl<'tcx> Body<'tcx> { &mut LocalDecls<'tcx>, &mut Vec<VarDebugInfo<'tcx>>, ) { + self.invalidate_cfg_cache(); + (&mut self.basic_blocks, &mut self.local_decls, &mut self.var_debug_info) + } + + /// Get mutable access to parts of the Body without invalidating the CFG cache. + /// + /// By calling this method instead of eg [`Body::basic_blocks_mut`], you promise not to change + /// the CFG. This means that + /// + /// 1) The number of basic blocks remains unchanged + /// 2) The set of successors of each terminator remains unchanged. + /// 3) For each `TerminatorKind::SwitchInt`, the `targets` remains the same and the terminator + /// kind is not changed. + /// + /// If any of these conditions cannot be upheld, you should call [`Body::invalidate_cfg_cache`]. + #[inline] + pub fn basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate( + &mut self, + ) -> ( + &mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, + &mut LocalDecls<'tcx>, + &mut Vec<VarDebugInfo<'tcx>>, + ) { + (&mut self.basic_blocks, &mut self.local_decls, &mut self.var_debug_info) + } + + /// Invalidates cached information about the CFG. + /// + /// You will only ever need this if you have also called + /// [`Body::basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate`]. All other methods + /// that allow you to mutate the body also call this method themselves, thereby avoiding any + /// risk of accidentaly cache invalidation. + pub fn invalidate_cfg_cache(&mut self) { self.predecessor_cache.invalidate(); self.switch_source_cache.invalidate(); self.is_cyclic.invalidate(); self.postorder_cache.invalidate(); - (&mut self.basic_blocks, &mut self.local_decls, &mut self.var_debug_info) } /// Returns `true` if a cycle exists in the control-flow graph that is reachable from the diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 462c0ada3cf..24c6cd91d0a 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -716,12 +716,12 @@ pub fn write_allocations<'tcx>( } write!(w, "{}", display_allocation(tcx, alloc.inner())) }; - write!(w, "\n{}", id)?; + write!(w, "\n{id:?}")?; match tcx.get_global_alloc(id) { // This can't really happen unless there are bugs, but it doesn't cost us anything to // gracefully handle it and allow buggy rustc to be debugged via allocation printing. None => write!(w, " (deallocated)")?, - Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {})", inst)?, + Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {inst})")?, Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => { match tcx.eval_static_initializer(did) { Ok(alloc) => { diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index f8ee59f306f..3b7eb820df8 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -311,6 +311,7 @@ pub enum StatementKind<'tcx> { /// Describes what kind of retag is to be performed. #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, Hash, HashStable)] +#[rustc_pass_by_value] pub enum RetagKind { /// The initial retag when entering a function. FnEntry, @@ -990,11 +991,19 @@ pub enum Rvalue<'tcx> { /// matching types and return a value of that type. BinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>), - /// Same as `BinaryOp`, but yields `(T, bool)` instead of `T`. In addition to performing the - /// same computation as the matching `BinaryOp`, checks if the infinite precison result would be - /// unequal to the actual result and sets the `bool` if this is the case. + /// Same as `BinaryOp`, but yields `(T, bool)` with a `bool` indicating an error condition. /// - /// This only supports addition, subtraction, multiplication, and shift operations on integers. + /// When overflow checking is disabled, the error condition is false. Otherwise, the error + /// condition is determined as described below. + /// + /// For addition, subtraction, and multiplication on integers the error condition is set when + /// the infinite precision result would be unequal to the actual result. + /// + /// For shift operations on integers the error condition is set when the value of right-hand + /// side is greater than or equal to the number of bits in the type of the left-hand side, or + /// when the value of right-hand side is negative. + /// + /// Other combinations of types and operators are unsupported. CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>), /// Computes a value as described by the operation. diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 9285246eb79..d1477f9e2ae 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -147,7 +147,7 @@ macro_rules! make_mir_visitor { fn visit_ascribe_user_ty( &mut self, place: & $($mutability)? Place<'tcx>, - variance: & $($mutability)? ty::Variance, + variance: $(& $mutability)? ty::Variance, user_ty: & $($mutability)? UserTypeProjection, location: Location, ) { @@ -164,7 +164,7 @@ macro_rules! make_mir_visitor { fn visit_retag( &mut self, - kind: & $($mutability)? RetagKind, + kind: $(& $mutability)? RetagKind, place: & $($mutability)? Place<'tcx>, location: Location, ) { @@ -425,7 +425,7 @@ macro_rules! make_mir_visitor { self.visit_source_info(source_info); match kind { StatementKind::Assign( - box(ref $($mutability)? place, ref $($mutability)? rvalue) + box (place, rvalue) ) => { self.visit_assign(place, rvalue, location); } @@ -465,13 +465,13 @@ macro_rules! make_mir_visitor { ); } StatementKind::Retag(kind, place) => { - self.visit_retag(kind, place, location); + self.visit_retag($(& $mutability)? *kind, place, location); } StatementKind::AscribeUserType( - box(ref $($mutability)? place, ref $($mutability)? user_ty), + box (place, user_ty), variance ) => { - self.visit_ascribe_user_ty(place, variance, user_ty, location); + self.visit_ascribe_user_ty(place, $(& $mutability)? *variance, user_ty, location); } StatementKind::Coverage(coverage) => { self.visit_coverage( @@ -480,9 +480,9 @@ macro_rules! make_mir_visitor { ) } StatementKind::CopyNonOverlapping(box crate::mir::CopyNonOverlapping{ - ref $($mutability)? src, - ref $($mutability)? dst, - ref $($mutability)? count, + src, + dst, + count, }) => { self.visit_operand(src, location); self.visit_operand(dst, location); @@ -517,8 +517,7 @@ macro_rules! make_mir_visitor { TerminatorKind::GeneratorDrop | TerminatorKind::Unreachable | TerminatorKind::FalseEdge { .. } | - TerminatorKind::FalseUnwind { .. } => { - } + TerminatorKind::FalseUnwind { .. } => {} TerminatorKind::Return => { // `return` logically moves from the return place `_0`. Note that the place @@ -830,7 +829,7 @@ macro_rules! make_mir_visitor { fn super_ascribe_user_ty(&mut self, place: & $($mutability)? Place<'tcx>, - _variance: & $($mutability)? ty::Variance, + _variance: $(& $mutability)? ty::Variance, user_ty: & $($mutability)? UserTypeProjection, location: Location) { self.visit_place( @@ -847,7 +846,7 @@ macro_rules! make_mir_visitor { } fn super_retag(&mut self, - _kind: & $($mutability)? RetagKind, + _kind: $(& $mutability)? RetagKind, place: & $($mutability)? Place<'tcx>, location: Location) { self.visit_place( diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index 20a6af5f6c1..c4b743dd467 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -15,6 +15,12 @@ pub enum IntTy { Char, } +impl IntTy { + pub fn is_signed(self) -> bool { + matches!(self, Self::I) + } +} + // Valid types for the result of a non-coercion cast #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum CastTy<'tcx> { diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 51e51a63fd0..c7c2692281e 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -452,6 +452,10 @@ impl fmt::Debug for ScalarInt { impl fmt::LowerHex for ScalarInt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.check_data(); + if f.alternate() { + // Like regular ints, alternate flag adds leading `0x`. + write!(f, "0x")?; + } // Format as hex number wide enough to fit any value of the given `size`. // So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014". // Using a block `{self.data}` here to force a copy instead of using `self.data` diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f73eca5bf61..c71905b4aca 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -611,6 +611,12 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> { } } +impl rustc_errors::IntoDiagnosticArg for Predicate<'_> { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string())) + } +} + #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable)] pub enum PredicateKind<'tcx> { | 
