Skip to content

Commit ca42f42

Browse files
committed
llr::Expression: add support for owned arrays
Generating Slice::from_slice(&[...]) is only valid for values being passed as function arguments. For a function's return type, for instance, this is invalid, the array will be deallocated immediately. The bool as_model is now an enum, to offer three choices Before: as_model=false => Slice::from_slice as_model=true => ModelRc<VecModel> After: ArrayOutput::Slice => Slice::from_slice ArrayOutput::Vector => Vec ArrayOutput::Model => ModelRc<VecModel>
1 parent 2d5de6f commit ca42f42

File tree

4 files changed

+52
-38
lines changed

4 files changed

+52
-38
lines changed

internal/compiler/generator/cpp.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3401,7 +3401,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
34013401
) =>
34023402
{
34033403
let path_elements = match from.as_ref() {
3404-
Expression::Array { element_ty: _, values, as_model: _ } => {
3404+
Expression::Array { element_ty: _, values, output: _ } => {
34053405
values.iter().map(|path_elem_expr| {
34063406
let (field_count, qualified_elem_type_name) =
34073407
match path_elem_expr.ty(ctx) {
@@ -3609,25 +3609,27 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
36093609
format!("({cond_code} ? {true_code} : {false_code})")
36103610
}
36113611
}
3612-
Expression::Array { element_ty, values, as_model } => {
3612+
Expression::Array { element_ty, values, output } => {
36133613
let ty = element_ty.cpp_type().unwrap();
36143614
let mut val = values
36153615
.iter()
36163616
.map(|e| format!("{ty} ( {expr} )", expr = compile_expression(e, ctx), ty = ty));
3617-
if *as_model {
3618-
format!(
3617+
match output {
3618+
llr::ArrayOutput::Model => format!(
36193619
"std::make_shared<slint::private_api::ArrayModel<{count},{ty}>>({val})",
36203620
count = values.len(),
36213621
ty = ty,
36223622
val = val.join(", ")
3623-
)
3624-
} else {
3625-
format!(
3623+
),
3624+
llr::ArrayOutput::Slice => format!(
36263625
"slint::private_api::make_slice<{ty}>(std::array<{ty}, {count}>{{ {val} }}.data(), {count})",
36273626
count = values.len(),
36283627
ty = ty,
36293628
val = val.join(", ")
3630-
)
3629+
),
3630+
llr::ArrayOutput::Vector => {
3631+
format!("std::vector<{ty}>{{ {val} }}", ty = ty, val = val.join(", "))
3632+
}
36313633
}
36323634
}
36333635
Expression::Struct { ty, values } => {

internal/compiler/generator/rust.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use crate::expression_tree::{BuiltinFunction, EasingCurve, MinMaxOp, OperatorCla
1717
use crate::langtype::{Enumeration, EnumerationValue, Struct, StructName, Type};
1818
use crate::layout::Orientation;
1919
use crate::llr::{
20-
self, EvaluationContext as llr_EvaluationContext, EvaluationScope, Expression, ParentScope,
21-
TypeResolutionContext as _,
20+
self, ArrayOutput, EvaluationContext as llr_EvaluationContext, EvaluationScope, Expression,
21+
ParentScope, TypeResolutionContext as _,
2222
};
2323
use crate::object_tree::Document;
2424
use crate::typeloader::LibraryInfo;
@@ -2362,7 +2362,7 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream
23622362
) =>
23632363
{
23642364
let path_elements = match from.as_ref() {
2365-
Expression::Array { element_ty: _, values, as_model: _ } => values
2365+
Expression::Array { element_ty: _, values, output: _ } => values
23662366
.iter()
23672367
.map(|path_elem_expr|
23682368
// Close{} is a struct with no fields in markup, and PathElement::Close has no fields
@@ -2612,17 +2612,21 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream
26122612
}
26132613
)
26142614
}
2615-
Expression::Array { values, element_ty, as_model } => {
2615+
Expression::Array { values, element_ty, output } => {
26162616
let val = values.iter().map(|e| compile_expression(e, ctx));
2617-
if *as_model {
2618-
let rust_element_ty = rust_primitive_type(element_ty).unwrap();
2619-
quote!(sp::ModelRc::new(
2620-
sp::VecModel::<#rust_element_ty>::from(
2621-
sp::vec![#(#val as _),*]
2622-
)
2623-
))
2624-
} else {
2625-
quote!(sp::Slice::from_slice(&[#(#val),*]))
2617+
match output {
2618+
ArrayOutput::Model => {
2619+
let rust_element_ty = rust_primitive_type(element_ty).unwrap();
2620+
quote!(sp::ModelRc::new(
2621+
sp::VecModel::<#rust_element_ty>::from(
2622+
sp::vec![#(#val as _),*]
2623+
)
2624+
))
2625+
}
2626+
ArrayOutput::Slice =>
2627+
quote!(sp::Slice::from_slice(&[#(#val),*])),
2628+
ArrayOutput::Vector =>
2629+
quote!(sp::vec![#(#val as _),*]),
26262630
}
26272631
}
26282632
Expression::Struct { ty, values } => {

internal/compiler/llr/expression.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ use smol_str::SmolStr;
1313
use std::collections::BTreeMap;
1414
use std::rc::Rc;
1515

16+
#[derive(Debug, Clone)]
17+
pub enum ArrayOutput {
18+
Slice,
19+
Model,
20+
Vector,
21+
}
22+
1623
#[derive(Debug, Clone)]
1724
pub enum Expression {
1825
/// A string literal. The .0 is the content of the string, without the quotes
@@ -137,8 +144,8 @@ pub enum Expression {
137144
Array {
138145
element_ty: Type,
139146
values: Vec<Expression>,
140-
/// When true, this should be converted to a model. When false, this should stay as a slice
141-
as_model: bool,
147+
/// Choose what will be generated: a slice, a model, or a vector
148+
output: ArrayOutput,
142149
},
143150
Struct {
144151
ty: Rc<crate::langtype::Struct>,
@@ -252,7 +259,7 @@ impl Expression {
252259
Type::Array(element_ty) => Expression::Array {
253260
element_ty: (**element_ty).clone(),
254261
values: Vec::new(),
255-
as_model: true,
262+
output: ArrayOutput::Model,
256263
},
257264
Type::Struct(s) => Expression::Struct {
258265
ty: s.clone(),

internal/compiler/llr/lower_expression.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use super::{
1616
use crate::expression_tree::{BuiltinFunction, Callable, Expression as tree_Expression};
1717
use crate::langtype::{BuiltinPrivateStruct, EnumerationValue, Struct, StructName, Type};
1818
use crate::layout::{GridLayoutCell, Orientation, RowColExpr};
19+
use crate::llr::ArrayOutput as llr_ArrayOutput;
1920
use crate::llr::Expression as llr_Expression;
2021
use crate::namedreference::NamedReference;
2122
use crate::object_tree::{Element, ElementRc, PropertyAnimation};
@@ -145,8 +146,8 @@ pub fn lower_expression(
145146
let mut arguments =
146147
arguments.iter().map(|e| lower_expression(e, ctx)).collect::<Vec<_>>();
147148
if *f == BuiltinFunction::Translate {
148-
if let llr_Expression::Array { as_model, .. } = &mut arguments[3] {
149-
*as_model = false;
149+
if let llr_Expression::Array { output, .. } = &mut arguments[3] {
150+
*output = llr_ArrayOutput::Slice;
150151
}
151152
#[cfg(feature = "bundle-translations")]
152153
if let Some(translation_builder) = ctx.state.translation_builder.as_mut() {
@@ -212,7 +213,7 @@ pub fn lower_expression(
212213
tree_Expression::Array { element_ty, values } => llr_Expression::Array {
213214
element_ty: element_ty.clone(),
214215
values: values.iter().map(|e| lower_expression(e, ctx)).collect::<_>(),
215-
as_model: true,
216+
output: llr_ArrayOutput::Model,
216217
},
217218
tree_Expression::Struct { ty, values } => llr_Expression::Struct {
218219
ty: ty.clone(),
@@ -628,7 +629,7 @@ fn compute_grid_layout_info(
628629
llr_Expression::Array {
629630
element_ty: Type::Int32,
630631
values: Vec::new(),
631-
as_model: false,
632+
output: llr_ArrayOutput::Slice,
632633
}
633634
} else {
634635
llr_Expression::ReadLocalVariable {
@@ -713,7 +714,7 @@ fn organize_grid_layout(
713714
let roles_expr = llr_Expression::Array {
714715
element_ty: Type::Enumeration(e),
715716
values: roles,
716-
as_model: false,
717+
output: llr_ArrayOutput::Slice,
717718
};
718719
llr_Expression::ExtraBuiltinFunctionCall {
719720
function: "organize_dialog_button_layout".into(),
@@ -729,7 +730,7 @@ fn organize_grid_layout(
729730
llr_Expression::Array {
730731
element_ty: Type::Int32,
731732
values: Vec::new(),
732-
as_model: false,
733+
output: llr_ArrayOutput::Slice,
733734
}
734735
} else {
735736
llr_Expression::ReadLocalVariable {
@@ -810,7 +811,7 @@ fn solve_grid_layout(
810811
// empty array of repeated indices
811812
element_ty: Type::Int32,
812813
values: Vec::new(),
813-
as_model: false,
814+
output: llr_ArrayOutput::Slice,
814815
},
815816
],
816817
return_ty: Type::LayoutCache,
@@ -868,7 +869,7 @@ fn solve_layout(
868869
llr_Expression::Array {
869870
element_ty: Type::Int32,
870871
values: Vec::new(),
871-
as_model: false,
872+
output: llr_ArrayOutput::Slice,
872873
},
873874
],
874875
return_ty: Type::LayoutCache,
@@ -926,7 +927,7 @@ fn box_layout_data(
926927
})
927928
.collect(),
928929
element_ty,
929-
as_model: false,
930+
output: llr_ArrayOutput::Slice,
930931
};
931932
BoxLayoutDataResult { alignment, cells, compute_cells: None }
932933
} else {
@@ -982,7 +983,7 @@ fn grid_layout_cell_constraints(
982983
make_layout_cell_data_struct(layout_info)
983984
})
984985
.collect(),
985-
as_model: false,
986+
output: llr_ArrayOutput::Slice,
986987
};
987988
GridLayoutCellConstraintsResult { cells, compute_cells: None }
988989
} else {
@@ -1066,7 +1067,7 @@ fn grid_layout_input_data(
10661067
)
10671068
})
10681069
.collect(),
1069-
as_model: false,
1070+
output: llr_ArrayOutput::Slice,
10701071
};
10711072
GridLayoutInputDataResult { cells, compute_cells: None }
10721073
} else {
@@ -1244,7 +1245,7 @@ fn compile_path(
12441245
from: llr_Expression::Array {
12451246
element_ty: crate::typeregister::path_element_type(),
12461247
values: elements,
1247-
as_model: false,
1248+
output: llr_ArrayOutput::Slice,
12481249
}
12491250
.into(),
12501251
to: Type::PathData,
@@ -1328,15 +1329,15 @@ fn compile_path(
13281329
llr_Expression::Array {
13291330
element_ty: event_type,
13301331
values: events,
1331-
as_model: false,
1332+
output: llr_ArrayOutput::Slice,
13321333
},
13331334
),
13341335
(
13351336
SmolStr::new_static("points"),
13361337
llr_Expression::Array {
13371338
element_ty: point_type,
13381339
values: points,
1339-
as_model: false,
1340+
output: llr_ArrayOutput::Slice,
13401341
},
13411342
),
13421343
])

0 commit comments

Comments
 (0)