Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir/eval/shim.rs')
-rw-r--r--crates/hir-ty/src/mir/eval/shim.rs85
1 files changed, 83 insertions, 2 deletions
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs
index 7a6cbb8ca3..d2a74f20a5 100644
--- a/crates/hir-ty/src/mir/eval/shim.rs
+++ b/crates/hir-ty/src/mir/eval/shim.rs
@@ -1062,12 +1062,15 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
let ans = ptr + offset * size;
destination.write_from_bytes(self, &ans.to_le_bytes()[0..destination.size])
}
- "assert_inhabited" | "assert_zero_valid" | "assert_uninit_valid" | "assume" => {
+ "assert_inhabited"
+ | "assert_zero_valid"
+ | "assert_uninit_valid"
+ | "assert_mem_uninitialized_valid" => {
// FIXME: We should actually implement these checks
Ok(())
}
"forget" => {
- // We don't call any drop glue yet, so there is nothing here
+ // FIXME
Ok(())
}
"transmute" | "transmute_unchecked" => {
@@ -1334,6 +1337,84 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
.write_from_interval(self, meta.interval)?;
Ok(())
}
+ "fabs" => {
+ let [arg] = args else {
+ return Err(MirEvalError::InternalError(
+ "fabs intrinsic signature doesn't match fn (T) -> T".into(),
+ ));
+ };
+ let mut bytes = arg.get(self)?.to_vec();
+ if let Some(sign_byte) = bytes.last_mut() {
+ *sign_byte &= 0x7f;
+ }
+ destination.write_from_bytes(self, &bytes)
+ }
+ "unreachable" => {
+ return Err(MirEvalError::UndefinedBehavior(
+ "`unreachable` intrinsic executed".to_owned(),
+ ));
+ }
+ "const_allocate" => {
+ let [size, align] = args else {
+ return Err(MirEvalError::InternalError(
+ "const_allocate args are not provided".into(),
+ ));
+ };
+ let size = from_bytes!(usize, size.get(self)?);
+ let align = from_bytes!(usize, align.get(self)?);
+ let result = self.heap_allocate(size, align)?;
+ destination.write_from_bytes(self, &result.to_bytes())
+ }
+ "const_deallocate" => Ok(()),
+ "caller_location" => {
+ let Some(location_adt) = self.lang_items().PanicLocation else {
+ not_supported!("`caller_location` requires the `panic_location` lang item");
+ };
+ let location_ty = self.db.ty(location_adt.into()).skip_binder();
+ let TyKind::Adt(_, subst) = location_ty.kind() else {
+ return Err(MirEvalError::InternalError(
+ "`panic_location` lang item is not an ADT".into(),
+ ));
+ };
+ let layout = self.layout(location_ty)?;
+ let (file, line, col) = self.caller_location_fields(locals.body.owner, span);
+ let file_len = file.len();
+ let file_addr = self.heap_allocate(file_len + 1, 1)?;
+ self.write_memory(file_addr, file.as_bytes())?;
+ let ptr_size = self.ptr_size();
+ let field_types = self.db.field_types(location_adt.into());
+ let mut line_col = [line, col].into_iter();
+ let mut fields = Vec::with_capacity(field_types.iter().count());
+ for (_, field) in field_types.iter() {
+ let field_ty = field.ty().instantiate(self.interner(), subst).skip_norm_wip();
+ let bytes =
+ if matches!(field_ty.kind(), TyKind::Uint(rustc_type_ir::UintTy::U32)) {
+ line_col.next().unwrap_or(0).to_le_bytes().to_vec()
+ } else {
+ let size =
+ self.size_of_sized(field_ty, locals, "caller_location field")?;
+ if size == ptr_size * 2 {
+ // The string slice pointing at the file name: (data pointer, length).
+ let mut bytes = file_addr.to_bytes()[..ptr_size].to_vec();
+ bytes.extend_from_slice(&file_len.to_le_bytes()[..ptr_size]);
+ bytes
+ } else {
+ vec![0; size]
+ }
+ };
+ fields.push(IntervalOrOwned::Owned(bytes));
+ }
+ let location = self.construct_with_layout(
+ layout.size.bytes_usize(),
+ &layout,
+ None,
+ fields.into_iter(),
+ )?;
+ let location_addr =
+ self.heap_allocate(layout.size.bytes_usize(), layout.align.bytes() as usize)?;
+ self.write_memory(location_addr, &location)?;
+ destination.write_from_bytes(self, &location_addr.to_bytes()[..ptr_size])
+ }
_ if needs_override => not_supported!("intrinsic {name} is not implemented"),
_ => return Ok(false),
}