From d19616da03cb49cdce96da62ec5a9e2c0b23105d Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 22 Jul 2025 11:26:26 +0200 Subject: [PATCH] chore!: bump the MSRV to 1.88 let-chains ftw --- Cargo.toml | 2 +- bindings/matrix-sdk-ffi/CHANGELOG.md | 3 + crates/matrix-sdk-ui/CHANGELOG.md | 6 ++ .../matrix-sdk-ui/src/notification_client.rs | 8 +-- .../src/timeline/controller/aggregations.rs | 61 ++++++++--------- .../src/timeline/controller/metadata.rs | 30 ++++----- .../src/timeline/controller/mod.rs | 18 +++-- .../timeline/controller/observable_items.rs | 8 +-- .../timeline/controller/state_transaction.rs | 13 ++-- .../src/timeline/date_dividers.rs | 65 +++++++++--------- .../src/timeline/event_item/mod.rs | 14 ++-- crates/matrix-sdk-ui/src/timeline/mod.rs | 27 ++++---- .../src/timeline/pinned_events_loader.rs | 11 ++-- .../tests/integration/sync_service.rs | 66 +++++++++---------- crates/matrix-sdk/CHANGELOG.md | 5 ++ 15 files changed, 169 insertions(+), 168 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a5c595088..f9ca02753 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ default-members = ["benchmarks", "crates/*", "labs/*"] resolver = "2" [workspace.package] -rust-version = "1.85" +rust-version = "1.88" [workspace.dependencies] anyhow = "1.0.95" diff --git a/bindings/matrix-sdk-ffi/CHANGELOG.md b/bindings/matrix-sdk-ffi/CHANGELOG.md index e656472be..1621c4f8f 100644 --- a/bindings/matrix-sdk-ffi/CHANGELOG.md +++ b/bindings/matrix-sdk-ffi/CHANGELOG.md @@ -25,6 +25,9 @@ All notable changes to this project will be documented in this file. - `ClientBuilder::build_with_qr_code` has been removed. Instead, the Client should be built by passing `QrCodeData::server_name` to `ClientBuilder::server_name_or_homeserver_url`, after which QR login can be performed by calling `Client::login_with_qr_code`. ([#5388](https://github.com/matrix-org/matrix-rust-sdk/pull/5388)) +- The MSRV has been bumped to Rust 1.88. + ([#5431](https://github.com/matrix-org/matrix-rust-sdk/pull/5431)) + ## [0.13.0] - 2025-07-10 diff --git a/crates/matrix-sdk-ui/CHANGELOG.md b/crates/matrix-sdk-ui/CHANGELOG.md index 9e39c2378..4dc5b8750 100644 --- a/crates/matrix-sdk-ui/CHANGELOG.md +++ b/crates/matrix-sdk-ui/CHANGELOG.md @@ -6,6 +6,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - ReleaseDate +### Refactor + +- [**breaking**] The MSRV has been bumped to Rust 1.88. + ([#5431](https://github.com/matrix-org/matrix-rust-sdk/pull/5431)) + + ## [0.13.0] - 2025-07-10 ### Features diff --git a/crates/matrix-sdk-ui/src/notification_client.rs b/crates/matrix-sdk-ui/src/notification_client.rs index 5c3fb2053..ebe9b8e80 100644 --- a/crates/matrix-sdk-ui/src/notification_client.rs +++ b/crates/matrix-sdk-ui/src/notification_client.rs @@ -747,10 +747,10 @@ impl NotificationClient { timeline_event = decrypted_event; } - if let Some(actions) = timeline_event.push_actions() { - if !actions.iter().any(|a| a.should_notify()) { - return Ok(NotificationStatus::EventFilteredOut); - } + if let Some(actions) = timeline_event.push_actions() + && !actions.iter().any(|a| a.should_notify()) + { + return Ok(NotificationStatus::EventFilteredOut); } let push_actions = timeline_event.push_actions().map(ToOwned::to_owned); diff --git a/crates/matrix-sdk-ui/src/timeline/controller/aggregations.rs b/crates/matrix-sdk-ui/src/timeline/controller/aggregations.rs index 07eb0f32f..12f569d3a 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/aggregations.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/aggregations.rs @@ -377,13 +377,12 @@ impl Aggregations { // If there was any redaction among the current aggregation, adding a new one // should be a noop. - if let Some(previous_aggregations) = self.related_events.get(&related_to) { - if previous_aggregations + if let Some(previous_aggregations) = self.related_events.get(&related_to) + && previous_aggregations .iter() .any(|agg| matches!(agg.kind, AggregationKind::Redaction)) - { - return; - } + { + return; } self.inverted_map.insert(aggregation.own_id.clone(), related_to.clone()); @@ -553,26 +552,26 @@ impl Aggregations { return false; }; - if let Some(aggregations) = self.related_events.get_mut(&target) { - if let Some(found) = aggregations.iter_mut().find(|agg| agg.own_id == from) { - found.own_id = to.clone(); + if let Some(aggregations) = self.related_events.get_mut(&target) + && let Some(found) = aggregations.iter_mut().find(|agg| agg.own_id == from) + { + found.own_id = to.clone(); - match &mut found.kind { - AggregationKind::PollResponse { .. } - | AggregationKind::PollEnd { .. } - | AggregationKind::Edit(..) - | AggregationKind::Redaction => { - // Nothing particular to do. - } + match &mut found.kind { + AggregationKind::PollResponse { .. } + | AggregationKind::PollEnd { .. } + | AggregationKind::Edit(..) + | AggregationKind::Redaction => { + // Nothing particular to do. + } - AggregationKind::Reaction { reaction_status, .. } => { - // Mark the reaction as becoming remote, and signal that update to the - // caller. - *reaction_status = ReactionStatus::RemoteToRemote(event_id); + AggregationKind::Reaction { reaction_status, .. } => { + // Mark the reaction as becoming remote, and signal that update to the + // caller. + *reaction_status = ReactionStatus::RemoteToRemote(event_id); - let found = found.clone(); - find_item_and_apply_aggregation(self, items, &target, found, room_version); - } + let found = found.clone(); + find_item_and_apply_aggregation(self, items, &target, found, room_version); } } } @@ -754,16 +753,14 @@ pub(crate) fn find_item_and_apply_aggregation( Some(new_event_item) } ApplyAggregationResult::Edit => { - if let Some(aggregations) = aggregations.related_events.get(target) { - if resolve_edits(aggregations, items, &mut cowed) { - let new_event_item = cowed.into_owned(); - let new_item = TimelineItem::new( - new_event_item.clone(), - event_item.internal_id.to_owned(), - ); - items.replace(idx, new_item); - return Some(new_event_item); - } + if let Some(aggregations) = aggregations.related_events.get(target) + && resolve_edits(aggregations, items, &mut cowed) + { + let new_event_item = cowed.into_owned(); + let new_item = + TimelineItem::new(new_event_item.clone(), event_item.internal_id.to_owned()); + items.replace(idx, new_item); + return Some(new_event_item); } None } diff --git a/crates/matrix-sdk-ui/src/timeline/controller/metadata.rs b/crates/matrix-sdk-ui/src/timeline/controller/metadata.rs index b02c4d6fe..c81bb78a6 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/metadata.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/metadata.rs @@ -318,21 +318,21 @@ impl TimelineMetadata { timeline_items: &Vector>, is_thread_focus: bool, ) -> (Option, Option) { - if let AnySyncTimelineEvent::MessageLike(ev) = event { - if let Some(content) = ev.original_content() { - let remote_ctx = Some(RemoteEventContext { - event_id: ev.event_id(), - raw_event, - relations: ev.relations(), - bundled_edit_encryption_info, - }); - return self.process_content_relations( - &content, - remote_ctx, - timeline_items, - is_thread_focus, - ); - } + if let AnySyncTimelineEvent::MessageLike(ev) = event + && let Some(content) = ev.original_content() + { + let remote_ctx = Some(RemoteEventContext { + event_id: ev.event_id(), + raw_event, + relations: ev.relations(), + bundled_edit_encryption_info, + }); + return self.process_content_relations( + &content, + remote_ctx, + timeline_items, + is_thread_focus, + ); } (None, None) } diff --git a/crates/matrix-sdk-ui/src/timeline/controller/mod.rs b/crates/matrix-sdk-ui/src/timeline/controller/mod.rs index ad9a3b994..8d5c75915 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/mod.rs @@ -850,12 +850,11 @@ impl TimelineController { .await; } - if track_read_markers { - if let Some(fully_read_event_id) = + if track_read_markers + && let Some(fully_read_event_id) = self.room_data_provider.load_fully_read_marker().await - { - state.handle_fully_read_marker(fully_read_event_id); - } + { + state.handle_fully_read_marker(fully_read_event_id); } } @@ -1561,14 +1560,13 @@ impl TimelineController { SendReceiptType::FullyRead => { if let Some(prev_event_id) = self.room_data_provider.load_fully_read_marker().await - { - if let Some(relative_pos) = state.meta.compare_events_positions( + && let Some(relative_pos) = state.meta.compare_events_positions( &prev_event_id, event_id, state.items.all_remote_events(), - ) { - return relative_pos == RelativePosition::After; - } + ) + { + return relative_pos == RelativePosition::After; } } diff --git a/crates/matrix-sdk-ui/src/timeline/controller/observable_items.rs b/crates/matrix-sdk-ui/src/timeline/controller/observable_items.rs index 247d9bfe9..b9688ebef 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/observable_items.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/observable_items.rs @@ -2008,10 +2008,10 @@ impl AllRemoteEvents { ) { self.increment_all_timeline_item_index_after(new_timeline_item_index); - if let Some(event_index) = event_index { - if let Some(event_meta) = self.0.get_mut(event_index) { - event_meta.timeline_item_index = Some(new_timeline_item_index); - } + if let Some(event_index) = event_index + && let Some(event_meta) = self.0.get_mut(event_index) + { + event_meta.timeline_item_index = Some(new_timeline_item_index); } } diff --git a/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs b/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs index 6fdf22a12..9060beae8 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs @@ -850,15 +850,14 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> { TimelineItemPosition::UpdateAt { .. } => { if let Some(event) = self.items.get_remote_event_by_event_id_mut(&event_meta.event_id) + && event.visible != event_meta.visible { - if event.visible != event_meta.visible { - event.visible = event_meta.visible; + event.visible = event_meta.visible; - if settings.track_read_receipts { - // Since the event's visibility changed, we need to update the read - // receipts of the previous visible event. - self.maybe_update_read_receipts_of_prev_event(&event_meta.event_id); - } + if settings.track_read_receipts { + // Since the event's visibility changed, we need to update the read + // receipts of the previous visible event. + self.maybe_update_read_receipts_of_prev_event(&event_meta.event_id); } } } diff --git a/crates/matrix-sdk-ui/src/timeline/date_dividers.rs b/crates/matrix-sdk-ui/src/timeline/date_dividers.rs index b774df677..b344993b9 100644 --- a/crates/matrix-sdk-ui/src/timeline/date_dividers.rs +++ b/crates/matrix-sdk-ui/src/timeline/date_dividers.rs @@ -297,16 +297,16 @@ impl DateDividerAdjuster { if timestamp_to_date(*prev_ts) != event_date { // The date divider is wrong. Should we replace it with the correct value, or // remove it entirely? - if let Some(last_event_ts) = latest_event_ts { - if timestamp_to_date(last_event_ts) == event_date { - // There's a previous event with the same date: remove the divider. - trace!( - "removed date divider @ {item_index} between two events \ + if let Some(last_event_ts) = latest_event_ts + && timestamp_to_date(last_event_ts) == event_date + { + // There's a previous event with the same date: remove the divider. + trace!( + "removed date divider @ {item_index} between two events \ that have the same date" - ); - self.ops.insert(insert_op_at, DateDividerOperation::Remove(item_index)); - return; - } + ); + self.ops.insert(insert_op_at, DateDividerOperation::Remove(item_index)); + return; } // There's no previous event or there's one with a different date: replace @@ -440,10 +440,10 @@ impl DateDividerAdjuster { }; // 3. There's no trailing date divider. - if let Some(last) = items.last() { - if last.is_date_divider() { - report.errors.push(DateDividerInsertError::TrailingDateDivider); - } + if let Some(last) = items.last() + && last.is_date_divider() + { + report.errors.push(DateDividerInsertError::TrailingDateDivider); } // 4. Items are properly separated with date dividers. @@ -456,12 +456,12 @@ impl DateDividerAdjuster { let ts = ev.timestamp(); // We have the same date as the previous event we've seen. - if let Some(prev_ts) = prev_event_ts { - if !self.is_same_date_divider_group_as(prev_ts, ts) { - report.errors.push( - DateDividerInsertError::MissingDateDividerBetweenEvents { at: i }, - ); - } + if let Some(prev_ts) = prev_event_ts + && !self.is_same_date_divider_group_as(prev_ts, ts) + { + report.errors.push( + DateDividerInsertError::MissingDateDividerBetweenEvents { at: i }, + ); } // There is a date divider before us, and it's the same date as our timestamp. @@ -484,12 +484,10 @@ impl DateDividerAdjuster { item.kind() { // The previous date divider is for a different date. - if let Some(prev_ts) = prev_date_divider_ts { - if self.is_same_date_divider_group_as(prev_ts, *ts) { - report - .errors - .push(DateDividerInsertError::DuplicateDateDivider { at: i }); - } + if let Some(prev_ts) = prev_date_divider_ts + && self.is_same_date_divider_group_as(prev_ts, *ts) + { + report.errors.push(DateDividerInsertError::DuplicateDateDivider { at: i }); } prev_event_ts = None; @@ -500,15 +498,14 @@ impl DateDividerAdjuster { // 5. If there was a read marker at the beginning, there should be one at the // end. - if let Some(state) = &report.initial_state { - if state.iter().any(|item| item.is_read_marker()) - && !report - .final_state - .iter_remotes_and_locals_regions() - .any(|(_i, item)| item.is_read_marker()) - { - report.errors.push(DateDividerInsertError::ReadMarkerDisappeared); - } + if let Some(state) = &report.initial_state + && state.iter().any(|item| item.is_read_marker()) + && !report + .final_state + .iter_remotes_and_locals_regions() + .any(|(_i, item)| item.is_read_marker()) + { + report.errors.push(DateDividerInsertError::ReadMarkerDisappeared); } if report.errors.is_empty() { None } else { Some(report) } diff --git a/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs b/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs index 3cc678419..fe0c3c2c9 100644 --- a/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs @@ -773,14 +773,14 @@ impl ReactionsByKeyBySender { sender: &UserId, annotation: &str, ) -> Option { - if let Some(by_user) = self.0.get_mut(annotation) { - if let Some(info) = by_user.swap_remove(sender) { - // If this was the last reaction, remove the annotation entry. - if by_user.is_empty() { - self.0.swap_remove(annotation); - } - return Some(info); + if let Some(by_user) = self.0.get_mut(annotation) + && let Some(info) = by_user.swap_remove(sender) + { + // If this was the last reaction, remove the annotation entry. + if by_user.is_empty() { + self.0.swap_remove(annotation); } + return Some(info); } None } diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index beb28f6a5..c3ad28025 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -614,8 +614,8 @@ impl Timeline { /// This also unsets the unread marker of the room if necessary. #[instrument(skip(self))] pub async fn send_multiple_receipts(&self, mut receipts: Receipts) -> Result<()> { - if let Some(fully_read) = &receipts.fully_read { - if !self + if let Some(fully_read) = &receipts.fully_read + && !self .controller .should_send_receipt( &ReceiptType::FullyRead, @@ -623,23 +623,21 @@ impl Timeline { fully_read, ) .await - { - receipts.fully_read = None; - } + { + receipts.fully_read = None; } - if let Some(read_receipt) = &receipts.public_read_receipt { - if !self + if let Some(read_receipt) = &receipts.public_read_receipt + && !self .controller .should_send_receipt(&ReceiptType::Read, &ReceiptThread::Unthreaded, read_receipt) .await - { - receipts.public_read_receipt = None; - } + { + receipts.public_read_receipt = None; } - if let Some(private_read_receipt) = &receipts.private_read_receipt { - if !self + if let Some(private_read_receipt) = &receipts.private_read_receipt + && !self .controller .should_send_receipt( &ReceiptType::ReadPrivate, @@ -647,9 +645,8 @@ impl Timeline { private_read_receipt, ) .await - { - receipts.private_read_receipt = None; - } + { + receipts.private_read_receipt = None; } let room = self.room(); diff --git a/crates/matrix-sdk-ui/src/timeline/pinned_events_loader.rs b/crates/matrix-sdk-ui/src/timeline/pinned_events_loader.rs index cc53b3a85..d605d6b6c 100644 --- a/crates/matrix-sdk-ui/src/timeline/pinned_events_loader.rs +++ b/crates/matrix-sdk-ui/src/timeline/pinned_events_loader.rs @@ -171,13 +171,12 @@ impl PinnedEventsRoom for Room { related_event_filters: Option>, ) -> BoxFuture<'a, Result<(TimelineEvent, Vec), matrix_sdk::Error>> { Box::pin(async move { - if let Ok((cache, _handles)) = self.event_cache().await { - if let Some(ret) = + if let Ok((cache, _handles)) = self.event_cache().await + && let Some(ret) = cache.find_event_with_relations(event_id, related_event_filters).await - { - debug!("Loaded pinned event {event_id} and related events from cache"); - return Ok(ret); - } + { + debug!("Loaded pinned event {event_id} and related events from cache"); + return Ok(ret); } debug!("Loading pinned event {event_id} from HS"); diff --git a/crates/matrix-sdk-ui/tests/integration/sync_service.rs b/crates/matrix-sdk-ui/tests/integration/sync_service.rs index dffb04427..f61984372 100644 --- a/crates/matrix-sdk-ui/tests/integration/sync_service.rs +++ b/crates/matrix-sdk-ui/tests/integration/sync_service.rs @@ -110,22 +110,22 @@ async fn test_sync_service_state() -> anyhow::Result<()> { let mut json_value = serde_json::from_slice::(&request.body).unwrap(); - if let Some(root) = json_value.as_object_mut() { - if let Some(conn_id) = root.get("conn_id").and_then(|obj| obj.as_str()) { - if conn_id == "encryption" { - num_encryption_sync_requests += 1; - } else if conn_id == "room-list" { - num_room_list_requests += 1; + if let Some(root) = json_value.as_object_mut() + && let Some(conn_id) = root.get("conn_id").and_then(|obj| obj.as_str()) + { + if conn_id == "encryption" { + num_encryption_sync_requests += 1; + } else if conn_id == "room-list" { + num_room_list_requests += 1; - // Retrieve the position used in the query. - for (key, val) in request.url.query_pairs() { - if key == "pos" { - latest_room_list_pos = Some(val.to_string()); - } + // Retrieve the position used in the query. + for (key, val) in request.url.query_pairs() { + if key == "pos" { + latest_room_list_pos = Some(val.to_string()); } - } else { - panic!("unexpected conn id seen server side: {conn_id}"); } + } else { + panic!("unexpected conn id seen server side: {conn_id}"); } } } @@ -167,29 +167,29 @@ async fn test_sync_service_state() -> anyhow::Result<()> { let mut json_value = serde_json::from_slice::(&request.body).unwrap(); - if let Some(root) = json_value.as_object_mut() { - if let Some(conn_id) = root.get("conn_id").and_then(|obj| obj.as_str()) { - if conn_id == "encryption" { - num_encryption_sync_requests += 1; - } else if conn_id == "room-list" { - if num_room_list_requests == 0 { - // Either it's the same pos, or it's the next one if the request could be - // processed by the client. - let mut current_pos = None; - for (key, val) in request.url.query_pairs() { - if key == "pos" { - current_pos = Some(val); - } + if let Some(root) = json_value.as_object_mut() + && let Some(conn_id) = root.get("conn_id").and_then(|obj| obj.as_str()) + { + if conn_id == "encryption" { + num_encryption_sync_requests += 1; + } else if conn_id == "room-list" { + if num_room_list_requests == 0 { + // Either it's the same pos, or it's the next one if the request could be + // processed by the client. + let mut current_pos = None; + for (key, val) in request.url.query_pairs() { + if key == "pos" { + current_pos = Some(val); } - let current_pos: i32 = current_pos.unwrap().parse()?; - let prev_pos: i32 = latest_room_list_pos.take().unwrap().parse()?; - assert!((current_pos - prev_pos).abs() <= 1); } - - num_room_list_requests += 1; - } else { - panic!("unexpected conn id seen server side: {conn_id}"); + let current_pos: i32 = current_pos.unwrap().parse()?; + let prev_pos: i32 = latest_room_list_pos.take().unwrap().parse()?; + assert!((current_pos - prev_pos).abs() <= 1); } + + num_room_list_requests += 1; + } else { + panic!("unexpected conn id seen server side: {conn_id}"); } } } diff --git a/crates/matrix-sdk/CHANGELOG.md b/crates/matrix-sdk/CHANGELOG.md index 09212c74c..e4d00450e 100644 --- a/crates/matrix-sdk/CHANGELOG.md +++ b/crates/matrix-sdk/CHANGELOG.md @@ -19,6 +19,11 @@ All notable changes to this project will be documented in this file. - [**breaking**] `OAuth::login` now allows requesting additional scopes for the authorization code grant. ([#5395](https://github.com/matrix-org/matrix-rust-sdk/pull/5395)) +### Refactor + +- [**breaking**] The MSRV has been bumped to Rust 1.88. + ([#5431](https://github.com/matrix-org/matrix-rust-sdk/pull/5431)) + ## [0.13.0] - 2025-07-10 ### Security Fixes