diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2023-09-06 21:49:16 +0200 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2023-09-06 21:49:16 +0200 |
| commit | f13b184eb3ab0e9ec59c1671b2cfb027d8745ef0 (patch) | |
| tree | 7e4cc92ca86e4ec996f2fd700ef01b794c8ce12d | |
| parent | f29867bd26ec0ed34a8c26cd39fc02df657a13f8 (diff) | |
| download | rust-f13b184eb3ab0e9ec59c1671b2cfb027d8745ef0.tar.gz rust-f13b184eb3ab0e9ec59c1671b2cfb027d8745ef0.zip | |
Implement `write_via_move` intrinsic for mir-eval
| -rw-r--r-- | crates/hir-ty/src/consteval/tests/intrinsics.rs | 18 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/eval/shim.rs | 16 |
2 files changed, 34 insertions, 0 deletions
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 @@ -587,6 +587,24 @@ fn write_bytes() { } #[test] +fn write_via_move() { + check_number( + r#" + extern "rust-intrinsic" { + fn write_via_move<T>(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( r#" 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")); |
