//! Lowers intrinsic calls
-use crate::MirPass;
+use crate::{errors, MirPass};
use rustc_middle::mir::*;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TyCtxt};
}
}
}
+ sym::write_via_move => {
+ let target = target.unwrap();
+ let Ok([ptr, val]) = <[_; 2]>::try_from(std::mem::take(args)) else {
+ span_bug!(
+ terminator.source_info.span,
+ "Wrong number of arguments for write_via_move intrinsic",
+ );
+ };
+ let derefed_place =
+ if let Some(place) = ptr.place() && let Some(local) = place.as_local() {
+ tcx.mk_place_deref(local.into())
+ } else {
+ span_bug!(terminator.source_info.span, "Only passing a local is supported");
+ };
+ block.statements.push(Statement {
+ source_info: terminator.source_info,
+ kind: StatementKind::Assign(Box::new((
+ derefed_place,
+ Rvalue::Use(val),
+ ))),
+ });
+ terminator.kind = TerminatorKind::Goto { target };
+ }
sym::discriminant_value => {
if let (Some(target), Some(arg)) = (*target, args[0].place()) {
let arg = tcx.mk_place_deref(arg);
terminator.kind = TerminatorKind::Goto { target };
}
}
+ sym::offset => {
+ let target = target.unwrap();
+ let Ok([ptr, delta]) = <[_; 2]>::try_from(std::mem::take(args)) else {
+ span_bug!(
+ terminator.source_info.span,
+ "Wrong number of arguments for offset intrinsic",
+ );
+ };
+ block.statements.push(Statement {
+ source_info: terminator.source_info,
+ kind: StatementKind::Assign(Box::new((
+ *destination,
+ Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, delta))),
+ ))),
+ });
+ terminator.kind = TerminatorKind::Goto { target };
+ }
sym::option_payload_ptr => {
if let (Some(target), Some(arg)) = (*target, args[0].place()) {
let ty::RawPtr(ty::TypeAndMut { ty: dest_ty, .. }) =
terminator.kind = TerminatorKind::Goto { target };
}
}
- sym::transmute => {
+ sym::transmute | sym::transmute_unchecked => {
let dst_ty = destination.ty(local_decls, tcx).ty;
let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else {
span_bug!(
}
fn validate_simd_shuffle<'tcx>(tcx: TyCtxt<'tcx>, args: &[Operand<'tcx>], span: Span) {
- match &args[2] {
- Operand::Constant(_) => {} // all good
- _ => {
- let msg = "last argument of `simd_shuffle` is required to be a `const` item";
- tcx.sess.span_err(span, msg);
- }
+ if !matches!(args[2], Operand::Constant(_)) {
+ tcx.sess.emit_err(errors::SimdShuffleLastConst { span });
}
}