summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_ssa/src/mir
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/mir')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs74
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs140
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs76
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
6 files changed, 176 insertions, 130 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index c7617d2e4..dd1ac2c74 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -261,6 +261,9 @@ impl CleanupKind {
}
}
+/// MSVC requires unwinding code to be split to a tree of *funclets*, where each funclet can only
+/// branch to itself or to its parent. Luckily, the code we generates matches this pattern.
+/// Recover that structure in an analyze pass.
pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKind> {
fn discover_masters<'tcx>(
result: &mut IndexVec<mir::BasicBlock, CleanupKind>,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 03d833fbb..978aff511 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -289,16 +289,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx.cleanup_ret(funclet, None);
} else {
let slot = self.get_personality_slot(bx);
- let lp0 = slot.project_field(bx, 0);
- let lp0 = bx.load_operand(lp0).immediate();
- let lp1 = slot.project_field(bx, 1);
- let lp1 = bx.load_operand(lp1).immediate();
+ let exn0 = slot.project_field(bx, 0);
+ let exn0 = bx.load_operand(exn0).immediate();
+ let exn1 = slot.project_field(bx, 1);
+ let exn1 = bx.load_operand(exn1).immediate();
slot.storage_dead(bx);
- let mut lp = bx.const_undef(self.landing_pad_type());
- lp = bx.insert_value(lp, lp0, 0);
- lp = bx.insert_value(lp, lp1, 1);
- bx.resume(lp);
+ bx.resume(exn0, exn1);
}
}
@@ -307,12 +304,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
helper: TerminatorCodegenHelper<'tcx>,
bx: &mut Bx,
discr: &mir::Operand<'tcx>,
- switch_ty: Ty<'tcx>,
targets: &SwitchTargets,
) {
let discr = self.codegen_operand(bx, &discr);
- // `switch_ty` is redundant, sanity-check that.
- assert_eq!(discr.layout.ty, switch_ty);
+ let switch_ty = discr.layout.ty;
let mut target_iter = targets.iter();
if target_iter.len() == 1 {
// If there are two targets (one conditional, one fallback), emit `br` instead of
@@ -642,7 +637,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.set_debug_loc(bx, terminator.source_info);
// Obtain the panic entry point.
- let (fn_abi, llfn) = common::build_langcall(bx, Some(span), LangItem::PanicNoUnwind);
+ let (fn_abi, llfn) = common::build_langcall(bx, Some(span), LangItem::PanicCannotUnwind);
// Codegen the actual panic invoke/call.
let merging_succ = helper.do_call(self, bx, fn_abi, llfn, &[], None, None, &[], false);
@@ -668,12 +663,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
enum AssertIntrinsic {
Inhabited,
ZeroValid,
- UninitValid,
+ MemUninitializedValid,
}
let panic_intrinsic = intrinsic.and_then(|i| match i {
sym::assert_inhabited => Some(AssertIntrinsic::Inhabited),
sym::assert_zero_valid => Some(AssertIntrinsic::ZeroValid),
- sym::assert_uninit_valid => Some(AssertIntrinsic::UninitValid),
+ sym::assert_mem_uninitialized_valid => Some(AssertIntrinsic::MemUninitializedValid),
_ => None,
});
if let Some(intrinsic) = panic_intrinsic {
@@ -684,7 +679,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let do_panic = match intrinsic {
Inhabited => layout.abi.is_uninhabited(),
ZeroValid => !bx.tcx().permits_zero_init(layout),
- UninitValid => !bx.tcx().permits_uninit_init(layout),
+ MemUninitializedValid => !bx.tcx().permits_uninit_init(layout),
};
Some(if do_panic {
let msg_str = with_no_visible_paths!({
@@ -703,11 +698,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
})
});
let msg = bx.const_str(&msg_str);
- let location = self.get_caller_location(bx, source_info).immediate();
// Obtain the panic entry point.
let (fn_abi, llfn) =
- common::build_langcall(bx, Some(source_info.span), LangItem::Panic);
+ common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind);
// Codegen the actual panic invoke/call.
helper.do_call(
@@ -715,7 +709,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx,
fn_abi,
llfn,
- &[msg.0, msg.1, location],
+ &[msg.0, msg.1],
target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)),
cleanup,
&[],
@@ -753,10 +747,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (instance, mut llfn) = match *callee.layout.ty.kind() {
ty::FnDef(def_id, substs) => (
Some(
- ty::Instance::resolve(bx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs)
- .unwrap()
- .unwrap()
- .polymorphize(bx.tcx()),
+ ty::Instance::expect_resolve(
+ bx.tcx(),
+ ty::ParamEnv::reveal_all(),
+ def_id,
+ substs,
+ )
+ .polymorphize(bx.tcx()),
),
None,
),
@@ -1293,8 +1290,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
helper.funclet_br(self, bx, target, mergeable_succ())
}
- mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref targets } => {
- self.codegen_switchint_terminator(helper, bx, discr, switch_ty, targets);
+ mir::TerminatorKind::SwitchInt { ref discr, ref targets } => {
+ self.codegen_switchint_terminator(helper, bx, discr, targets);
MergingSucc::False
}
@@ -1635,24 +1632,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let mut cleanup_bx = Bx::build(self.cx, cleanup_llbb);
let llpersonality = self.cx.eh_personality();
- let llretty = self.landing_pad_type();
- let lp = cleanup_bx.cleanup_landing_pad(llretty, llpersonality);
+ let (exn0, exn1) = cleanup_bx.cleanup_landing_pad(llpersonality);
let slot = self.get_personality_slot(&mut cleanup_bx);
slot.storage_live(&mut cleanup_bx);
- Pair(cleanup_bx.extract_value(lp, 0), cleanup_bx.extract_value(lp, 1))
- .store(&mut cleanup_bx, slot);
+ Pair(exn0, exn1).store(&mut cleanup_bx, slot);
cleanup_bx.br(llbb);
cleanup_llbb
}
}
- fn landing_pad_type(&self) -> Bx::Type {
- let cx = self.cx;
- cx.type_struct(&[cx.type_i8p(), cx.type_i32()], false)
- }
-
fn unreachable_block(&mut self) -> Bx::BasicBlock {
self.unreachable_block.unwrap_or_else(|| {
let llbb = Bx::append_block(self.cx, self.llfn, "unreachable");
@@ -1672,10 +1662,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span));
let llpersonality = self.cx.eh_personality();
- let llretty = self.landing_pad_type();
- bx.cleanup_landing_pad(llretty, llpersonality);
+ bx.cleanup_landing_pad(llpersonality);
- let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicNoUnwind);
+ let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicCannotUnwind);
let fn_ty = bx.fn_decl_backend_type(&fn_abi);
let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &[], None);
@@ -1812,15 +1801,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
match (src.layout.abi, dst.layout.abi) {
(abi::Abi::Scalar(src_scalar), abi::Abi::Scalar(dst_scalar)) => {
// HACK(eddyb) LLVM doesn't like `bitcast`s between pointers and non-pointers.
- if (src_scalar.primitive() == abi::Pointer)
- == (dst_scalar.primitive() == abi::Pointer)
- {
+ let src_is_ptr = src_scalar.primitive() == abi::Pointer;
+ let dst_is_ptr = dst_scalar.primitive() == abi::Pointer;
+ if src_is_ptr == dst_is_ptr {
assert_eq!(src.layout.size, dst.layout.size);
// NOTE(eddyb) the `from_immediate` and `to_immediate_scalar`
// conversions allow handling `bool`s the same as `u8`s.
let src = bx.from_immediate(src.immediate());
- let src_as_dst = bx.bitcast(src, bx.backend_type(dst.layout));
+ // LLVM also doesn't like `bitcast`s between pointers in different address spaces.
+ let src_as_dst = if src_is_ptr {
+ bx.pointercast(src, bx.backend_type(dst.layout))
+ } else {
+ bx.bitcast(src, bx.backend_type(dst.layout))
+ };
Immediate(bx.to_immediate_scalar(src_as_dst, dst_scalar)).store(bx, dst);
return;
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index 53ff3c240..14fe84a14 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -1,3 +1,4 @@
+use crate::errors;
use crate::mir::operand::OperandRef;
use crate::traits::*;
use rustc_middle::mir;
@@ -44,10 +45,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| {
match err {
ErrorHandled::Reported(_) => {
- self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
+ self.cx.tcx().sess.emit_err(errors::ErroneousConstant { span: constant.span });
}
ErrorHandled::TooGeneric => {
- span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err);
+ self.cx
+ .tcx()
+ .sess
+ .diagnostic()
+ .emit_bug(errors::PolymorphicConstantTooGeneric { span: constant.span });
}
}
err
@@ -87,7 +92,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
(llval, c.ty())
})
.unwrap_or_else(|_| {
- bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time");
+ bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span });
// We've errored, so we don't have to produce working code.
let ty = self.monomorphize(ty);
let llty = bx.backend_type(bx.layout_of(ty));
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 99283d3bb..e9bc40c33 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -3,12 +3,12 @@ use rustc_index::vec::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir;
use rustc_middle::ty;
+use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_session::config::DebugInfo;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{BytePos, Span};
-use rustc_target::abi::Abi;
-use rustc_target::abi::Size;
+use rustc_target::abi::{Abi, Size, VariantIdx};
use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef;
@@ -57,9 +57,9 @@ pub struct DebugScope<S, L> {
}
impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
- /// DILocations inherit source file name from the parent DIScope. Due to macro expansions
+ /// DILocations inherit source file name from the parent DIScope. Due to macro expansions
/// it may so happen that the current span belongs to a different file than the DIScope
- /// corresponding to span's containing source scope. If so, we need to create a DIScope
+ /// corresponding to span's containing source scope. If so, we need to create a DIScope
/// "extension" into that file.
pub fn adjust_dbg_scope_for_span<Cx: CodegenMethods<'tcx, DIScope = S, DILocation = L>>(
&self,
@@ -76,6 +76,106 @@ impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
}
}
+trait DebugInfoOffsetLocation<'tcx, Bx> {
+ fn deref(&self, bx: &mut Bx) -> Self;
+ fn layout(&self) -> TyAndLayout<'tcx>;
+ fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self;
+ fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self;
+}
+
+impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
+ for PlaceRef<'tcx, Bx::Value>
+{
+ fn deref(&self, bx: &mut Bx) -> Self {
+ bx.load_operand(*self).deref(bx.cx())
+ }
+
+ fn layout(&self) -> TyAndLayout<'tcx> {
+ self.layout
+ }
+
+ fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self {
+ PlaceRef::project_field(*self, bx, field.index())
+ }
+
+ fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
+ self.project_downcast(bx, variant)
+ }
+}
+
+impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
+ for TyAndLayout<'tcx>
+{
+ fn deref(&self, bx: &mut Bx) -> Self {
+ bx.cx().layout_of(
+ self.ty.builtin_deref(true).unwrap_or_else(|| bug!("cannot deref `{}`", self.ty)).ty,
+ )
+ }
+
+ fn layout(&self) -> TyAndLayout<'tcx> {
+ *self
+ }
+
+ fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self {
+ self.field(bx.cx(), field.index())
+ }
+
+ fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
+ self.for_variant(bx.cx(), variant)
+ }
+}
+
+struct DebugInfoOffset<T> {
+ /// Offset from the `base` used to calculate the debuginfo offset.
+ direct_offset: Size,
+ /// Each offset in this vector indicates one level of indirection from the base or previous
+ /// indirect offset plus a dereference.
+ indirect_offsets: Vec<Size>,
+ /// The final location debuginfo should point to.
+ result: T,
+}
+
+fn calculate_debuginfo_offset<
+ 'a,
+ 'tcx,
+ Bx: BuilderMethods<'a, 'tcx>,
+ L: DebugInfoOffsetLocation<'tcx, Bx>,
+>(
+ bx: &mut Bx,
+ local: mir::Local,
+ var: &PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
+ base: L,
+) -> DebugInfoOffset<L> {
+ let mut direct_offset = Size::ZERO;
+ // FIXME(eddyb) use smallvec here.
+ let mut indirect_offsets = vec![];
+ let mut place = base;
+
+ for elem in &var.projection[..] {
+ match *elem {
+ mir::ProjectionElem::Deref => {
+ indirect_offsets.push(Size::ZERO);
+ place = place.deref(bx);
+ }
+ mir::ProjectionElem::Field(field, _) => {
+ let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
+ *offset += place.layout().fields.offset(field.index());
+ place = place.project_field(bx, field);
+ }
+ mir::ProjectionElem::Downcast(_, variant) => {
+ place = place.downcast(bx, variant);
+ }
+ _ => span_bug!(
+ var.source_info.span,
+ "unsupported var debuginfo place `{:?}`",
+ mir::Place { local, projection: var.projection },
+ ),
+ }
+ }
+
+ DebugInfoOffset { direct_offset, indirect_offsets, result: place }
+}
+
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn set_debug_loc(&self, bx: &mut Bx, source_info: mir::SourceInfo) {
bx.set_span(source_info.span);
@@ -262,33 +362,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let Some(dbg_var) = var.dbg_var else { continue };
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
- let mut direct_offset = Size::ZERO;
- // FIXME(eddyb) use smallvec here.
- let mut indirect_offsets = vec![];
- let mut place = base;
-
- for elem in &var.projection[..] {
- match *elem {
- mir::ProjectionElem::Deref => {
- indirect_offsets.push(Size::ZERO);
- place = bx.load_operand(place).deref(bx.cx());
- }
- mir::ProjectionElem::Field(field, _) => {
- let i = field.index();
- let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
- *offset += place.layout.fields.offset(i);
- place = place.project_field(bx, i);
- }
- mir::ProjectionElem::Downcast(_, variant) => {
- place = place.project_downcast(bx, variant);
- }
- _ => span_bug!(
- var.source_info.span,
- "unsupported var debuginfo place `{:?}`",
- mir::Place { local, projection: var.projection },
- ),
- }
- }
+ let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
+ calculate_debuginfo_offset(bx, local, &var, base.layout);
// When targeting MSVC, create extra allocas for arguments instead of pointing multiple
// dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
@@ -306,6 +381,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|| !matches!(&indirect_offsets[..], [Size::ZERO] | []));
if should_create_individual_allocas {
+ let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
+ calculate_debuginfo_offset(bx, local, &var, base);
+
// Create a variable which will be a pointer to the actual value
let ptr_ty = bx.tcx().mk_ty(ty::RawPtr(ty::TypeAndMut {
mutbl: mir::Mutability::Mut,
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 215edbe02..766dc74cb 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -1,7 +1,9 @@
use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef;
use super::FunctionCx;
-use crate::common::{span_invalid_monomorphization_error, IntPredicate};
+use crate::common::IntPredicate;
+use crate::errors;
+use crate::errors::InvalidMonomorphization;
use crate::glue;
use crate::meth;
use crate::traits::*;
@@ -110,10 +112,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
_ => bug!(),
};
let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable);
- if name == sym::vtable_align {
+ match name {
+ // Size is always <= isize::MAX.
+ sym::vtable_size => {
+ let size_bound = bx.data_layout().ptr_sized_integer().signed_max() as u128;
+ bx.range_metadata(value, WrappingRange { start: 0, end: size_bound });
+ },
// Alignment is always nonzero.
- bx.range_metadata(value, WrappingRange { start: 1, end: !0 });
- };
+ sym::vtable_align => bx.range_metadata(value, WrappingRange { start: 1, end: !0 }),
+ _ => {}
+ }
value
}
sym::pref_align_of
@@ -299,15 +307,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
_ => bug!(),
},
None => {
- span_invalid_monomorphization_error(
- bx.tcx().sess,
- span,
- &format!(
- "invalid monomorphization of `{}` intrinsic: \
- expected basic integer type, found `{}`",
- name, ty
- ),
- );
+ bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty });
return;
}
}
@@ -323,15 +323,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
_ => bug!(),
},
None => {
- span_invalid_monomorphization_error(
- bx.tcx().sess,
- span,
- &format!(
- "invalid monomorphization of `{}` intrinsic: \
- expected basic float type, found `{}`",
- name, arg_tys[0]
- ),
- );
+ bx.tcx().sess.emit_err(InvalidMonomorphization::BasicFloatType { span, name, ty: arg_tys[0] });
return;
}
}
@@ -339,29 +331,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
sym::float_to_int_unchecked => {
if float_type_width(arg_tys[0]).is_none() {
- span_invalid_monomorphization_error(
- bx.tcx().sess,
- span,
- &format!(
- "invalid monomorphization of `float_to_int_unchecked` \
- intrinsic: expected basic float type, \
- found `{}`",
- arg_tys[0]
- ),
- );
+ bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, ty: arg_tys[0] });
return;
}
let Some((_width, signed)) = int_type_width_signed(ret_ty, bx.tcx()) else {
- span_invalid_monomorphization_error(
- bx.tcx().sess,
- span,
- &format!(
- "invalid monomorphization of `float_to_int_unchecked` \
- intrinsic: expected basic integer type, \
- found `{}`",
- ret_ty
- ),
- );
+ bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, ty: ret_ty });
return;
};
if signed {
@@ -396,7 +370,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
use crate::common::{AtomicRmwBinOp, SynchronizationScope};
let Some((instruction, ordering)) = atomic.split_once('_') else {
- bx.sess().fatal("Atomic intrinsic missing memory ordering");
+ bx.sess().emit_fatal(errors::MissingMemoryOrdering);
};
let parse_ordering = |bx: &Bx, s| match s {
@@ -406,25 +380,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
"release" => Release,
"acqrel" => AcquireRelease,
"seqcst" => SequentiallyConsistent,
- _ => bx.sess().fatal("unknown ordering in atomic intrinsic"),
+ _ => bx.sess().emit_fatal(errors::UnknownAtomicOrdering),
};
let invalid_monomorphization = |ty| {
- span_invalid_monomorphization_error(
- bx.tcx().sess,
- span,
- &format!(
- "invalid monomorphization of `{}` intrinsic: \
- expected basic integer type, found `{}`",
- name, ty
- ),
- );
+ bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty });
};
match instruction {
"cxchg" | "cxchgweak" => {
let Some((success, failure)) = ordering.split_once('_') else {
- bx.sess().fatal("Atomic compare-exchange intrinsic missing failure memory ordering");
+ bx.sess().emit_fatal(errors::AtomicCompareExchange);
};
let ty = substs.type_at(0);
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
@@ -523,7 +489,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
"min" => AtomicRmwBinOp::AtomicMin,
"umax" => AtomicRmwBinOp::AtomicUMax,
"umin" => AtomicRmwBinOp::AtomicUMin,
- _ => bx.sess().fatal("unknown atomic operation"),
+ _ => bx.sess().emit_fatal(errors::UnknownAtomicOperation),
};
let ty = substs.type_at(0);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 9ad96f7a4..23196c8cb 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -462,7 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
assert!(bx.cx().tcx().is_static(def_id));
let static_ = bx.get_static(def_id);
let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id));
- OperandRef::from_immediate_or_packed_pair(bx, static_, layout)
+ OperandRef { val: OperandValue::Immediate(static_), layout }
}
mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => {