Compiler: fix conversion of array of array of structs

When finding the common types for array of array, we must recurse in the
inner type

Fixes: #3574
This commit is contained in:
Olivier Goffart 2023-10-02 17:51:39 +02:00 committed by Olivier Goffart
parent b50b661928
commit 661080676a
4 changed files with 56 additions and 1 deletions

View file

@ -14,6 +14,7 @@ All notable changes to this project are documented in this file.
- Added `Number`, `Decimal` variant to enum `InputType`
- Added `spacing-horizontal` and `spacing-vertical` in `GridLayout`
- Fixed conversion in array of array of structs (#3574)
### Rust API

View file

@ -1216,7 +1216,7 @@ impl Expression {
) => {
*existing_field.get_mut() =
Self::common_target_type_for_type_list(
[existing_field.get().clone(), elem_ty].iter().cloned(),
[existing_field.get().clone(), elem_ty].into_iter(),
);
}
}
@ -1228,6 +1228,9 @@ impl Expression {
rust_attributes: rust_attributes.or(deriven),
}
}
(Type::Array(lhs), Type::Array(rhs)) => Type::Array(
Self::common_target_type_for_type_list([*lhs, *rhs].into_iter()).into(),
),
(Type::Color, Type::Brush) | (Type::Brush, Type::Color) => Type::Brush,
(target_type, expr_ty) => {
if expr_ty.can_convert(&target_type) {

View file

@ -48,5 +48,6 @@ export X := Rectangle {
property <[{a: [int]}]> ccc: [{a: []}, {}, {a: ["123"]}, {a: [123]}];
// ^error{Cannot convert string to int} (FIXME: error location)
// ^^error{Cannot convert string to int} (FIXME: duplicated)
}

View file

@ -0,0 +1,50 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
struct KeySlot { width-u: float, spacer: bool, background: color, font-size: length, }
struct Row { key-slots: [KeySlot], }
struct Layer { default-key-width-u: float, total-width-u: float, rows: [Row] }
export component TestCase {
// issue #3574
out property<[Layer]> layers: [ {
default-key-width-u: 1.0,
total-width-u: 10.0,
rows: [
{ key-slots: [ { width-u: 0.5}, { spacer: true, width-u: 0.5}, ] },
{ key-slots: [ { width-u: 2.5, background: #bbbbbb }, ] }
],
} ];
property <[[{a: string, b: string, c: string}]]> array : [
[{a: "hello"}],
[],
[{a: "world"}, {a: "extra", b: "ok"} ],
];
out property <bool> test: array[2][1].b == "ok" && layers[0].rows[0].key-slots[1].spacer;
}
/*
```cpp
auto handle = TestCase::create();
const TestCase &instance = *handle;
assert(instance.get_test());
```
```rust
let instance = TestCase::new().unwrap();
assert!(instance.get_test());
```
```js
var instance = new slint.TestCase({});
assert(instance.test);
```
*/