diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs index fd68d06c93829..44b4664101bc0 100644 --- a/compiler/rustc_abi/src/layout/coroutine.rs +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -186,7 +186,8 @@ pub(super) fn layout< // "a" (`0..b_start`) and "b" (`b_start..`) correspond to // "outer" and "promoted" fields respectively. let b_start = tag_index.plus(1); - let offsets_b = IndexVec::from_raw(offsets.raw.split_off(b_start.index())); + let offsets_b = + IndexVec::from_raw(offsets.mutate(|raw| raw.split_off(b_start.index()))); let offsets_a = offsets; // Disentangle the "a" and "b" components of `in_memory_order` @@ -271,7 +272,7 @@ pub(super) fn layout< // Remove the unused slots to obtain the combined `in_memory_order` // (also see previous comment). - combined_in_memory_order.raw.retain(|&i| i.index() != invalid_field_idx); + combined_in_memory_order.mutate(|raw| raw.retain(|&i| i.index() != invalid_field_idx)); variant.fields = FieldsShape::Arbitrary { offsets: combined_offsets, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 35e16ce78a8a8..f6838d409c42b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -494,8 +494,8 @@ fn index_ast<'tcx>( impl Indexer<'_, '_> { fn insert(&mut self, id: NodeId, node: AstOwner) { let def_id = self.owners[&id].def_id; - self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); - self.index[def_id] = node; + let elem = self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); + *elem = node; } fn make_dummy( diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 467eceea221c8..10583d65163f7 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -862,7 +862,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: { let ty = to_place_and_rval.1.ty(&fx.mir.local_decls, fx.tcx); let layout = fx.layout_of(fx.monomorphize(ty)); - let [data, meta] = &*operands.raw else { + let [data, meta] = &operands.as_slice().raw else { bug!("RawPtr fields: {operands:?}"); }; let data = codegen_operand(fx, data); diff --git a/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs index cecb051172598..dd796cf6bb558 100644 --- a/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs @@ -91,10 +91,12 @@ impl NodeIndex { } impl Idx for NodeIndex { + #[inline] fn new(idx: usize) -> NodeIndex { NodeIndex(idx) } + #[inline] fn index(self) -> usize { self.0 } diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 2fe2a30c36751..31c854fdcc23c 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -95,6 +95,7 @@ impl_dyn_send!( [indexmap::IndexSet where V: DynSend, S: DynSend] [indexmap::IndexMap where K: DynSend, V: DynSend, S: DynSend] [thin_vec::ThinVec where T: DynSend] + [rustc_index::IndexVec where I: rustc_index::Idx, T: DynSend] [smallvec::SmallVec where A: smallvec::Array + DynSend] ); @@ -182,6 +183,7 @@ impl_dyn_sync!( [indexmap::IndexMap where K: DynSync, V: DynSync, S: DynSync] [smallvec::SmallVec where A: smallvec::Array + DynSync] [thin_vec::ThinVec where T: DynSync] + [rustc_index::IndexVec where I: rustc_index::Idx, T: DynSync] ); pub fn assert_dyn_sync() {} diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index c84b06769e081..af110a6f53256 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -1,6 +1,7 @@ // tidy-alphabetical-start #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] #![cfg_attr(all(feature = "nightly", test), feature(test))] +#![cfg_attr(feature = "nightly", feature(dropck_eyepatch))] #![cfg_attr(feature = "nightly", feature(extend_one, step_trait))] // tidy-alphabetical-end diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index 415fe370b702c..a5c9da386fee5 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -254,7 +254,10 @@ impl ToOwned for IndexSlice { } fn clone_into(&self, target: &mut IndexVec) { - self.raw.clone_into(&mut target.raw) + target.mutate(|v| { + // todo this coerces to a slice now, is that correct? + self.raw.clone_into(v) + }); } } diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 13f0dda180be9..7d745c8ce5e6d 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -1,8 +1,10 @@ use std::borrow::{Borrow, BorrowMut}; -use std::hash::Hash; +use std::hash::{Hash, Hasher}; use std::marker::PhantomData; +use std::mem::ManuallyDrop; use std::ops::{Deref, DerefMut, RangeBounds}; -use std::{fmt, slice, vec}; +use std::ptr::NonNull; +use std::{fmt, ptr, slice, vec}; #[cfg(feature = "nightly")] use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -35,24 +37,85 @@ use crate::{Idx, IndexSlice}; /// This allows to index the IndexVec with the new index type. /// /// [`newtype_index!`]: ../macro.newtype_index.html -#[derive(Clone, PartialEq, Eq, Hash)] -#[repr(transparent)] pub struct IndexVec { - pub raw: Vec, + data: NonNull, + len: I, + capacity: I, + _marker: PhantomData, + _marker2: PhantomData, +} + +impl Clone for IndexVec { + fn clone(&self) -> Self { + IndexVec::from_raw(self.as_slice().raw.to_vec()) + } +} + +impl PartialEq for IndexVec { + fn eq(&self, other: &Self) -> bool { + self.as_slice().eq(other.as_slice()) + } +} + +impl Eq for IndexVec {} + +impl Hash for IndexVec { + fn hash(&self, state: &mut H) { + self.as_slice().hash(state); + } +} + +#[cfg(feature = "nightly")] +unsafe impl Drop for IndexVec { + #[inline] + fn drop(&mut self) { + if self.capacity.index() == 0 { + return; + } + std::mem::take(self).into_vec(); + } +} + +#[cfg(not(feature = "nightly"))] +impl Drop for IndexVec { + fn drop(&mut self) { + std::mem::take(self).into_vec(); + } } impl IndexVec { /// Constructs a new, empty `IndexVec`. #[inline] - pub const fn new() -> Self { + pub fn new() -> Self { IndexVec::from_raw(Vec::new()) } /// Constructs a new `IndexVec` from a `Vec`. #[inline] - pub const fn from_raw(raw: Vec) -> Self { - IndexVec { raw, _marker: PhantomData } + pub fn from_raw(raw: Vec) -> Self { + let mut me = ManuallyDrop::new(raw); + + IndexVec { + data: unsafe { NonNull::new_unchecked(me.as_mut_ptr()) }, + len: I::new(me.len()), + capacity: I::new(me.capacity()), + + _marker: PhantomData, + _marker2: PhantomData, + } + } + + #[inline] + pub fn into_vec(self) -> Vec { + let me = ManuallyDrop::new(self); + // fixme this is unsound because we rely on correct Idx trait impls + let len = me.len.index(); + let cap = me.capacity.index(); + unsafe { + core::hint::assert_unchecked(len <= cap); + } + unsafe { Vec::from_raw_parts(me.data.as_ptr(), len, cap) } } #[inline] @@ -98,32 +161,52 @@ impl IndexVec { IndexVec::from_raw((0..n).map(I::new).map(func).collect()) } + #[inline] + pub fn len(&self) -> usize { + self.len.index() + } + #[inline] pub fn as_slice(&self) -> &IndexSlice { - IndexSlice::from_raw(&self.raw) + IndexSlice::from_raw(unsafe { + &*std::ptr::slice_from_raw_parts(self.data.as_ptr(), self.len.index()) + }) } #[inline] pub fn as_mut_slice(&mut self) -> &mut IndexSlice { - IndexSlice::from_raw_mut(&mut self.raw) + IndexSlice::from_raw_mut(unsafe { + &mut *ptr::slice_from_raw_parts_mut(self.data.as_ptr(), self.len.index()) + }) } /// Pushes an element to the array returning the index where it was pushed to. #[inline] pub fn push(&mut self, d: T) -> I { let idx = self.next_index(); - self.raw.push(d); + let len = self.len.index(); + + if len < self.capacity.index() { + unsafe { + // todo copy pasta from Vec::push_mut + let end = self.data.add(len); + ptr::write(end.as_ptr(), d); + self.len = I::new(len + 1); + } + } else { + self.mutate(|vec| vec.push(d)); + } idx } #[inline] pub fn pop(&mut self) -> Option { - self.raw.pop() + self.mutate(|raw| raw.pop()) } #[inline] pub fn into_iter(self) -> vec::IntoIter { - self.raw.into_iter() + self.into_vec().into_iter() } #[inline] @@ -132,35 +215,39 @@ impl IndexVec { ) -> impl DoubleEndedIterator + ExactSizeIterator { // Allow the optimizer to elide the bounds checking when creating each index. let _ = I::new(self.len()); - self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t)) + self.into_iter().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] - pub fn drain>(&mut self, range: R) -> impl Iterator { - self.raw.drain(range) + pub fn drain_into>(&mut self, range: R, target: &mut IndexVec) { + self.mutate(|raw| target.extend(raw.drain(range))) } - #[inline] - pub fn drain_enumerated>( - &mut self, - range: R, - ) -> impl Iterator { - let begin = match range.start_bound() { - std::ops::Bound::Included(i) => *i, - std::ops::Bound::Excluded(i) => i.checked_add(1).unwrap(), - std::ops::Bound::Unbounded => 0, + #[inline(always)] + pub fn mutate) -> U>(&mut self, f: F) -> U { + let sentinel = IndexVec { + data: NonNull::dangling(), + len: I::new(0), + capacity: I::new(0), + _marker: PhantomData, + _marker2: PhantomData, }; - self.raw.drain(range).enumerate().map(move |(n, t)| (I::new(begin + n), t)) + let mut vec = std::mem::replace(self, sentinel).into_vec(); + + // let mut vec = std::mem::take(self).into_vec(); + let v = f(&mut vec); + let _ = std::mem::replace(self, IndexVec::from_raw(vec)); + v } #[inline] pub fn shrink_to_fit(&mut self) { - self.raw.shrink_to_fit() + self.mutate(|vec| vec.shrink_to_fit()); } #[inline] pub fn truncate(&mut self, a: usize) { - self.raw.truncate(a) + self.mutate(|vec| vec.truncate(a)) } /// Grows the index vector so that it contains an entry for @@ -173,7 +260,7 @@ impl IndexVec { pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) -> &mut T { let min_new_len = elem.index() + 1; if self.len() < min_new_len { - self.raw.resize_with(min_new_len, fill_value); + self.mutate(|vec| vec.resize_with(min_new_len, fill_value)); } &mut self[elem] @@ -184,18 +271,18 @@ impl IndexVec { where T: Clone, { - self.raw.resize(new_len, value) + self.mutate(|vec| vec.resize(new_len, value)) } #[inline] pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { let min_new_len = elem.index() + 1; - self.raw.resize_with(min_new_len, fill_value); + self.mutate(|vec| vec.resize_with(min_new_len, fill_value)); } #[inline] pub fn append(&mut self, other: &mut Self) { - self.raw.append(&mut other.raw); + self.mutate(|vec| other.mutate(|other| vec.append(other))); } } @@ -259,19 +346,19 @@ impl BorrowMut> for IndexVec { impl Extend for IndexVec { #[inline] fn extend>(&mut self, iter: J) { - self.raw.extend(iter); + self.mutate(|vec| vec.extend(iter)); } #[inline] #[cfg(feature = "nightly")] fn extend_one(&mut self, item: T) { - self.raw.push(item); + self.mutate(|vec| vec.push(item)); } #[inline] #[cfg(feature = "nightly")] fn extend_reserve(&mut self, additional: usize) { - self.raw.reserve(additional); + self.mutate(|vec| vec.reserve(additional)); } } @@ -291,7 +378,7 @@ impl IntoIterator for IndexVec { #[inline] fn into_iter(self) -> vec::IntoIter { - self.raw.into_iter() + self.into_vec().into_iter() } } @@ -347,5 +434,15 @@ impl> Decodable for IndexVec { // not the phantom data. unsafe impl Send for IndexVec where T: Send {} +#[cfg(target_pointer_width = "64")] +mod size_asserts { + use super::IndexVec; + use crate::static_assert_size; + static_assert_size!(IndexVec, 16); + static_assert_size!(IndexVec, 24); + static_assert_size!(Option>, 16); + static_assert_size!(Option>, 24); +} + #[cfg(test)] mod tests; diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index f3666d5f30817..196ab3a6228ea 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -13,7 +13,7 @@ use rustc_data_structures::stable_hash::{StableHash, StableHasher}; use rustc_data_structures::sync::{AtomicU64, Lock, WorkerLocal}; use rustc_data_structures::unord::UnordMap; use rustc_errors::DiagInner; -use rustc_index::IndexVec; +use rustc_index::{IndexSlice, IndexVec}; use rustc_macros::{Decodable, Encodable}; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_session::Session; @@ -1061,10 +1061,13 @@ impl DepGraph { let _prof_timer = tcx.prof.generic_activity("incr_comp_query_cache_promotion"); let data = self.data.as_ref().unwrap(); - for prev_index in data.colors.values.indices() { - match data.colors.get(prev_index) { + let nodes = data.previous.nodes(); + let colors = data.colors.values.as_slice(); + + for prev_index in colors.indices() { + match DepNodeColorMap::get_from_slice(colors, prev_index) { DepNodeColor::Green(_) => { - let dep_node = data.previous.index_to_node(prev_index); + let dep_node = &nodes[prev_index]; if let Some(promote_fn) = tcx.dep_kind_vtable(dep_node.kind).promote_from_disk_fn { @@ -1370,7 +1373,15 @@ impl DepNodeColorMap { #[inline] pub(super) fn get(&self, index: SerializedDepNodeIndex) -> DepNodeColor { - let value = self.values[index].load(Ordering::Acquire); + Self::get_from_slice(self.values.as_slice(), index) + } + + #[inline] + pub(super) fn get_from_slice( + values: &IndexSlice, + index: SerializedDepNodeIndex, + ) -> DepNodeColor { + let value = values[index].load(Ordering::Acquire); // Green is by far the most common case. Check for that first so we can succeed with a // single comparison. if value < COMPRESSED_RED { diff --git a/compiler/rustc_middle/src/dep_graph/serialized.rs b/compiler/rustc_middle/src/dep_graph/serialized.rs index dbaf29745a8bc..06e91375e1e91 100644 --- a/compiler/rustc_middle/src/dep_graph/serialized.rs +++ b/compiler/rustc_middle/src/dep_graph/serialized.rs @@ -232,6 +232,11 @@ impl SerializedDepGraph { &self.nodes[dep_node_index] } + #[inline] + pub fn nodes(&self) -> &IndexSlice { + self.nodes.as_slice() + } + #[inline] pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option { let kind = self.reverse_index.kinds.get(dep_node.kind.as_usize())?; @@ -340,6 +345,10 @@ impl SerializedDepGraph { let mut edge_list_data = Vec::with_capacity(graph_bytes - node_count * size_of::()); + let node_slice = nodes.as_mut_slice(); + let value_fingerprints_slice = value_fingerprints.as_mut_slice(); + let edge_list_indices_slice = edge_list_indices.as_mut_slice(); + for _ in 0..node_count { // Decode the header for this edge; the header packs together as many of the fixed-size // fields as possible to limit the number of times we update decoder state. @@ -347,12 +356,12 @@ impl SerializedDepGraph { let index = node_header.index(); - let node = &mut nodes[index]; + let node = &mut node_slice[index]; // Make sure there's no duplicate indices in the dep graph. assert!(node_header.node().kind != DepKind::Null && node.kind == DepKind::Null); *node = node_header.node(); - value_fingerprints[index] = node_header.value_fingerprint(); + value_fingerprints_slice[index] = node_header.value_fingerprint(); // If the length of this node's edge list is small, the length is stored in the header. // If it is not, we fall back to another decoder call. @@ -368,7 +377,7 @@ impl SerializedDepGraph { edge_list_data.extend(d.read_raw_bytes(edges_len_bytes)); - edge_list_indices[index] = edges_header; + edge_list_indices_slice[index] = edges_header; } // When we access the edge list data, we do a fixed-size read from the edge list data then diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index e0c1482af72ba..92e104c8b275e 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -444,7 +444,7 @@ impl<'tcx> ProjectedMaybeOwner<'tcx> { } } - pub fn unwrap(&'tcx self) -> &'tcx ProjectedOwnerInfo<'tcx> { + pub fn unwrap<'a>(&'a self) -> &'a ProjectedOwnerInfo<'tcx> { self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner")) } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 1d809a2c84ca0..4874cc777d5a5 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -505,8 +505,8 @@ impl<'tcx> Body<'tcx> { } #[inline] - pub fn drain_vars_and_temps(&mut self) -> impl Iterator> { - self.local_decls.drain(self.arg_count + 1..) + pub fn drain_vars_and_temps_into(&mut self, target: &mut IndexVec>) { + self.local_decls.drain_into(self.arg_count + 1.., target) } /// Returns the source info associated with `location`. diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 1f2ce9e5dc10d..440a9c991c9f2 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -78,7 +78,7 @@ impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck { body.basic_blocks.invalidate_cfg_cache(); } - body.user_type_annotations.raw.clear(); + body.user_type_annotations.mutate(|raw| raw.clear()); for decl in &mut body.local_decls { decl.user_ty = None; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index b30d2bd135546..bf8366e528425 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1831,7 +1831,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { } else if let ty::Adt(adt, args) = ty.kind() && adt.is_struct() && adt.repr().transparent() - && let [single_field] = adt.non_enum_variant().fields.raw.as_slice() + && let [single_field] = &adt.non_enum_variant().fields.as_slice().raw { Some((FieldIdx::ZERO, single_field.ty(self.tcx, args).skip_norm_wip())) } else { diff --git a/compiler/rustc_mir_transform/src/impossible_predicates.rs b/compiler/rustc_mir_transform/src/impossible_predicates.rs index cc216c39b8599..1e9fc5be8ecdb 100644 --- a/compiler/rustc_mir_transform/src/impossible_predicates.rs +++ b/compiler/rustc_mir_transform/src/impossible_predicates.rs @@ -63,11 +63,11 @@ impl<'tcx> MirPass<'tcx> for ImpossiblePredicates { trace!("found unsatisfiable predicates"); // Clear the body to only contain a single `unreachable` statement. let bbs = body.basic_blocks.as_mut(); - bbs.raw.truncate(1); + bbs.truncate(1); bbs[START_BLOCK].statements.clear(); bbs[START_BLOCK].terminator_mut().kind = TerminatorKind::Unreachable; body.var_debug_info.clear(); - body.local_decls.raw.truncate(body.arg_count + 1); + body.local_decls.truncate(body.arg_count + 1); } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index c36b687111c01..2395c2692ee4b 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -997,7 +997,7 @@ fn inline_call<'tcx, I: Inliner<'tcx>>( } // Insert all of the (mapped) parts of the callee body into the caller. - caller_body.local_decls.extend(callee_body.drain_vars_and_temps()); + callee_body.drain_vars_and_temps_into(&mut caller_body.local_decls); caller_body.source_scopes.append(&mut callee_body.source_scopes); // only "full" debug promises any variable-level information diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 14ab4fb0e74eb..4a67766f75847 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -375,28 +375,30 @@ pub(super) fn remove_dead_blocks(body: &mut Body<'_>) { let mut used_index = 0; let mut kept_unreachable = None; let mut deduplicated_unreachable = false; - basic_blocks.raw.retain(|bbdata| { - let orig_bb = BasicBlock::new(orig_index); - if !reachable.contains(orig_bb) { - orig_index += 1; - return false; - } - - let used_bb = BasicBlock::new(used_index); - if should_deduplicate_unreachable(bbdata) { - let kept_unreachable = *kept_unreachable.get_or_insert(used_bb); - if kept_unreachable != used_bb { - replacements[orig_index] = kept_unreachable; - deduplicated_unreachable = true; + basic_blocks.mutate(|raw| { + raw.retain(|bbdata| { + let orig_bb = BasicBlock::new(orig_index); + if !reachable.contains(orig_bb) { orig_index += 1; return false; } - } - replacements[orig_index] = used_bb; - used_index += 1; - orig_index += 1; - true + let used_bb = BasicBlock::new(used_index); + if should_deduplicate_unreachable(bbdata) { + let kept_unreachable = *kept_unreachable.get_or_insert(used_bb); + if kept_unreachable != used_bb { + replacements[orig_index] = kept_unreachable; + deduplicated_unreachable = true; + orig_index += 1; + return false; + } + } + + replacements[orig_index] = used_bb; + used_index += 1; + orig_index += 1; + true + }) }); // If we deduplicated unreachable blocks we erase their source_info as we diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index bbbae98cd49d0..bcb69be785e32 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1035,7 +1035,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.typing_env, adt_def.non_enum_variant().fields[field].ty(self.tcx, args), ); - if let [field] = fields.raw.as_slice() { + if let [field] = &fields.as_slice().raw { let src_ty = field.ty(self.body, self.tcx); if !self.mir_assign_valid_types(src_ty, dest_ty) { self.fail(location, "union field has the wrong type"); @@ -1108,7 +1108,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, "RawPtr should be in runtime MIR only"); } - if let [data_ptr, metadata] = fields.raw.as_slice() { + if let [data_ptr, metadata] = &fields.as_slice().raw { let data_ptr_ty = data_ptr.ty(self.body, self.tcx); let metadata_ty = metadata.ty(self.body, self.tcx); if let ty::RawPtr(in_pointee, in_mut) = data_ptr_ty.kind() { diff --git a/compiler/rustc_monomorphize/src/graph_checks/statics.rs b/compiler/rustc_monomorphize/src/graph_checks/statics.rs index 4a6416843fded..145d49a96b0db 100644 --- a/compiler/rustc_monomorphize/src/graph_checks/statics.rs +++ b/compiler/rustc_monomorphize/src/graph_checks/statics.rs @@ -14,10 +14,12 @@ use crate::diagnostics; struct StaticNodeIdx(usize); impl Idx for StaticNodeIdx { + #[inline] fn new(idx: usize) -> Self { Self(idx) } + #[inline] fn index(self) -> usize { self.0 } diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 8b1401c0609f9..d46eefe3f52ae 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -351,11 +351,11 @@ impl> TypeFoldable for Box<[T]> { impl, Ix: Idx> TypeFoldable for IndexVec { fn try_fold_with>(self, folder: &mut F) -> Result { - self.raw.try_fold_with(folder).map(IndexVec::from_raw) + self.into_vec().try_fold_with(folder).map(IndexVec::from_raw) } fn fold_with>(self, folder: &mut F) -> Self { - IndexVec::from_raw(self.raw.fold_with(folder)) + IndexVec::from_raw(self.into_vec().fold_with(folder)) } } diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 7d9001e73b30d..bf429a2268be7 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -74,10 +74,12 @@ impl ThreadId { } impl Idx for ThreadId { + #[inline] fn new(idx: usize) -> Self { ThreadId(u32::try_from(idx).unwrap()) } + #[inline] fn index(self) -> usize { usize::try_from(self.0).unwrap() }