Compiler: fix lookup of the model not seeing that the element is being repeated

The problem is that we were taking the whole `repeated` field and as a
result we wouldn't see that the element was being repeated and that we
shouldn't have to lookup id within it

Fix #4683
This commit is contained in:
Olivier Goffart 2024-02-26 11:12:06 +01:00
parent 35e3456e26
commit 11e8070726
3 changed files with 37 additions and 6 deletions

View file

@ -2036,11 +2036,14 @@ pub fn visit_element_expressions(
}
}
let repeated = std::mem::take(&mut elem.borrow_mut().repeated);
if let Some(mut r) = repeated {
let is_conditional_element = r.is_conditional_element;
vis(&mut r.model, None, &|| if is_conditional_element { Type::Bool } else { Type::Model });
elem.borrow_mut().repeated = Some(r)
let repeated = elem
.borrow_mut()
.repeated
.as_mut()
.map(|r| (std::mem::take(&mut r.model), r.is_conditional_element));
if let Some((mut model, is_cond)) = repeated {
vis(&mut model, None, &|| if is_cond { Type::Bool } else { Type::Model });
elem.borrow_mut().repeated.as_mut().unwrap().model = model;
}
visit_element_expressions_simple(elem, &mut vis);
let mut states = std::mem::take(&mut elem.borrow_mut().states);

View file

@ -89,7 +89,10 @@ pub fn resolve_expressions(
visit_element_expressions(elem, |expr, property_name, property_type| {
if is_repeated {
// The first expression is always the model and it needs to be resolved with the parent scope
debug_assert!(elem.borrow().repeated.as_ref().is_none()); // should be none because it is taken by the visit_element_expressions function
debug_assert!(matches!(
elem.borrow().repeated.as_ref().unwrap().model,
Expression::Invalid
)); // should be Invalid because it is taken by the visit_element_expressions function
resolve_expression(
expr,
property_name,

View file

@ -67,4 +67,29 @@ export Hello := Rectangle {
text: pp.b; // Ok! pp will have a, b and c properties, and b will be the empty string.
}
// issue 4683
if issue_4683.shown : issue_4683 := TouchArea {
// ^error{Cannot access id 'issue_4683'}
property <bool> shown: true;
clicked => { shown = !shown; }
}
for xx in inner_for.model: inner_for := Rectangle {
// ^error{Cannot access id 'inner_for'}
property <[int]> model: [1,2,3,4];
}
for xx in inner_model: Rectangle {
// ^error{Unknown unqualified identifier 'inner_model'}
property <[int]> inner_model: [1,2,3,4];
}
if element_inside_if.pressed : Rectangle {
// ^error{Cannot access id 'element_inside_if'}
element_inside_if := TouchArea {}
}
if self.pressed : TouchArea { }
// ^error{Element 'Rectangle' does not have a property 'pressed'}
}