From f13b184eb3ab0e9ec59c1671b2cfb027d8745ef0 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 6 Sep 2023 21:49:16 +0200 Subject: [PATCH] Implement `write_via_move` intrinsic for mir-eval --- .../hir-ty/src/consteval/tests/intrinsics.rs | 18 ++++++++++++++++++ crates/hir-ty/src/mir/eval/shim.rs | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/crates/hir-ty/src/consteval/tests/intrinsics.rs b/crates/hir-ty/src/consteval/tests/intrinsics.rs index cc3a43fd9ae..44a4ac27af0 100644 --- a/crates/hir-ty/src/consteval/tests/intrinsics.rs +++ b/crates/hir-ty/src/consteval/tests/intrinsics.rs @@ -586,6 +586,24 @@ fn write_bytes() { ); } +#[test] +fn write_via_move() { + check_number( + r#" + extern "rust-intrinsic" { + fn write_via_move(ptr: *mut T, value: T); + } + + const GOAL: i32 = unsafe { + let mut x = 2; + write_via_move(&mut x, 100); + x + }; + "#, + 100, + ); +} + #[test] fn copy() { check_number( diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index 18396638940..803ef631f1e 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -1200,6 +1200,22 @@ impl Evaluator<'_> { let addr = Address::from_bytes(arg.interval.get(self)?)?; destination.write_from_interval(self, Interval { addr, size: destination.size }) } + "write_via_move" => { + let [ptr, val] = args else { + return Err(MirEvalError::TypeError("write_via_move args are not provided")); + }; + let dst = Address::from_bytes(ptr.get(self)?)?; + let Some(ty) = + generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner)) + else { + return Err(MirEvalError::TypeError( + "write_via_copy generic arg is not provided", + )); + }; + let size = self.size_of_sized(ty, locals, "write_via_move ptr type")?; + Interval { addr: dst, size }.write_from_interval(self, val.interval)?; + Ok(()) + } "write_bytes" => { let [dst, val, count] = args else { return Err(MirEvalError::TypeError("write_bytes args are not provided"));