rustc_codegen_ssa/mir/
locals.rs1use std::ops::{Index, IndexMut};
6
7use rustc_index::IndexVec;
8use rustc_middle::mir;
9use rustc_middle::ty::print::with_no_trimmed_paths;
10use tracing::{debug, warn};
11
12use crate::mir::{FunctionCx, LocalRef};
13use crate::traits::BuilderMethods;
14
15pub(super) struct Locals<'tcx, V> {
16 values: IndexVec<mir::Local, LocalRef<'tcx, V>>,
17}
18
19impl<'tcx, V> Index<mir::Local> for Locals<'tcx, V> {
20 type Output = LocalRef<'tcx, V>;
21 #[inline]
22 fn index(&self, index: mir::Local) -> &LocalRef<'tcx, V> {
23 &self.values[index]
24 }
25}
26
27impl<'tcx, V, Idx: ?Sized> !IndexMut<Idx> for Locals<'tcx, V> {}
29
30impl<'tcx, V> Locals<'tcx, V> {
31 pub(super) fn empty() -> Locals<'tcx, V> {
32 Locals { values: IndexVec::default() }
33 }
34
35 pub(super) fn indices(&self) -> impl DoubleEndedIterator<Item = mir::Local> + Clone + 'tcx {
36 self.values.indices()
37 }
38}
39
40impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
41 pub(super) fn initialize_locals(&mut self, values: Vec<LocalRef<'tcx, Bx::Value>>) {
42 assert!(self.locals.values.is_empty());
43 self.locals.values = IndexVec::from_raw(values);
44 for (local, value) in self.locals.values.iter_enumerated() {
46 match value {
47 LocalRef::Place(_) | LocalRef::UnsizedPlace(_) | LocalRef::PendingOperand => (),
48 LocalRef::Operand(op) => {
49 let expected_ty = self.monomorphize(self.mir.local_decls[local].ty);
50 if expected_ty != op.layout.ty {
51 warn!(
52 "Unexpected initial operand type:\nexpected {expected_ty:?},\nfound {:?}.\n\
53 See <https://github.com/rust-lang/rust/issues/114858>.",
54 op.layout.ty
55 );
56 }
57 }
58 }
59 }
60 }
61
62 pub(super) fn overwrite_local(
63 &mut self,
64 local: mir::Local,
65 mut value: LocalRef<'tcx, Bx::Value>,
66 ) {
67 match value {
68 LocalRef::Place(_) | LocalRef::UnsizedPlace(_) | LocalRef::PendingOperand => (),
69 LocalRef::Operand(ref mut op) => {
70 let local_ty = self.monomorphize(self.mir.local_decls[local].ty);
71 if local_ty != op.layout.ty {
72 debug!("updating type of operand due to subtyping");
74 with_no_trimmed_paths!(debug!(?op.layout.ty));
75 with_no_trimmed_paths!(debug!(?local_ty));
76 op.layout.ty = local_ty;
77 }
78 }
79 };
80
81 self.locals.values[local] = value;
82 }
83}