diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs index 98384c4749..9199663be1 100644 --- a/crates/hir-ty/src/consteval/tests.rs +++ b/crates/hir-ty/src/consteval/tests.rs @@ -2825,3 +2825,30 @@ fn unsized_local() { |e| matches!(e, ConstEvalError::MirLowerError(MirLowerError::UnsizedTemporary(_))), ); } + +#[test] +fn recursive_adt() { + check_answer( + r#" + //- minicore: coerce_unsized, index, slice + pub enum TagTree { + Leaf, + Choice(&'static [TagTree]), + } + const GOAL: TagTree = { + const TAG_TREE: TagTree = TagTree::Choice(&[ + { + const VARIANT_TAG_TREE: TagTree = TagTree::Choice( + &[ + TagTree::Leaf, + ], + ); + VARIANT_TAG_TREE + }, + ]); + TAG_TREE + }; + "#, + |b, _| assert_eq!(b[0] % 8, 0), + ); +} diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index fd98141af6..90b8092b4b 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -1710,7 +1710,14 @@ impl Evaluator<'_> { } ConstScalar::Unknown => not_supported!("evaluating unknown const"), }; - let patch_map = memory_map.transform_addresses(|b, align| { + let patch_map = memory_map.transform_addresses(|b, mut align| { + // Prevent recursive addresses is adts and slices + match ((&b[..b.len() / 2]).try_into(), HEAP_OFFSET.checked_add(align)) { + (Ok(arr), Some(new_addr)) if usize::from_le_bytes(arr) == new_addr => { + align *= 2; + } + _ => (), + }; let addr = self.heap_allocate(b.len(), align)?; self.write_memory(addr, b)?; Ok(addr.to_usize())