Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22030 from Wilfred/pre-mir-relocation-test
fix: MIR evaluation of sized &T with recursive const fn
| -rw-r--r-- | crates/hir-ty/src/mir/eval.rs | 25 | ||||
| -rw-r--r-- | crates/ide/src/hover/tests.rs | 52 |
2 files changed, 70 insertions, 7 deletions
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 505db1776f..88376f14d1 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -2211,10 +2211,10 @@ impl<'db> Evaluator<'db> { match size { Some((size, _)) => { let addr_usize = from_bytes!(usize, bytes); - mm.insert( - addr_usize, - this.read_memory(Address::from_usize(addr_usize), size)?.into(), - ) + let bytes = + this.read_memory(Address::from_usize(addr_usize), size)?.to_vec(); + mm.insert(addr_usize, bytes.clone().into()); + rec(this, &bytes, t, locals, mm, stack_depth_limit - 1)?; } None => { let mut check_inner = None; @@ -2379,9 +2379,20 @@ impl<'db> Evaluator<'db> { match size { Some(_) => { let current = from_bytes!(usize, self.read_memory(addr, my_size)?); - if let Some(it) = patch_map.get(¤t) { - self.write_memory(addr, &it.to_le_bytes())?; - } + let patched = match patch_map.get(¤t) { + Some(it) => { + self.write_memory(addr, &it.to_le_bytes())?; + *it + } + None => current, + }; + self.patch_addresses( + patch_map, + ty_of_bytes, + Address::from_usize(patched), + t, + locals, + )?; } None => { let current = from_bytes!(usize, self.read_memory(addr, my_size / 2)?); diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 9c53b05539..6f6a4b3e0c 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -11079,6 +11079,58 @@ impl PublicFlags for NoteDialects { } #[test] +fn hover_recursive_const_fn() { + check( + r#" +//- minicore: option +enum Child { + Static { child: &'static MyEnum }, +} + +enum MyEnum { + Unit, + Array(Child), +} + +impl MyEnum { + pub const fn static_array(child: &'static MyEnum) -> Self { + MyEnum::Array(Child::Static { child }) + } +} + +pub trait MyTrait { + const MY_CONST: &'static MyEnum; +} + +impl<T> MyTrait for Option<T> where T: MyTrait { + const MY_CONST: &'static MyEnum = &MyEnum::static_array(T::MY_CONST); +} + +impl MyTrait for () { + const MY_CONST: &'static MyEnum = &MyEnum::Unit; +} + +pub struct Address; + +impl MyTrait for Address { + const MY_CONST$0: &'static MyEnum = (<Option<()> as MyTrait>::MY_CONST); +} + "#, + expect![[r#" + *MY_CONST* + + ```rust + ra_test_fixture::Address + ``` + + ```rust + const MY_CONST: &'static MyEnum = &Array(Static { child: &Unit }) + ``` + "#]], + ); +} + +#[test] fn bounds_from_container_do_not_panic() { check( r#" |