-
Notifications
You must be signed in to change notification settings - Fork 0
Fix stack overflow with many attributed runs #1
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -96,9 +96,12 @@ extension Text { | |
| return text | ||
| } | ||
|
|
||
| self = textValues.reduce(Text(verbatim: "")) { partialResult, text in | ||
| Text("\(partialResult)\(text)") | ||
| } | ||
| // Concatenate via `Text + Text` rather than `Text("\(partialResult)\(text)")`. | ||
| // The interpolation form produces a `LocalizedStringKey`-backed `Text` at every | ||
| // reduce step; resolving the resulting N-deep chain recurses ~8 stack frames per | ||
| // level during SwiftUI's render pass and overflows the main-thread stack for | ||
| // content that produces a few hundred attributed runs (e.g. emoji-dense notes). | ||
| self = textValues.reduce(Text(verbatim: ""), +) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When this PR is merged into current Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For inputs that still produce many runs, such as a large syntax-highlighted code block built in Useful? React with 👍 / 👎. |
||
| } | ||
|
|
||
| private init(placeholderSize size: CGSize) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When this PR is merged into current
main, this line conflicts with the existingTextBuilderrewrite there; resolving the conflict by keeping thisreduce(..., +)path would drop the plain-run coalescing and balanced concatenation thatmainalready uses. For inputs with thousands of attributed runs, such as large syntax-highlighted code blocks or emoji-dense text, this still builds one left-deepTextconcatenation node per run, so SwiftUI can recurse through thousands ofConcatenatedTextStoragenodes and hit the same stack-overflow class this PR is meant to fix. Resolve the conflict by keeping the currentmainimplementation rather than replacing it with this left fold.Useful? React with 👍 / 👎.