Fix getting type of more complex expressions in model

Fixes #2977

The problem is that expressions such as "foo * foo" can be optimized by
optimization pass to only query the property once, and this is
transformed in a Expression::CodeBlock and is no longer a
Expression::Cast(Model)
So we need to introspect the expression more.
This commit is contained in:
Olivier Goffart 2023-06-27 09:01:36 +02:00 committed by Olivier Goffart
parent 9991908d40
commit f0a1ef7194
4 changed files with 25 additions and 19 deletions

View file

@ -631,24 +631,13 @@ impl Expression {
Expression::BuiltinMacroReference { .. } => Type::Invalid, // We don't know the type
Expression::ElementReference(_) => Type::ElementReference,
Expression::RepeaterIndexReference { .. } => Type::Int32,
Expression::RepeaterModelReference { element } => {
if let Expression::Cast { from, .. } = element
.upgrade()
.unwrap()
.borrow()
.repeated
.as_ref()
.map_or(&Expression::Invalid, |e| &e.model)
{
match from.ty() {
Type::Float32 | Type::Int32 => Type::Int32,
Type::Array(elem) => *elem,
_ => Type::Invalid,
}
} else {
Type::Invalid
}
}
Expression::RepeaterModelReference { element } => element
.upgrade()
.unwrap()
.borrow()
.repeated
.as_ref()
.map_or(Type::Invalid, |e| model_inner_type(&e.model)),
Expression::FunctionParameterReference { ty, .. } => ty.clone(),
Expression::StructFieldAccess { base, name } => match base.ty() {
Type::Struct { fields, .. } => {
@ -1318,6 +1307,18 @@ impl Expression {
}
}
fn model_inner_type(model: &Expression) -> Type {
match model {
Expression::Cast { from, to: Type::Model } => model_inner_type(&from),
Expression::CodeBlock(cb) => cb.last().map_or(Type::Invalid, model_inner_type),
_ => match model.ty() {
Type::Float32 | Type::Int32 => Type::Int32,
Type::Array(elem) => *elem,
_ => Type::Invalid,
},
}
}
/// The expression in the Element::binding hash table
#[derive(Debug, Clone, derive_more::Deref, derive_more::DerefMut)]
pub struct BindingExpression {