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.rs | 85 |
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), } |