Compiler Warning Reductions (#5609)

* Reduce warnings in AttributedStringBuilderTests

(cherry picked from commit e1f32b2b1df147c93207e01df5c8fec4046b0f48)

* Fixed Sentry warning

(cherry picked from commit e45c3002b2331a6f2d363de61a12377316078602)

* JoinRule and AllowRule conform to Sendable

(cherry picked from commit 27c67c27b944df11adc17bdd405e442e8c50b0d6)

* AudioConverterProtocol conform to Sendable

(cherry picked from commit 352bdab15db424c632538eb3140858eae9fdfb15)

* TimelineControllerProtocol conform to Sendable

(cherry picked from commit 07a927745624db4bab3cf68842027e12177be70b)

* Resolved some AI review notes

(cherry picked from commit 8d3ac820754a6126785e639a98c8c1fcf86ef77f)

# Conflicts:
#	ElementX/Sources/Other/SendableConformance/SendableBox.swift
#	ElementX/Sources/Other/SendableConformance/WeakSendableBox.swift
This commit is contained in:
Michael
2026-05-22 03:56:30 -05:00
committed by GitHub
parent 26f3f699a5
commit dfebb4719c
5 changed files with 66 additions and 30 deletions
@@ -8,7 +8,7 @@
import Foundation import Foundation
protocol AudioConverterProtocol { protocol AudioConverterProtocol: Sendable {
func convertToOpusOgg(sourceURL: URL, destinationURL: URL) throws func convertToOpusOgg(sourceURL: URL, destinationURL: URL) throws
func convertToMPEG4AAC(sourceURL: URL, destinationURL: URL) throws func convertToMPEG4AAC(sourceURL: URL, destinationURL: URL) throws
} }
@@ -49,7 +49,7 @@ class BugReportService: NSObject, BugReportServiceProtocol {
// MARK: - BugReportServiceProtocol // MARK: - BugReportServiceProtocol
var crashedLastRun: Bool { var crashedLastRun: Bool {
SentrySDK.crashedLastRun SentrySDK.lastRunStatus == .didCrash
} }
// swiftlint:disable:next cyclomatic_complexity // swiftlint:disable:next cyclomatic_complexity
@@ -9,7 +9,7 @@ import Foundation
import MatrixRustSDK import MatrixRustSDK
/// The rule used for users wishing to join a room. /// The rule used for users wishing to join a room.
public enum JoinRule: Equatable, Hashable { public enum JoinRule: Equatable, Hashable, Sendable {
/// Anyone can join the room without any prior action. /// Anyone can join the room without any prior action.
case `public` case `public`
/// A user who wishes to join the room must first receive an invite. /// A user who wishes to join the room must first receive an invite.
@@ -52,7 +52,7 @@ public enum JoinRule: Equatable, Hashable {
} }
/// An allow rule which defines a condition that allows joining a room. /// An allow rule which defines a condition that allows joining a room.
public enum AllowRule: Equatable, Hashable { public enum AllowRule: Equatable, Hashable, Sendable {
/// Only a member of the `room_id` Room can join the one this rule is used in. /// Only a member of the `room_id` Room can join the one this rule is used in.
case roomMembership(roomID: String) case roomMembership(roomID: String)
/// A custom allow rule implementation, containing its JSON representation as a `String`. /// A custom allow rule implementation, containing its JSON representation as a `String`.
@@ -42,7 +42,7 @@ enum TimelineControllerError: Error {
/// It, for example, permits switching from a live timeline to an event focused one, building view specific /// It, for example, permits switching from a live timeline to an event focused one, building view specific
/// timeline items, grouping together state events, donating intents to the larger system etc. /// timeline items, grouping together state events, donating intents to the larger system etc.
@MainActor @MainActor
protocol TimelineControllerProtocol { protocol TimelineControllerProtocol: Sendable {
var roomID: String { get } var roomID: String { get }
var timelineKind: TimelineKind { get } var timelineKind: TimelineKind { get }
@@ -149,7 +149,7 @@ struct AttributedStringBuilderTests {
let attributedString = try #require(attributedStringBuilder.fromHTML(htmlString), "Could not build the attributed string") let attributedString = try #require(attributedStringBuilder.fromHTML(htmlString), "Could not build the attributed string")
#expect(attributedString.uiKit.attachment == nil, #expect(attributedString.suppressedAttachment == nil,
"iFrame attachments should be removed as they're not included in the allowedHTMLTags array.") "iFrame attachments should be removed as they're not included in the allowedHTMLTags array.")
} }
@@ -305,7 +305,7 @@ struct AttributedStringBuilderTests {
foundBlockquoteAndLink = true foundBlockquoteAndLink = true
} }
#expect(foundBlockquoteAndLink != nil, "Couldn't find blockquote or link") #expect(foundBlockquoteAndLink == true, "Couldn't find blockquote or link")
} }
@Test @Test
@@ -358,11 +358,11 @@ struct AttributedStringBuilderTests {
func userPermalinkMentionAtachment() { func userPermalinkMentionAtachment() {
let string = "https://matrix.to/#/@test:matrix.org" let string = "https://matrix.to/#/@test:matrix.org"
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string) let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
#expect(attributedStringFromHTML?.attachment != nil) #expect(attributedStringFromHTML?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.userID == "@test:matrix.org") #expect(attributedStringFromHTML?.userID == "@test:matrix.org")
#expect(attributedStringFromHTML?.link?.absoluteString == string) #expect(attributedStringFromHTML?.link?.absoluteString == string)
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string) let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
#expect(attributedStringFromPlain?.attachment != nil) #expect(attributedStringFromPlain?.suppressedAttachment != nil)
#expect(attributedStringFromPlain?.userID == "@test:matrix.org") #expect(attributedStringFromPlain?.userID == "@test:matrix.org")
#expect(attributedStringFromPlain?.link?.absoluteString == string) #expect(attributedStringFromPlain?.link?.absoluteString == string)
} }
@@ -371,11 +371,11 @@ struct AttributedStringBuilderTests {
func userIDMentionAtachment() { func userIDMentionAtachment() {
let string = "@test:matrix.org" let string = "@test:matrix.org"
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string) let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
#expect(attributedStringFromHTML?.attachment != nil) #expect(attributedStringFromHTML?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.userID == "@test:matrix.org") #expect(attributedStringFromHTML?.userID == "@test:matrix.org")
#expect(attributedStringFromHTML?.link?.absoluteString == "https://matrix.to/#/@test:matrix.org") #expect(attributedStringFromHTML?.link?.absoluteString == "https://matrix.to/#/@test:matrix.org")
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string) let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
#expect(attributedStringFromPlain?.attachment != nil) #expect(attributedStringFromPlain?.suppressedAttachment != nil)
#expect(attributedStringFromPlain?.userID == "@test:matrix.org") #expect(attributedStringFromPlain?.userID == "@test:matrix.org")
#expect(attributedStringFromPlain?.link?.absoluteString == "https://matrix.to/#/@test:matrix.org") #expect(attributedStringFromPlain?.link?.absoluteString == "https://matrix.to/#/@test:matrix.org")
} }
@@ -384,11 +384,11 @@ struct AttributedStringBuilderTests {
func roomIDPermalinkMentionAttachment() { func roomIDPermalinkMentionAttachment() {
let string = "https://matrix.to/#/!test:matrix.org" let string = "https://matrix.to/#/!test:matrix.org"
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string) let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
#expect(attributedStringFromHTML?.attachment != nil) #expect(attributedStringFromHTML?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.roomID == "!test:matrix.org") #expect(attributedStringFromHTML?.roomID == "!test:matrix.org")
#expect(attributedStringFromHTML?.link?.absoluteString == string) #expect(attributedStringFromHTML?.link?.absoluteString == string)
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string) let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
#expect(attributedStringFromPlain?.attachment != nil) #expect(attributedStringFromPlain?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.roomID == "!test:matrix.org") #expect(attributedStringFromHTML?.roomID == "!test:matrix.org")
#expect(attributedStringFromPlain?.link?.absoluteString == string) #expect(attributedStringFromPlain?.link?.absoluteString == string)
} }
@@ -397,11 +397,11 @@ struct AttributedStringBuilderTests {
func roomAliasPermalinkMentionAttachment() { func roomAliasPermalinkMentionAttachment() {
let string = "https://matrix.to/#/#test:matrix.org" let string = "https://matrix.to/#/#test:matrix.org"
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string) let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
#expect(attributedStringFromHTML?.attachment != nil) #expect(attributedStringFromHTML?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.roomAlias == "#test:matrix.org") #expect(attributedStringFromHTML?.roomAlias == "#test:matrix.org")
#expect(attributedStringFromHTML?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org") #expect(attributedStringFromHTML?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org")
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string) let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
#expect(attributedStringFromPlain?.attachment != nil) #expect(attributedStringFromPlain?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.roomAlias == "#test:matrix.org") #expect(attributedStringFromHTML?.roomAlias == "#test:matrix.org")
#expect(attributedStringFromPlain?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org") #expect(attributedStringFromPlain?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org")
} }
@@ -410,11 +410,11 @@ struct AttributedStringBuilderTests {
func roomAliasMentionAttachment() { func roomAliasMentionAttachment() {
let string = "#test:matrix.org" let string = "#test:matrix.org"
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string) let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
#expect(attributedStringFromHTML?.attachment != nil) #expect(attributedStringFromHTML?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.roomAlias == "#test:matrix.org") #expect(attributedStringFromHTML?.roomAlias == "#test:matrix.org")
#expect(attributedStringFromHTML?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org") #expect(attributedStringFromHTML?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org")
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string) let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
#expect(attributedStringFromPlain?.attachment != nil) #expect(attributedStringFromPlain?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.roomAlias == "#test:matrix.org") #expect(attributedStringFromHTML?.roomAlias == "#test:matrix.org")
#expect(attributedStringFromPlain?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org") #expect(attributedStringFromPlain?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org")
} }
@@ -423,11 +423,11 @@ struct AttributedStringBuilderTests {
func eventRoomIDPermalinkMentionAttachment() { func eventRoomIDPermalinkMentionAttachment() {
let string = "https://matrix.to/#/!test:matrix.org/$test" let string = "https://matrix.to/#/!test:matrix.org/$test"
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string) let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
#expect(attributedStringFromHTML?.attachment != nil) #expect(attributedStringFromHTML?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.eventOnRoomID == .some(.init(roomID: "!test:matrix.org", eventID: "$test"))) #expect(attributedStringFromHTML?.eventOnRoomID == .some(.init(roomID: "!test:matrix.org", eventID: "$test")))
#expect(attributedStringFromHTML?.link?.absoluteString == string) #expect(attributedStringFromHTML?.link?.absoluteString == string)
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string) let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
#expect(attributedStringFromPlain?.attachment != nil) #expect(attributedStringFromPlain?.suppressedAttachment != nil)
#expect(attributedStringFromPlain?.eventOnRoomID == .some(.init(roomID: "!test:matrix.org", eventID: "$test"))) #expect(attributedStringFromPlain?.eventOnRoomID == .some(.init(roomID: "!test:matrix.org", eventID: "$test")))
#expect(attributedStringFromPlain?.link?.absoluteString == string) #expect(attributedStringFromPlain?.link?.absoluteString == string)
} }
@@ -436,11 +436,11 @@ struct AttributedStringBuilderTests {
func eventRoomAliasPermalinkMentionAttachment() { func eventRoomAliasPermalinkMentionAttachment() {
let string = "https://matrix.to/#/#test:matrix.org/$test" let string = "https://matrix.to/#/#test:matrix.org/$test"
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string) let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
#expect(attributedStringFromHTML?.attachment != nil) #expect(attributedStringFromHTML?.suppressedAttachment != nil)
#expect(attributedStringFromHTML?.eventOnRoomAlias == .some(.init(alias: "#test:matrix.org", eventID: "$test"))) #expect(attributedStringFromHTML?.eventOnRoomAlias == .some(.init(alias: "#test:matrix.org", eventID: "$test")))
#expect(attributedStringFromHTML?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org/$test") #expect(attributedStringFromHTML?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org/$test")
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string) let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
#expect(attributedStringFromPlain?.attachment != nil) #expect(attributedStringFromPlain?.suppressedAttachment != nil)
#expect(attributedStringFromPlain?.eventOnRoomAlias == .some(.init(alias: "#test:matrix.org", eventID: "$test"))) #expect(attributedStringFromPlain?.eventOnRoomAlias == .some(.init(alias: "#test:matrix.org", eventID: "$test")))
#expect(attributedStringFromPlain?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org/$test") #expect(attributedStringFromPlain?.link?.absoluteString == "https://matrix.to/#/%23test:matrix.org/$test")
} }
@@ -536,7 +536,7 @@ struct AttributedStringBuilderTests {
#expect(attributedString?.runs.count == 1) #expect(attributedString?.runs.count == 1)
#expect(attributedString?.attachment == nil) #expect(attributedString?.suppressedAttachment == nil)
} }
@Test @Test
@@ -546,7 +546,7 @@ struct AttributedStringBuilderTests {
#expect(attributedString?.runs.count == 1) #expect(attributedString?.runs.count == 1)
#expect(attributedString?.attachment == nil) #expect(attributedString?.suppressedAttachment == nil)
} }
@Test @Test
@@ -556,7 +556,7 @@ struct AttributedStringBuilderTests {
#expect(attributedString?.runs.count == 1) #expect(attributedString?.runs.count == 1)
#expect(attributedString?.attachment == nil) #expect(attributedString?.suppressedAttachment == nil)
} }
@Test @Test
@@ -569,7 +569,7 @@ struct AttributedStringBuilderTests {
var foundAttachments = 0 var foundAttachments = 0
var foundLink: URL? var foundLink: URL?
for run in attributedStringFromHTML.runs { for run in attributedStringFromHTML.runs {
if run.attachment != nil { if run.suppressedAttachment != nil {
foundAttachments += 1 foundAttachments += 1
} }
@@ -585,7 +585,7 @@ struct AttributedStringBuilderTests {
foundAttachments = 0 foundAttachments = 0
foundLink = nil foundLink = nil
for run in attributedStringFromPlain.runs { for run in attributedStringFromPlain.runs {
if run.attachment != nil { if run.suppressedAttachment != nil {
foundAttachments += 1 foundAttachments += 1
} }
@@ -607,7 +607,7 @@ struct AttributedStringBuilderTests {
var foundAttachments = 0 var foundAttachments = 0
var foundLink: URL? var foundLink: URL?
for run in attributedStringFromHTML.runs { for run in attributedStringFromHTML.runs {
if run.attachment != nil { if run.suppressedAttachment != nil {
foundAttachments += 1 foundAttachments += 1
} }
@@ -623,7 +623,7 @@ struct AttributedStringBuilderTests {
foundAttachments = 0 foundAttachments = 0
foundLink = nil foundLink = nil
for run in attributedStringFromPlain.runs { for run in attributedStringFromPlain.runs {
if run.attachment != nil { if run.suppressedAttachment != nil {
foundAttachments += 1 foundAttachments += 1
} }
@@ -983,7 +983,7 @@ struct AttributedStringBuilderTests {
#expect(String(attributedString2.characters) == "This is visible. And this text and link are visible too.") #expect(String(attributedString2.characters) == "This is visible. And this text and link are visible too.")
try #require(attributedString2.runs.first { $0.link != nil }?.link, "Couldn't find the link") _ = try #require(attributedString2.runs.first { $0.link != nil }?.link, "Couldn't find the link")
} }
// MARK: - Private // MARK: - Private
@@ -1006,10 +1006,46 @@ struct AttributedStringBuilderTests {
#expect(attributedString.runs.count == expectedRuns) #expect(attributedString.runs.count == expectedRuns)
for run in attributedString.runs where run.attachment != nil { for run in attributedString.runs where run.suppressedAttachment != nil {
return return
} }
Issue.record("Couldn't find expected value.") Issue.record("Couldn't find expected value.")
} }
} }
// warning suppression
// `NSTextAttachment` is marked `@_nonSendable(_assumed)` by Apple in the UIKit SDK, and
// `ScopedAttributeContainer` (returned by `AttributedString.uiKit` and used by dynamic member
// lookup on `AttributedString` and `AttributedString.Runs.Element`) is marked `Sendable`.
// The compiler warns at every access point where a `@_nonSendable` value is read through a
// `Sendable` container — regardless of Swift version or strict concurrency mode. There is no
// compiler flag that suppresses this cleanly.
//
// Attempted fixes:
// - `@MainActor` on the test class: does not help; the warning is not about actor isolation
// - `@preconcurrency import UIKit`: does not help; the warning originates from the SDK type attribute
// - Varying `-strict-concurrency` (targeted/complete) or `-swift-version` (5/6): all produce
// the same warning — confirmed via standalone `swiftc` repro
//
// The warning is safe to ignore here because no concurrency boundary is actually crossed —
// the value is accessed synchronously within a single context and never escapes.
//
// These two extension properties consolidate 20+ warning sites across this file down to just
// these two definitions taking the hit. This pattern is test-only; app code reads attachments
// via `NSAttributedString.attribute(_:at:effectiveRange:)` which does not trigger the warning.
// swiftformat:disable redundantSelf
// self is not redundant here because these are NOT properties directly on the type, but on a
// child through dynamicMember which requires the `self` for access
private extension AttributedString {
var suppressedAttachment: NSTextAttachment? {
self.attachment
}
}
private extension AttributedString.Runs.Element {
var suppressedAttachment: NSTextAttachment? {
self.attachment
}
}