Skip to content

feat: address concurrency warnings arising from Theme #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Sources/MarkdownUI/Theme/BlockStyle/BlockStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import SwiftUI
/// ```
///
/// ![](CustomBlockquote)
public struct BlockStyle<Configuration> {
private let body: (Configuration) -> AnyView
public struct BlockStyle<Configuration> : Sendable {
private let body: @Sendable (Configuration) -> AnyView
Copy link
Author

@cweider cweider Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s a whole followup chunk of work needed to make initializers (and so on) provide a @Sendable. The functions, producing View should be bound to the @MainActor as well.

You can see that at fe5621b7af. It could be squashed onto this change or pushed later.


/// Creates a block style that customizes a block by applying the given body.
/// - Parameter body: A view builder that returns the customized block.
Expand Down
27 changes: 19 additions & 8 deletions Sources/MarkdownUI/Theme/TextStyle/Styles/FontProperties.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import SwiftUI
/// The characteristics of a font.
public struct FontProperties: Hashable {
/// The font family.
public enum Family: Hashable {
public enum Family: Hashable, Sendable {
/// The system font family.
case system(Font.Design = .default)

Expand All @@ -12,7 +12,7 @@ public struct FontProperties: Hashable {
}

/// The font family variant.
public enum FamilyVariant: Hashable {
public enum FamilyVariant: Hashable, Sendable {
/// No variant. Use the current font family.
case normal

Expand All @@ -21,7 +21,7 @@ public struct FontProperties: Hashable {
}

/// The font caps variant.
public enum CapsVariant: Hashable {
public enum CapsVariant: Hashable, Sendable {
/// Don't use a font caps variant.
case normal

Expand All @@ -36,7 +36,7 @@ public struct FontProperties: Hashable {
}

/// The font digit variant.
public enum DigitVariant: Hashable {
public enum DigitVariant: Hashable, Sendable {
/// Don't use a font digit variant.
case normal

Expand All @@ -45,7 +45,7 @@ public struct FontProperties: Hashable {
}

/// The font style.
public enum Style {
public enum Style: Sendable {
/// Don't use a font style.
case normal

Expand Down Expand Up @@ -98,11 +98,11 @@ public struct FontProperties: Hashable {
/// The font width.
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
public var width: Font.Width {
get { (self.widthStorage as? Font.Width) ?? .standard }
set { self.widthStorage = newValue }
get { (self.widthStorage?.base as? Font.Width) ?? .standard }
set { self.widthStorage = AnySendableHashableBox(newValue) }
}

private var widthStorage: AnyHashable?
private var widthStorage: AnySendableHashableBox?

/// The font size.
public var size: CGFloat = Self.defaultSize
Expand Down Expand Up @@ -187,3 +187,14 @@ extension FontProperties: TextStyle {
attributes.fontProperties = self
}
}

// A cheap workaround for `AnyHashable` of a `Sendable` not being `Sendable`.
// This is necessary for `widthStorage`.
// TODO: iOS16,macOS13 once minimum deployment target is raised, remove this indirection
fileprivate struct AnySendableHashableBox: Hashable, @unchecked Sendable {
let base: AnyHashable

init<V: Hashable & Sendable>(_ base: V) {
self.base = base
}
}
2 changes: 1 addition & 1 deletion Sources/MarkdownUI/Theme/TextStyle/Styles/FontSize.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation

/// A text style that sets the font size.
public struct FontSize: TextStyle {
private enum Size {
private enum Size: Sendable {
case points(CGFloat)
case relative(RelativeSize)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/MarkdownUI/Theme/TextStyle/TextStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ import SwiftUI
/// ```
///
/// ![](CustomBlockquote)
public protocol TextStyle {
public protocol TextStyle : Sendable {
func _collectAttributes(in attributes: inout AttributeContainer)
}
4 changes: 2 additions & 2 deletions Sources/MarkdownUI/Utility/RelativeSize.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import SwiftUI
/// FontSize(.em(2))
/// }
/// ```
public struct RelativeSize: Hashable {
enum Unit: Hashable {
public struct RelativeSize: Hashable, Sendable {
enum Unit: Hashable, Sendable {
case em
case rem
}
Expand Down