slint-ui / slint

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
https://slint.dev
Other
16.95k stars 568 forks source link

Compile error starting with Slint v1.7.2 #5883

Closed Ultrajackstr closed 1 month ago

Ultrajackstr commented 1 month ago

W11 Pro 22631.3880 stable-x86_64-pc-windows-msvc rustc 1.80.1 (3f5fd8dd4 2024-08-06)

[dependencies]
slint = { version = "=1.7.1", default-features = false, features = [
    # "renderer-winit-femtovg",
    "renderer-winit-skia-opengl",
    "compat-1-2",
    "backend-winit",
] }
[build-dependencies]
slint-build = { version = "=1.7.1"}

Hello,

I am getting a compile error starting at version 1.7.2, including the Git version. It compiles fine with version 1.7.1 or below. I could not find any related issue on Github.

Thank you,

Jack

error: expected expression, found `let` statement
     --> C:\Users\Jack\RustroverProjects\cell_slint\gui\target\debug\build\cell_slint-f627651258b436a1\out\main-window.rs:78014:35
      |
78014 | ...                   (let _ = (_self . parent . upgrade () . and_then (| x | x . parent . upgrade ()) . as_ref () . map (| x | ({
      |                        ^^^
      |
      = note: only supported directly in conditions of `if` and `while` expressions

error: closure bodies that contain statements must be surrounded by braces
     --> C:\Users\Jack\RustroverProjects\cell_slint\gui\target\debug\build\cell_slint-f627651258b436a1\out\main-window.rs:78016:141
      |
78016 | ...                    + InnerButton_root_314 :: FIELD_OFFSETS . r#root_314_clicked) . apply_pin (x . as_pin_ref ()))) . map (| x | x . call (& ())) ;
      |                                                                                                                                   ^
78017 | ...                   ) ;
      |                       ^
      |
note: statement found outside of a block
     --> C:\Users\Jack\RustroverProjects\cell_slint\gui\target\debug\build\cell_slint-f627651258b436a1\out\main-window.rs:78016:160
      |
78016 | ...                   + InnerButton_root_314 :: FIELD_OFFSETS . r#root_314_clicked) . apply_pin (x . as_pin_ref ()))) . map (| x | x . call (& ())) ;
      |                                                                                                                                    ---------------  ^ this `;` turns the preceding closure into a statement
      |                                                                                                                                    |
      |                                                                                                                                    this expression is a statement because of the trailing semicolon
note: the closure body may be incorrectly delimited
     --> C:\Users\Jack\RustroverProjects\cell_slint\gui\target\debug\build\cell_slint-f627651258b436a1\out\main-window.rs:78016:137
      |
78016 | ...                    + InnerButton_root_314 :: FIELD_OFFSETS . r#root_314_clicked) . apply_pin (x . as_pin_ref ()))) . map (| x | x . call (& ())) ;
      |                                                                                                                               ^^^^^^^^^^^^^^^^^^^^^ this is the parsed closure...
78017 | ...                   ) ;
      |                       - ...but likely you meant the closure to end here
help: try adding braces
      |
78016 ~                                  + InnerButton_root_314 :: FIELD_OFFSETS . r#root_314_clicked) . apply_pin (x . as_pin_ref ()))) . map (| x | { x . call (& ())) ;
78017 ~                                 }) ;
      |
ogoffart commented 1 month ago

Thanks for the report. Looks like this is caused by https://github.com/slint-ui/slint/pull/5813 Do you have an example i can use to reproduce?

Ultrajackstr commented 1 month ago

Hi Olivier, The project is quite big so I do not have an isolated example to provide. However, I just found the problematic line:

Button {
 text: "Yes";
 clicked => {
  ProtocolManagerLogic.delete-protocol-by-type-uuid(root.current-selected-protocol-type, protocol.uuid);
  if root.current-selected-protocol-name-uuid[1] == protocol.uuid {
   root.current-selected-protocol-name-uuid = ["", ""]
  };
/////// When I comment out the next line, the program compiles fine.
  root.current-selected-protocol-type == "unit" ? btn-show-unit-protocols.clicked() : btn-show-global-protocols.clicked();
///////
  search-field.text = "";
  root.is_confirm_delete_open = false;
 }
}

This is the code for the buttons:

btn-show-unit-protocols := Button {
 text: "Show Unit Protocols";
 checked: root.current-selected-protocol-type == "unit";
 clicked => {
  root.get-all-unit-protocols();
 }
}

btn-show-global-protocols := Button {
 text: "Show Global Protocols";
 checked: root.current-selected-protocol-type == "global";
 clicked => {
  root.get-all-global-protocols();
 }
}

This is the code for the functions (only for "unit", "global" is essentially the same):

function get-all-unit-protocols() {
 ProtocolManagerLogic.get-all-unit-protocols();
 root.current-selected-protocol-type = "unit";
 root.current-selected-protocol-name-uuid = [current-displayed-protocols[0].name, current-displayed-protocols[0].uuid];
 root.is_confirm_delete_open = false;
 if current-displayed-protocols[0].uuid != "" {
 ProtocolManagerLogic.get-protocol-by-type-uuid(root.current-selected-protocol-type, current-displayed-protocols[0].uuid)
 }
 search-field.text = "";
 root.current-searched-protocols = root.current-displayed-protocols;
 protcol-list.viewport-y = 0px;
}
ogoffart commented 1 month ago

Thanks, I was able to reproduce. (and fix in #5884)

Workaround: use if/else

if root.current-selected-protocol-type == "unit" {
 btn-show-unit-protocols.clicked();
} else {
 btn-show-global-protocols.clicked();
}
Ultrajackstr commented 1 month ago

It works now. Thank you for your quick answer !