Fix panic when inlining into clip during the second phase of inlining

During the second phase, anything that involve @children should already
have been processed, so there shouldn't be anything left to inline.
But the children insertion point may be pointing to the wrong location
if some items were moved around (eg because of the `clip`).
So work it around by not accessing the children array at that indax that
might be out of range.

Fixes #7724
This commit is contained in:
Olivier Goffart 2025-02-24 16:40:30 +01:00
parent 27f2d1418c
commit 11accc190a
2 changed files with 33 additions and 8 deletions

View file

@ -131,14 +131,16 @@ fn inline_element(
let children = std::mem::take(&mut elem_mut.children);
let old_count = children.len();
if let Some(insertion_element) = mapping.get(&element_key(insertion_element.clone())) {
if !Rc::ptr_eq(elem, insertion_element) {
debug_assert!(std::rc::Weak::ptr_eq(
&insertion_element.borrow().enclosing_component,
&elem_mut.enclosing_component,
));
insertion_element.borrow_mut().children.splice(index..index, children);
} else {
new_children.splice(index..index, children);
if old_count > 0 {
if !Rc::ptr_eq(elem, insertion_element) {
debug_assert!(std::rc::Weak::ptr_eq(
&insertion_element.borrow().enclosing_component,
&elem_mut.enclosing_component,
));
insertion_element.borrow_mut().children.splice(index..index, children);
} else {
new_children.splice(index..index, children);
}
}
let mut cip = root_component.child_insertion_point.borrow_mut();
if let Some(cip) = cip.as_mut() {

View file

@ -0,0 +1,23 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
// TestCase from #7724
// compilation shouldn't panic
component Hallo {
inner := Rectangle {
clip: true;
@children
Rectangle {}
}
}
component World inherits Hallo {
Rectangle {}
Rectangle {}
Rectangle {}
}
export component Demo {
World { }
}