diff --git a/internal/compiler/generator/cpp.rs b/internal/compiler/generator/cpp.rs index 608c7b8d131..6cff1745cb1 100644 --- a/internal/compiler/generator/cpp.rs +++ b/internal/compiler/generator/cpp.rs @@ -3401,7 +3401,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String ) => { let path_elements = match from.as_ref() { - Expression::Array { element_ty: _, values, as_model: _ } => { + Expression::Array { element_ty: _, values, output: _ } => { values.iter().map(|path_elem_expr| { let (field_count, qualified_elem_type_name) = match path_elem_expr.ty(ctx) { @@ -3609,25 +3609,27 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String format!("({cond_code} ? {true_code} : {false_code})") } } - Expression::Array { element_ty, values, as_model } => { + Expression::Array { element_ty, values, output } => { let ty = element_ty.cpp_type().unwrap(); let mut val = values .iter() .map(|e| format!("{ty} ( {expr} )", expr = compile_expression(e, ctx), ty = ty)); - if *as_model { - format!( + match output { + llr::ArrayOutput::Model => format!( "std::make_shared>({val})", count = values.len(), ty = ty, val = val.join(", ") - ) - } else { - format!( + ), + llr::ArrayOutput::Slice => format!( "slint::private_api::make_slice<{ty}>(std::array<{ty}, {count}>{{ {val} }}.data(), {count})", count = values.len(), ty = ty, val = val.join(", ") - ) + ), + llr::ArrayOutput::Vector => { + format!("std::vector<{ty}>{{ {val} }}", ty = ty, val = val.join(", ")) + } } } Expression::Struct { ty, values } => { diff --git a/internal/compiler/generator/rust.rs b/internal/compiler/generator/rust.rs index a6cd357bfdf..11dc9a5b6ca 100644 --- a/internal/compiler/generator/rust.rs +++ b/internal/compiler/generator/rust.rs @@ -17,8 +17,8 @@ use crate::expression_tree::{BuiltinFunction, EasingCurve, MinMaxOp, OperatorCla use crate::langtype::{Enumeration, EnumerationValue, Struct, StructName, Type}; use crate::layout::Orientation; use crate::llr::{ - self, EvaluationContext as llr_EvaluationContext, EvaluationScope, Expression, ParentScope, - TypeResolutionContext as _, + self, ArrayOutput, EvaluationContext as llr_EvaluationContext, EvaluationScope, Expression, + ParentScope, TypeResolutionContext as _, }; use crate::object_tree::Document; use crate::typeloader::LibraryInfo; @@ -2362,7 +2362,7 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream ) => { let path_elements = match from.as_ref() { - Expression::Array { element_ty: _, values, as_model: _ } => values + Expression::Array { element_ty: _, values, output: _ } => values .iter() .map(|path_elem_expr| // Close{} is a struct with no fields in markup, and PathElement::Close has no fields @@ -2612,17 +2612,19 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream } ) } - Expression::Array { values, element_ty, as_model } => { + Expression::Array { values, element_ty, output } => { let val = values.iter().map(|e| compile_expression(e, ctx)); - if *as_model { - let rust_element_ty = rust_primitive_type(element_ty).unwrap(); - quote!(sp::ModelRc::new( - sp::VecModel::<#rust_element_ty>::from( - sp::vec![#(#val as _),*] - ) - )) - } else { - quote!(sp::Slice::from_slice(&[#(#val),*])) + match output { + ArrayOutput::Model => { + let rust_element_ty = rust_primitive_type(element_ty).unwrap(); + quote!(sp::ModelRc::new( + sp::VecModel::<#rust_element_ty>::from( + sp::vec![#(#val as _),*] + ) + )) + } + ArrayOutput::Slice => quote!(sp::Slice::from_slice(&[#(#val),*])), + ArrayOutput::Vector => quote!(sp::vec![#(#val as _),*]), } } Expression::Struct { ty, values } => { diff --git a/internal/compiler/llr/expression.rs b/internal/compiler/llr/expression.rs index b59a0f5c0f7..501ad287d60 100644 --- a/internal/compiler/llr/expression.rs +++ b/internal/compiler/llr/expression.rs @@ -13,6 +13,13 @@ use smol_str::SmolStr; use std::collections::BTreeMap; use std::rc::Rc; +#[derive(Debug, Clone)] +pub enum ArrayOutput { + Slice, + Model, + Vector, +} + #[derive(Debug, Clone)] pub enum Expression { /// A string literal. The .0 is the content of the string, without the quotes @@ -137,8 +144,8 @@ pub enum Expression { Array { element_ty: Type, values: Vec, - /// When true, this should be converted to a model. When false, this should stay as a slice - as_model: bool, + /// Choose what will be generated: a slice, a model, or a vector + output: ArrayOutput, }, Struct { ty: Rc, @@ -252,7 +259,7 @@ impl Expression { Type::Array(element_ty) => Expression::Array { element_ty: (**element_ty).clone(), values: Vec::new(), - as_model: true, + output: ArrayOutput::Model, }, Type::Struct(s) => Expression::Struct { ty: s.clone(), diff --git a/internal/compiler/llr/lower_expression.rs b/internal/compiler/llr/lower_expression.rs index 6d968a29940..f910913ff6d 100644 --- a/internal/compiler/llr/lower_expression.rs +++ b/internal/compiler/llr/lower_expression.rs @@ -16,6 +16,7 @@ use super::{ use crate::expression_tree::{BuiltinFunction, Callable, Expression as tree_Expression}; use crate::langtype::{BuiltinPrivateStruct, EnumerationValue, Struct, StructName, Type}; use crate::layout::{GridLayoutCell, Orientation, RowColExpr}; +use crate::llr::ArrayOutput as llr_ArrayOutput; use crate::llr::Expression as llr_Expression; use crate::namedreference::NamedReference; use crate::object_tree::{Element, ElementRc, PropertyAnimation}; @@ -144,9 +145,11 @@ pub fn lower_expression( Callable::Builtin(f) => { let mut arguments = arguments.iter().map(|e| lower_expression(e, ctx)).collect::>(); + // https://github.com/rust-lang/rust-clippy/issues/16191 + #[allow(clippy::collapsible_if)] if *f == BuiltinFunction::Translate { - if let llr_Expression::Array { as_model, .. } = &mut arguments[3] { - *as_model = false; + if let llr_Expression::Array { output, .. } = &mut arguments[3] { + *output = llr_ArrayOutput::Slice; } #[cfg(feature = "bundle-translations")] if let Some(translation_builder) = ctx.state.translation_builder.as_mut() { @@ -212,7 +215,7 @@ pub fn lower_expression( tree_Expression::Array { element_ty, values } => llr_Expression::Array { element_ty: element_ty.clone(), values: values.iter().map(|e| lower_expression(e, ctx)).collect::<_>(), - as_model: true, + output: llr_ArrayOutput::Model, }, tree_Expression::Struct { ty, values } => llr_Expression::Struct { ty: ty.clone(), @@ -628,7 +631,7 @@ fn compute_grid_layout_info( llr_Expression::Array { element_ty: Type::Int32, values: Vec::new(), - as_model: false, + output: llr_ArrayOutput::Slice, } } else { llr_Expression::ReadLocalVariable { @@ -713,7 +716,7 @@ fn organize_grid_layout( let roles_expr = llr_Expression::Array { element_ty: Type::Enumeration(e), values: roles, - as_model: false, + output: llr_ArrayOutput::Slice, }; llr_Expression::ExtraBuiltinFunctionCall { function: "organize_dialog_button_layout".into(), @@ -729,7 +732,7 @@ fn organize_grid_layout( llr_Expression::Array { element_ty: Type::Int32, values: Vec::new(), - as_model: false, + output: llr_ArrayOutput::Slice, } } else { llr_Expression::ReadLocalVariable { @@ -810,7 +813,7 @@ fn solve_grid_layout( // empty array of repeated indices element_ty: Type::Int32, values: Vec::new(), - as_model: false, + output: llr_ArrayOutput::Slice, }, ], return_ty: Type::LayoutCache, @@ -868,7 +871,7 @@ fn solve_layout( llr_Expression::Array { element_ty: Type::Int32, values: Vec::new(), - as_model: false, + output: llr_ArrayOutput::Slice, }, ], return_ty: Type::LayoutCache, @@ -926,7 +929,7 @@ fn box_layout_data( }) .collect(), element_ty, - as_model: false, + output: llr_ArrayOutput::Slice, }; BoxLayoutDataResult { alignment, cells, compute_cells: None } } else { @@ -972,7 +975,7 @@ fn grid_layout_cell_constraints( if repeater_count == 0 { let cells = llr_Expression::Array { - element_ty: element_ty, + element_ty, values: layout .elems .iter() @@ -982,7 +985,7 @@ fn grid_layout_cell_constraints( make_layout_cell_data_struct(layout_info) }) .collect(), - as_model: false, + output: llr_ArrayOutput::Slice, }; GridLayoutCellConstraintsResult { cells, compute_cells: None } } else { @@ -1066,7 +1069,7 @@ fn grid_layout_input_data( ) }) .collect(), - as_model: false, + output: llr_ArrayOutput::Slice, }; GridLayoutInputDataResult { cells, compute_cells: None } } else { @@ -1244,7 +1247,7 @@ fn compile_path( from: llr_Expression::Array { element_ty: crate::typeregister::path_element_type(), values: elements, - as_model: false, + output: llr_ArrayOutput::Slice, } .into(), to: Type::PathData, @@ -1328,7 +1331,7 @@ fn compile_path( llr_Expression::Array { element_ty: event_type, values: events, - as_model: false, + output: llr_ArrayOutput::Slice, }, ), ( @@ -1336,7 +1339,7 @@ fn compile_path( llr_Expression::Array { element_ty: point_type, values: points, - as_model: false, + output: llr_ArrayOutput::Slice, }, ), ])